背景介绍
串口这里不再多说,不懂的进链接去了解一下。在STM32中,串口的通信协议一般是应用层协议,即上位机和下位机之间的通信协议。这里的应用层协议是师兄设计的,之前也看过几遍,但没看懂,今天来仔细分析一下。
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
是串口接收中断的回调函数,简单理解就是每次串口接收到数据都会调用这个函数。
协议格式
1 2 3 4 5 6 7 8 9
| A00B0000
A01B1200
|
代码正文
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
| void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
static uint8_t rcvstate = 0x00; switch (UART_RCV_DATA) { case 'A': UART_RCV_BUFFER[0] = 'A'; rcvstate |= 0x81; break; case 'B': if(rcvstate == 0x83) { rcvstate = 0xC4; UART_RCV_BUFFER[3] = 'B'; } else { rcvstate = 0x00; } break; default: if(UART_RCV_DATA - '0' <= 9) { if(rcvstate & 0xC0) { UART_RCV_BUFFER[rcvstate & 0x0F] = UART_RCV_DATA; rcvstate += 1; } else { rcvstate = 0x00; } } else { rcvstate = 0x00; } if((rcvstate & 0x0F) == 8) { rcvstate |= 0x20;
uint32_t CMD_temp = 0x00000000; CMD_temp = 10 * (UART_RCV_BUFFER[1] - '0') + (UART_RCV_BUFFER[2] - '0'); CMD_temp <<= 16; CMD_temp += 1000 * (UART_RCV_BUFFER[4] - '0') + 100 * (UART_RCV_BUFFER[5] - '0') + 10 * (UART_RCV_BUFFER[6] - '0') + 1 * (UART_RCV_BUFFER[7] - '0'); if(osMessageQueuePut(CMD_QueueHandle, &CMD_temp, 0, 0) == osOK) { rcvstate = 0x00; } else { rcvstate |= 0x10; } } break; } if(rcvstate & 0x10) { rcvstate = 0x00; } }
|
解析过程
代码里面有注释可以参考,口头表述比较困难这里用结果来表示吧。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| //char input[13] = "A02B0005CCCC";
输入的数据为 :A rcvstate: 81 输入的数据为 :0 rcvstate: 82 输入的数据为 :2 rcvstate: 83 输入的数据为 :B rcvstate: c4 输入的数据为 :0 rcvstate: c5 输入的数据为 :0 rcvstate: c6 输入的数据为 :0 rcvstate: c7 输入的数据为 :5 rcvstate: e8 输入的数据为 :C rcvstate: 0 输入的数据为 :C rcvstate: 0 输入的数据为 :C rcvstate: 0 输入的数据为 :C rcvstate: 0 输入的数据为 : rcvstate: 0
|
已知的BUG
发送 A02B010
也会有数据产生,而且会乱码
本文作者:wxy
本文链接: https://c.undf.top/posts/a941f9c6/
文章默认使用 CC BY-NC-SA 4.0 协议进行许可,使用时请注意遵守协议。
本站不设评论,网站底部邮件图标可以联系博主