嵌入式平台如何从数据流中提取一帧数据?
通过实例来说明问题:
A作为主机(上位机软件),B作为从机(STM32)硬件和电机连接,A和B之间通过串口通讯,使A能间接的控制电机正反转,速度等。
协议初定:
问题一:怎么判断帧数据开始信息?
通过定义一个固定的帧头,作为数据开始信号。记为0x01。
问题二:如何判断帧的长度?
帧的长度可以选择固定长度或可变长度。固定长度逻辑简单,检测到帧头后,往后读取固定的长度即可。可变长度灵活度高,一帧数据可以携带更多的信息量。那么可以在帧头后增加一个字节作为长度,记为0xXX,以便从机判断帧长。
问题三:数据格式?
数据格式按需编写,这里用16bit功能+16bit数据的方式。一组数据共4个字节。
问题四:如何校验帧完整性?
可以用两种方式:
1、增加帧尾作为数据结束标志,验证帧尾就知道数据是否完整。但是存在数据=帧尾、通讯异常的情况,这时候可能提取到了错误的数据。
2、采用通用校验方式,工业控制一般使用CRC16-MODBUS。这里增加两个字节作为检验码。这种方式可以保证数据不会出错。
至此:我们可以将通讯协议制定下来:
| 帧头 | 帧长 | 功能1 | 数据1 | 功能2 | 数据2 | 功能… | 数据… | CRC16高位 | CRC16低位 |
|---|---|---|---|---|---|---|---|---|---|
| 0x01 | len | 0xXX | 0xXX | 0xXX | 0xXX | 0xXX | 0xXX | CRC_H | CRC_L |
在理想状态下,从机在串口中断里面判断帧头,然后循环往后读取len长度的字节到数组里面去,最后验证一下CRC是否一致即可。
但实际使用往往面对更复杂的情形:
问题五:如果一帧数据没有提取完成,下一帧数据又过来了怎么处理?
这个问题其实就是要解决两件事情:什么时候接收数据?什么时候处理数据?
假设提取数据的函数为:UserExtractFrameData();该函数执行时间为1us。
那么由简入繁看看几种方式:1、中断接收中断处理。(弊端太明显不再赘述)
2、中断保存到buff,中断外处理buff,处理完后buff清空。uint8_t RecvBuff
嵌入式串口通信协议设计与数据完整性保障

本文介绍了如何设计嵌入式系统的串口通信协议,包括帧头定义、帧长度判断、数据格式设定、帧完整性校验以及如何处理数据流中的帧交错问题。使用环形缓冲区解决了数据接收与处理的同步问题,并提出了应对一对多通信场景的字节流处理策略。此外,还讨论了处理长时间传输数据的方案,以确保在数据处理过程中不出现错误。
最低0.47元/天 解锁文章
1万+

被折叠的 条评论
为什么被折叠?



