今天发布STM32的串口3配置程序,话不多说。
1 /*=============================================================================== 2 Copyright: 3 Version: 4 Author: 5 Date: 2017/11/3 6 Description: 7 函数功能是将接收固定长度的字符串,并将接收后的字符串通过串口发送出去 8 通过滴答定时器方式获取数据 9 revise Description: 10 ===============================================================================*/
11 #include "stm32f10x_usart.h"
12 #include "stm32f10x.h"
13
14 #define USART4_TIMEOUT_Setting 800 //(ms)
15
16 u8 USART4_RX_BUF[250]; 17 u16 USART4_RX_CNT=0; 18 u16 USART2_RX_STA=0; //接收状态标记
19
20 void Systick_delay_init(u8 SYSCLK); 21 u8 virtual_delay(u32 num,u8 unit); 22
23 //通用异步收发器UART4
24 void UART4_Init(u32 bound) 25 { 26 USART_InitTypeDef USART_InitStructure; 27 GPIO_InitTypeDef GPIO_InitStructure; 28
29 //used for USART3 full remap 30 //GPIO_PinRemapConfig(GPIO_FullRemap_USART3, ENABLE);
31 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE); 32 RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE);//for UART4 33
34 //Configure RS485_TX_EN PIN
35 GPIO_InitStructure.GPIO_Pin = RS485_TX_EN_PIN; //PC9端口配置
36 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
37 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 38 GPIO_Init(RS485_TX_EN_PORT, &GPIO_InitStructure); 39
40 RS485_TX_EN=0; //设置485默认为接收模式
41
42 /* Configure USART Tx as alternate function push-pull */
43 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; 44 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 45 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 46 GPIO_Init(GPIOC, &GPIO_InitStructure); 47
48 /* Configure USART Rx as input floating */
49 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; 50 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 51 GPIO_Init(GPIOC, &GPIO_InitStructure); 52
53
54 USART_InitStructure.USART_BaudRate = bound; 55 USART_InitStructure.USART_WordLength = USART_WordLength_8b; 56 USART_InitStructure.USART_StopBits = USART_StopBits_1; 57 USART_InitStructure.USART_Parity = USART_Parity_No ; 58 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; 59 USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; 60
61 USART_Init(UART4, &USART_InitStructure); 62 //USART_Init(USART3, &USART_InitStructure);
63 /* Enable the USART */
64 USART_Cmd(UART4, ENABLE); 65 USART_ITConfig(UART4, USART_IT_RXNE, ENABLE);//开启串口接受中断
66 USART_ClearFlag(UART4,USART_FLAG_TC); 67 } 68 //USART1查询接收到的数据 69 //buf:接收缓存首地址 70 //len:读到的数据长度
71 void UART4_Receive_Data(u8 *buf) 72 { 73 u8 rxlen=21; 74 u8 i=0; 75 delay_ms(10); //等待10ms,连续超过10ms没有接收到一个数据,则认为接收结束
76
77 RS485_RX_FLAG = 0; 78 if((UART4_RX_BUF[0]==0x01)&&(UART4_RX_BUF[1]==0x03)) 79 { 80 for(i=0;i<rxlen;i++) 81 { 82 buf[ i]=UART4_RX_BUF[ i]; [ i] 83 UART4_RX_BUF[ i] = 0; 84 } 85 RS485_RX_FLAG = 1; 86 } 87 UART4_RX_CNT=0; //清零
88 } 89
90
91 //USART1发送len个字节. 92 //buf:发送区首地址 93 //len:发送的字节数(为了和本代码的接收匹配,这里建议不要超过64个字节)
94 void UART4_Send_Data(u8 *buf,u16 len) 95 { 96 u16 t; 97 RS485_TX_EN=1; //设置为发送模式
98 for(t=0;t<len;t++) //循环发送数据
99 { 100 while(USART_GetFlagStatus(UART4,USART_FLAG_TC)==RESET); //循环发送,直到发送完毕
101 USART_SendData(UART4,buf[t]); 102 } 103 while(USART_GetFlagStatus(UART4, USART_FLAG_TC) == RESET); 104 RS485_TX_EN=0; //设置为接收模式
105 }106
107 void main(void)108 {109 Systick_delay_init(72);110 Usart4_Init(9600);//串口1波特率设置为9600
111 while(1)112 {113 if(USART2_RX_STA)114 {115 if(virtual_delay(USART4_TIMEOUT_Setting,MS))//超过800ms空闲则可以读取数据
116 {117 UART4_Send_Data(UART4_RX_BUF,UART4_RX_CNT);118 USART2_RX_STA=0;119 UART4_RX_CNT=0; 120 }121
122 }123
124 } 125 }126 void UART4_IRQHandler(void) //UART4 Receive Interrupt
127 {128 u8 Res;129
130 if(USART_GetITStatus(UART4, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾)
131 { 132 Res =USART_ReceiveData(UART4);//(USART1->DR); //读取接收到的数据
133 UART4_RX_BUF[UART4_RX_CNT&0XFF]=Res; //回传的数据存入数组,0X3F限制为64个数值
134 UART4_RX_CNT++;135 USART2_RX_STA=1; 136 }137
138 if( USART_GetITStatus(UART4, USART_IT_TC) == SET )139 {140 USART_ClearFlag(UART4, USART_FLAG_TC);141 } 142 //溢出-如果发生溢出需要先读SR,再读DR寄存器则可清除不断入中断的问题
143 if(USART_GetFlagStatus(UART4,USART_FLAG_ORE) == SET)144 {145 USART_ReceiveData(UART4);146 USART_ClearFlag(UART4,USART_FLAG_ORE);147 }148 // USART_ITConfig(UART4, USART_IT_RXNE, DISABLE);//临时关闭接收中断
149 USART_ClearFlag(UART4,USART_IT_RXNE); //一定要清除接收中断
150
151 } 152
153 //初始化延迟函数154 //SYSTICK的时钟固定为HCLK时钟的1/8155 //SYSCLK:系统时钟
156 void Systick_delay_init(u8 SYSCLK)157 {158 SysTick->CTRL&=0xfffffffb;//bit2清空,选择外部时钟 HCLK/8159 // SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //选择外部时钟 HCLK/8
160 fac_us=SYSCLK/8; 161 fac_ms=(u16)fac_us*1000;162 }163 /*===============================================================================164 Author:peter pan165 Date: 166 Description: 查询式分时或叫做轮询式(近似延时)。本函数是用于执行高效率场合的查询延时,但是一个for or while 循环中只能用一次。167 revise Description: 168 @ num : //分时查询的周期计数值 169 @ unit : //分时查询的周期单位 170 @@ParaValue : 171 MS //周期单位为MS毫秒级172 US //周期单位为US微秒级173 @ virtual_delay_status : //静态变量174 @@ParaValue : 175 SET //SYSTICK正在占用中,请勿用176 RESET //SYSTICK空闲,可以使用177 @ReValue :178 with zero mean Time non-arrive ,one representative Time arrived ,you can do task;179 ##example if(virtual_delay(1000,MS)) LedFlash(); //1000ms LED闪烁一下180 ===============================================================================*/
181 u8 virtual_delay(u32 num,u8 unit)182 {183 u32 temp; 184 if(virtual_delay_status==RESET) // SYSTICK空闲,可以使用
185 {186 if(unit==MS)187 {188 SysTick->LOAD=(u32)num*Delay_SYSCLK*125;//时间加载(SysTick->LOAD为24bit)
189 SysTick->VAL =0x00; //清空计数器
190 SysTick->CTRL=0x01 ; //开始倒数
191 }else if(unit==US) 192 {193 SysTick->LOAD=num*Delay_SYSCLK/8; //时间加载
194 SysTick->VAL=0x00; //清空计数器
195 SysTick->CTRL=0x01 ; //开始倒数
196 }197 virtual_delay_status=SET;198 return 0;199 }200 else
201 { //virtual_delay_status==SET SYSTICK被占用
202
203 temp=SysTick->CTRL;204 if(!(temp&0x01&&!(temp&(1<<16))))//等待时间到达
205 {206 SysTick->CTRL=0x00; //关闭计数器
207 SysTick->VAL =0X00; //清空计数器
208 virtual_delay_status=RESET; 209 return 1;210 }else return 0;211 }212 }
|