串口使用杂记
作者:互联网
场景
实验是stm32 & Linux开发板间的TTL串口通信
32要一直回传一组固定长度为15的 包头包尾为ff的数据
问题
linux经常无法正确的解析
收到的数据
串口&接收
伪代码
//格式:0xff int32_t int32_t int32_t 0xff
while(true)
{
std::vector<uint8_t> vSerialDat;
while(Serial.readable()!=15)//缓冲区以存下的字节的数目
{
//等待完整的15个字节
wait1;
}
//得到数据->这一步之后 Serial.readable()就是0了,因为缓冲区的内容以全被读出
Serial.read(&vSerialDat);
//并解析
HandleData(&vSerialDat);
wait2; //等待下15个字节
}
缺点暴露无遗:
- 问题1:wait2之后 ,若恰好收到了大于15个字节 则程序将卡死在第二个while ->
==15
这个条件太苛刻 - 问题2:若linux重启 serial接受恰好从 2个 0xff中间接受数据 那么程序不会卡死 但解析的数据永远是错的 ->需要调整接收节奏了
just resolve it
问题1
==15
->
>=15
还是按照15个字节解析 如果有多余的就留给下一次解析
问题2
症结
在于 linux端的程序并不是从“包头”开始解析程序的,我们要重新调整识别节奏,找到“包头”
那就要识别到包头 抛弃包头之前的数据,等待与之成对的包尾,解析头尾间包含的数据就可以了
你应该注意到了 头尾都是0xff 那这样头尾似乎无法分辨,呵呵 还有别的办法
理想状态下的程序运行逻辑
接收数据-》0xff int32_t int32_t int32_t 0xff
解析数据
..无限循环
出现问题2的串口数据:
接收数据-> ?? ?? ?? 0xff 0xff ?? ...
如若出现问题2,则程序接受了15个字节 第一个并不是0xff
并不需要区分 包头、包尾: 2个0xFF是linux接收的所有数据的分隔符
数据1 ff ff 数据2 ff ff 数据3 ff ...
不考虑串口数据错误的问题 ff ff 与 ff ff 间必为正确的数据
而且只要出现问题2,前15个字节内必有ff ff
到这里 思路应当就畅通了 ,接受15个字节 正常则解析 不正常则根据ff ff 作为寻找新接收位置的依据
写后杂言
- 同样的场景 东北某校用的SPI (带纠错)
- 想试试freemodbus
- 包头与包尾之间有ff ff怎么处理呢。。
写着写着小写字母的字体变了,以为是cnblog的问题 发现是电脑问题。
大小写也没办法切换了 呵呵
标签:int32,15,字节,串口,杂记,使用,0xff,解析,数据 来源: https://www.cnblogs.com/MousseLee/p/16215260.html