我是靠谱客的博主 唠叨老师,这篇文章主要介绍STM32----------串口通信(USART),现在分享给大家,希望可以做个参考。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
#include "stm32f10x.h" #include "platform_config.h" #include "stm32f10x_usart.h" #include "misc.h" #include "stdarg.h" USART_InitTypeDef USART_InitStructure; uint8_t TxBuffer1[] = "USART Interrupt Example: This is USART2 DEMO"; uint8_t RxBuffer1[],rec_f,tx_flag; __IO uint8_t TxCounter1 = 0x00; __IO uint8_t RxCounter1 = 0x00; uint32_t Rec_Len; void RCC_Configuration(void); void GPIO_Configuration(void); void NVIC_Configuration(void); void Delay(__IO uint32_t nCount); void USART_OUT(USART_TypeDef* USARTx, uint8_t *Data,...); char *itoa(int value, char *string, int radix); void USART_Config(USART_TypeDef* USARTx); GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStruct; USART_ClockInitTypeDef USART_ClockInitStruct; void USART_Config(USART_TypeDef* USARTx){ USART_InitStructure.USART_BaudRate = 115200; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; // USART_Init(USARTx, &USART_InitStructure); // /* Enable USARTx Receive and Transmit interrupts */ USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); //使能接收端中断,TXE发送中断,TC传输完成中断,RXNE接收中断 USART_ITConfig(USART2, USART_IT_TXE, ENABLE); //使能发送端空中断 /* Enable the USARTx */ USART_Cmd(USART2, ENABLE); } int main(void) { uint8_t a=0; /* System Clocks Configuration */ RCC_Configuration(); NVIC_Configuration(); GPIO_Configuration(); USART_Config(USART2); USART_OUT(USART2,"****(C) COPYRIGHT 2014 · ******rn"); USART_OUT(USART2,"* *rn"); USART_OUT(USART2,"* *rn"); USART_OUT(USART2,"* www.ourstm.net *rn"); USART_OUT(USART2,"* *rn"); USART_OUT(USART2,"***************************************************rn"); USART_OUT(USART2,"rn"); USART_OUT(USART2,"rn"); while (1) { if(rec_f==1){ rec_f=0; USART_OUT(USART2,"你将发送的数据是 :rn"); USART_OUT(USART2,&TxBuffer1[0]); if(a==0) {GPIO_SetBits(GPIOB, GPIO_Pin_5); a=1;} else {GPIO_ResetBits(GPIOB, GPIO_Pin_5);a=0; } } } } void Delay(__IO uint32_t nCount) { for(; nCount != 0; nCount--); } void USART_OUT(USART_TypeDef* USARTx, uint8_t *Data,...){ const char *s; int d; char buf[16]; va_list ap; va_start(ap, Data); while(*Data!=0){ if(*Data==0x5c){ //'' switch (*++Data){ case 'r': // USART_SendData(USARTx, 0x0d); Data++; break; case 'n': // USART_SendData(USARTx, 0x0a); Data++; break; default: Data++; break; } } else if(*Data=='%'){ // switch (*++Data){ case 's': // s = va_arg(ap, const char *); for ( ; *s; s++) { USART_SendData(USARTx,*s); while(USART_GetFlagStatus(USARTx, USART_FLAG_TC)==RESET); } Data++; break; case 'd': // d = va_arg(ap, int); itoa(d, buf, 10); for (s = buf; *s; s++) { USART_SendData(USARTx,*s); while(USART_GetFlagStatus(USARTx, USART_FLAG_TC)==RESET); } Data++; break; default: Data++; break; } } else USART_SendData(USARTx, *Data++); while(USART_GetFlagStatus(USARTx, USART_FLAG_TC)==RESET); } } char *itoa(int value, char *string, int radix) { int i, d; int flag = 0; char *ptr = string; /* This implementation only works for decimal numbers. */ if (radix != 10) { *ptr = 0; return string; } if (!value) { *ptr++ = 0x30; *ptr = 0; return string; } /* if this is a negative value insert the minus sign. */ if (value < 0) { *ptr++ = '-'; /* Make the value positive. */ value *= -1; } for (i = 10000; i > 0; i /= 10) { d = value / i; if (d || flag) { *ptr++ = (char)(d + 0x30); value -= (d * i); flag = 1; } } /* Null terminate the string. */ *ptr = 0; return string; } /* NCL_Itoa */ void RCC_Configuration(void) { SystemInit(); RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO , ENABLE); RCC_APB1PeriphClockCmd( RCC_APB1Periph_USART2, ENABLE); } void GPIO_Configuration(void) { GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //USART2 TX GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // GPIO_Init(GPIOA, &GPIO_InitStructure); // GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; //USART2 RX GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; // GPIO_Init(GPIOA, &GPIO_InitStructure); // } void NVIC_Configuration(void) { NVIC_InitTypeDef NVIC_InitStructure; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); }

