1.实现平台
两块STM开发板,杜邦线;
初始化板子上的串口;
为串口开启中断;
根据需要制定两个板子的通讯协议。
2.实现过程
2.1协议制定
在工程实践的过程中,常常需要两个板子进行通讯来实现功能。现在常常使用的通讯方法常常是CAN通信,TTL通讯,RS485通讯,RS232通讯,I2C,I2S,SPI等。UART也是一种常用的通讯方式,这种通讯方式为全双工。
制定协议时应注意以下几点:
起始符,结束符和校验位 在为制定通讯协议的时候,首先应该确定发送数据的起始符,结束符和校验位;在设置起始符,结束符的时候应该避免和发送的内容发生冲突。结束符最好可以设置多位,一般可以设置两个位作为结束符;校验位需要在结束符之前;起始位一般没有特殊要求的话,设置一位即可。
校验方式
一般校验方式可以是奇检验,偶校验,CRC校验。现在用的较多的是CRC校验,CRC校验可以看引用的第三篇博文,讲的比较清楚。
接下来给个UART通讯例子:
接下来介绍实现
实现在STM32ZET6开发板上,UART4,正点原子
UART4初始化:
1 void UART4_Init(void)
2 {
3 //GPIO端口设置
4 GPIO_InitTypeDef GPIO_InitStructure;
5 USART_InitTypeDef USART_InitStructure;
6 NVIC_InitTypeDef NVIC_InitStructure;
7 USART_DeInit(UART4); //复位串口4
8 RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4 ,ENABLE);
9 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);//使能UART4,GPIOA时钟
10 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
11 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
12 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出
13 GPIO_Init(GPIOC, &GPIO_InitStructure);
14 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
15 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
16 GPIO_Init(GPIOC, &GPIO_InitStructure);
17 //UART4 NVIC 配置
18 NVIC_InitStructure.NVIC_IRQChannel = UART4_IRQn;
19 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
20 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;//子优先级3
21 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//IRQ通道使能
22 NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
23 //USART 初始化设置
24 USART_InitStructure.USART_BaudRate = 115200;//一般设置为9600;
25 USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
26 USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
27 USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
28 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
29 USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式
30 USART_Init(UART4, &USART_InitStructure); //初始化串口
31 USART_ITConfig(UART4, USART_IT_RXNE, ENABLE);//开启中断
32 USART_Cmd(UART4, ENABLE); //使能串口
33 return ;
34 }
UART中断函数:
1 u8 uart_flag=0;
2 extern u8 usart_signal[10];
3 u8 UART4_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.
4 u16 UART4_RX_STA = 0; //接收状态标记
5 void UART4_IRQHandler(void) //串口4中断服务程序
6 {
7 u8 Res;
8 u8 len = 0,v = 0;
9 if(USART_GetITStatus(UART4, USART_IT_RXNE) != RESET) //接收中断
10 {
11 Res = USART_ReceiveData(UART4);//(USART1->DR); //读取接收到的数据
12 if((UART4_RX_STA&0x8000)==0)//接收未完成
13 {
14 if(UART4_RX_STA&0x4000)//接收到了0xff
15 {
16 if(Res!=0x0a)
17 {
18 UART4_RX_STA = 0; //接收错误,重新开始
19 }
20 else
21 {
22 UART4_RX_STA|=0x8000; //接收完成了
23 len = UART4_RX_STA &0x3fff;
24 if(len != 10) // 数据长度不是(12-2)
25 {
26 UART4_RX_STA = 0; // 重新开始接收
27 }
28 else
29 {
30 if(UART_check(UART4_RX_BUF) == 1) // 检测起始符与终止符
31 {
32 for(v = 0;v < 10;v++)
33 {
34 usart_signal[v] = UART4_RX_BUF[v];
35 uart_flag=1;
36 }
37 }
38 else
39 {
40 UART4_RX_STA = 0;
41 }
42 }
43 }
44 }
45 else //还没收到0Xff
46 {
47 if(Res==0xff)
48 {
49 UART4_RX_STA|=0x4000;
50
51 }
52 else
53 {
54 UART4_RX_BUF[UART4_RX_STA&0X3FFF]=Res ;
55 UART4_RX_STA++;
56 if(UART4_RX_STA>(USART_REC_LEN-1))UART4_RX_STA=0;//接收数据错误,重新开始接收
57 }
58 }
59 }
60 }
61 }
『本文转载自网络,版权归原作者所有,如有侵权请联系删除』