串口通讯数据帧问题

q9923 2011-10-19 11:40:44
现在要用单片机和上位机进行串口通讯,单片机每20秒发送给上位机一个数据帧,其格式是这样的:

ffffff0411aa1e08

其中ffffff是帧头部,04是数据部分的字节数,11aa1e08就是数据部分。数据部分的长度是不固定的。

那请问大家这样的上位机串口程序一般怎样写?我想是先读三个字节判断其是不是ffffff,如果是的话就再读一个字节,然后根据读取的字节大小确定读取数据的长度,在读取之。

但有一个问题是如果由于某种原因某次发送的数据帧格式有错误,比如头部不是ffffff,或者由于某种原因两个数据帧之间发来了一些无效的干扰字节,那我读取了之后怎么办?后面的数据怎么处理?关键问题也就是如何保证错误的帧或干扰字节不影响对之后的帧的采集?
给个思路就好了,不甚感激!
...全文
621 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
绿领巾童鞋 2011-10-20
  • 打赏
  • 举报
回复
en,stonespace继续
q9923 2011-10-20
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 stonespace 的回复:]
我的做法是连续读取到一个字符串或者byte类型缓冲区中,读取串口一般不能一次读完,都要分几次,还不如在事件中把数据加到缓冲区,然后触发另一段代码从缓冲区里检查是否存在一个完整的数据帧,先在缓冲区中查找第一个帧头部,如果找到,检查后面的数据够了没有,如果够了就是有一个完整数据帧,把这个帧从缓冲整个取出,

否则什么都不做直到下次有新数据添加到缓冲,再执行类似的操作,
[/Quote]
----------------------------------------
谢谢,再请教下,.NET有个SerialPort类,在DataReceived事件函数里检查是否有完整的数据帧还是触发一个新线程用于检查数据帧好?
还有,我想会不会有这样的情况,假如我缓冲区是byte[100],恰好帧长度也是100左右,这样ffffff在缓冲区里有可能被截断了,即比如有可能是byte[98、99]=ffff,而byte[0]=ff,这样的情况貌似很棘手啊?写程序时要不要考虑?
shan7719515 2011-10-20
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 stonespace 的回复:]

我的做法是连续读取到一个字符串或者byte类型缓冲区中,读取串口一般不能一次读完,都要分几次,还不如在事件中把数据加到缓冲区,然后触发另一段代码从缓冲区里检查是否存在一个完整的数据帧,先在缓冲区中查找第一个帧头部,如果找到,检查后面的数据够了没有,如果够了就是有一个完整数据帧,把这个帧从缓冲整个取出,

否则什么都不做直到下次有新数据添加到缓冲,再执行类似的操作,
[/Quote]
我也正在做串口通信,也遇到这个问题,数据不合法现象。请问一下,那个怎么从缓冲区中检查
shan7719515 2011-10-20
  • 打赏
  • 举报
回复
mark
stonespace 2011-10-20
  • 打赏
  • 举报
回复
一般没必要用线程,我以前是这样做的,从缓冲中检查和取出数据帧写成一个方法A,在DataReceived事件里,把数据追加进缓冲后,调用方法A,方法A内部取出数据帧后就直接调用处理数据帧的方法,然后继续取数据帧直到找不到数据帧为止,

而缓冲的长度,则要比数据帧大两倍,这样就不会出现截断的情况,但如果缓冲真的溢出,可以把最老的数据扔掉,放进刚从串口得到的新数据,这样即使出现fff在byte[96]也不会有问题,这时候缓冲溢出,只需要在下次接受数据的时候,把byte中的数据前移n个字节,n是新数据长度,这样最老的n个数据被冲掉,但fff仍然在,它和新数据连起来后,就组成完整的帧头,


[Quote=引用 3 楼 q9923 的回复:]

谢谢,再请教下,.NET有个SerialPort类,在DataReceived事件函数里检查是否有完整的数据帧还是触发一个新线程用于检查数据帧好?
还有,我想会不会有这样的情况,假如我缓冲区是byte[100],恰好帧长度也是100左右,这样ffffff在缓冲区里有可能被截断了,
[/Quote]
stonespace 2011-10-20
  • 打赏
  • 举报
回复
在缓冲中查找第一个"ffffff",如果是字符串的话可以用String.IndexOf,如果是byte数组,那么就用for循环自己匹配,总之是找到第一个"ffffff"在缓冲中的位置,这样可以忽略掉"ffffff"之前的无效数据,
stonespace 2011-10-20
  • 打赏
  • 举报
回复
我的做法是连续读取到一个字符串或者byte类型缓冲区中,读取串口一般不能一次读完,都要分几次,还不如在事件中把数据加到缓冲区,然后触发另一段代码从缓冲区里检查是否存在一个完整的数据帧,先在缓冲区中查找第一个帧头部,如果找到,检查后面的数据够了没有,如果够了就是有一个完整数据帧,把这个帧从缓冲整个取出,

否则什么都不做直到下次有新数据添加到缓冲,再执行类似的操作,

110,566

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