C:从环形缓冲区提取帧数据

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

嵌入式平台如何从数据流中提取一帧数据?

通过实例来说明问题:

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
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值