上面的是main.c  ,下面是stm32f10x_it.c中断服务程序

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<span style="font-size:18px;">#include "stm32f10x_it.h" #include "stm32f10x_usart.h" extern uint8_t TxBuffer1[]; extern uint8_t TxBuffer2[]; extern uint8_t RxBuffer1[]; extern uint8_t RxBuffer2[]; extern __IO uint8_t TxCounter1; extern __IO uint8_t TxCounter2; extern __IO uint8_t RxCounter1; extern __IO uint8_t RxCounter2; extern uint8_t rec_f,tx_flag; void USART2_IRQHandler(void) //串口2中断服务函数 { unsigned int i; if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) //判断读寄存器是否为空,也就是是否有数据发送进来,是否发生接收中断 { RxBuffer1[RxCounter1++] = USART_ReceiveData(USART2); //将读寄存器的数据存到接收缓冲区里面 if(RxBuffer1[RxCounter1-2]==0x0d&&RxBuffer1[RxCounter1-1]==0x0a) //判断结束标志位是否为0x0d 0x0a (rn) 也就是是否为回车 </span>
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{ for(i=0; i< RxCounter1; i++) TxBuffer1[i] = RxBuffer1[i]; //将接收区数据送到发送缓冲区,准备转发 rec_f=1; //接收成功标志 TxBuffer1[RxCounter1]=0; //发送缓冲区结束符 RxCounter1=0; } } if(USART_GetITStatus(USART2, USART_IT_TXE) != RESET) //这段是为了STM32 UART 第一个字节发送不出去的BUG { USART_ITConfig(USART2, USART_IT_TXE, DISABLE); //禁止发缓冲器空中断 } }


STM32笔记之九:打断它来为我办事,EXIT (外部I/O中断)应用

a) 目的:跟串口输入类似,不使用中断进行的IO输入效率也很低,而且可以通过EXTI插入按钮事件,本节联系EXTI中断。

b) 初始化函数定义:

void EXTI_Configuration(void); //定义IO中断初始化函数

c) 初始化函数调用:

EXTI_Configuration();//IO中断初始化函数调用简单应用:

d) 初始化函数:

void EXTI_Configuration(void)

{ EXTI_InitTypeDef EXTI_InitStructure; //EXTI初始化结构定义

EXTI_ClearITPendingBit(EXTI_LINE_KEY_BUTTON);//清除中断标志

GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource3);//管脚选择

GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource4);

     GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource5);

     GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource6);

EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//事件选择

    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//触发模式

    EXTI_InitStructure.EXTI_Line = EXTI_Line3 | EXTI_Line4; //线路选择

    EXTI_InitStructure.EXTI_LineCmd = ENABLE;//启动中断

    EXTI_Init(&EXTI_InitStructure);//初始化

}

e) RCC初始化函数中开启I/O时钟

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);

GPIO初始化函数中定义输入I/O管脚。

//IO输入,GPIOA的4脚输入

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;        //上拉输入

    GPIO_Init(GPIOA, &GPIO_InitStructure);              //初始化

f) 在NVIC的初始化函数里面增加以下代码打开相关中断:

    NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQChannel; //通道

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//占先级

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //响应级

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //启动

    NVIC_Init(&NVIC_InitStructure); //初始化

g) 在stm32f10x_it.c文件中找到void USART1_IRQHandler函数,在其中添入执行代码。一般最少三个步骤:先使用if语句判断是发生那个中断,然后清除中断标志位,最后给字符串赋值,或做其他事情。

    if(EXTI_GetITStatus(EXTI_Line3) != RESET)                                //判断中断发生来源

{ EXTI_ClearITPendingBit(EXTI_Line3);                                         //清除中断标志

USART_SendData(USART1, 0x41);                                            //发送字符“a”

GPIO_WriteBit(GPIOB, GPIO_Pin_2, (BitAction)(1-GPIO_ReadOutputDataBit(GPIOB, GPIO_Pin_2)));//LED发生明暗交替

}

h) 中断注意事项:

中断发生后必须清除中断位,否则会出现死循环不断发生这个中断。然后需要对中断类型进行判断再执行代码。

使用EXTI的I/O中断,在完成RCC与GPIO硬件设置之后需要做三件事:初始化EXTI、NVIC开中断、编写中断执行代码。

中断注意事项:

可以随时在程序中使用USART_ITConfig(USART1, USART_IT_TXE, DISABLE);来关闭中断响应。

NVIC_InitTypeDef NVIC_InitStructure定义一定要加在NVIC初始化模块的第一句。

全局变量与函数的定义:在任意.c文件中定义的变量或函数,在其它.c文件中使用extern+定义代码再次定义就可以直接调用了。


最后

以上就是唠叨老师最近收集整理的关于STM32----------串口通信(USART)的全部内容,更多相关STM32----------串口通信(USART)内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(76)

评论列表共有 0 条评论

立即
投稿
返回
顶部