OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 7037|回复: 18

串口通信中的“帧同步”小困惑,求小伙伴们解答下

[复制链接]

8

主题

31

帖子

0

精华

初级会员

Rank: 2

积分
84
金钱
84
注册时间
2012-12-4
在线时间
0 小时
发表于 2013-11-23 01:11:08 | 显示全部楼层 |阅读模式
本人最近在研究RS232串口通信,用战舰开发板DMA+串口模式,循环。
与电脑通信进行模拟。
但是考虑到实际应用情况中,双机间通信帧包括了“帧头、地址、命令、长度、数据、校验”等。
现在的疑问是:
假如帧头定义为0xff,那在之后的数据中如果也出现了0xff,我如何识别此0xff非帧头呢?
即便帧头定义为两个字节,在后面的数据中也有重复的可能性啊。。
看网上都没有这个方面的解释啊。。。
请小伙伴们给予指导。。。谢谢了。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

2

主题

1446

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
2256
金钱
2256
注册时间
2010-12-16
在线时间
206 小时
发表于 2013-11-23 01:14:11 | 显示全部楼层
你的校验不是吃素的吧.
技术讨论请发帖 , 需要我回复请点左下的 < 回复 > 让系统通知我 . 本人不通过其他方式返回任何参数.
回复 支持 反对

使用道具 举报

120

主题

7878

帖子

13

精华

资深版主

Rank: 8Rank: 8

积分
12012
金钱
12012
注册时间
2013-9-10
在线时间
427 小时
发表于 2013-11-23 08:15:20 | 显示全部楼层
回复【楼主位】lqz9057:
---------------------------------
你后面不是跟有长度,检验么,难道摆着好看???
现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
回复 支持 反对

使用道具 举报

8

主题

31

帖子

0

精华

初级会员

Rank: 2

积分
84
金钱
84
注册时间
2012-12-4
在线时间
0 小时
 楼主| 发表于 2013-11-23 10:23:01 | 显示全部楼层
回复1楼、2楼,感谢。
个人感觉还是需要帧与帧间的 串口超时 才可以。
长度和校验是可以利用,但仅作为参考,是有局限性的。
举例:
假如帧头是0xff
如果仅仅依靠长度和检验,假如 我开机上电初始化后,计算机(主机)正在发送100个字节的帧。接收到的数据是从中间第20个字节开始,而第50个字节恰好是个0xff,此时已得帧头。但是长度永远不够(因为仅仅还有100-50=50个长度),长度不够自然不能检验,那就等待数据?“穷等”肯定是不行的。
因此,必须考虑“帧与帧间的超时报警”,丢弃之前的“半成品”。

请问小伙伴,我的思考对否?
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-11-23 10:44:48 | 显示全部楼层
回复【4楼】lqz9057:
---------------------------------
按帧接收很容易做啊.
你记住一点:帧与帧之间,必须是有间隔的,这个间隔,远远大于串口连续发送2个字符之间的时间.
一般协议里面规定:50ms一帧,或者20ms一帧.甚至10ms一帧.就是指发送完一帧后,至少再过10ms/20MS.50MS再发下一帧,假设你波特率为9600,那么2个字符之间的时间一般不会超过2ms,所以你很明显的,就可以判断这些数据属不属于一个帧.

即便你是半路出家,截取了帧的一部分,但是由于校验帧头等检测过不去...直接丢弃之.等待下一帧到来.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

8

主题

31

帖子

0

精华

初级会员

Rank: 2

积分
84
金钱
84
注册时间
2012-12-4
在线时间
0 小时
 楼主| 发表于 2013-11-23 10:58:45 | 显示全部楼层
回复【5楼】正点原子:
回复【4楼】lqz9057: --------------------------------- 按帧接收很容易做啊. 你记住一点:帧与帧之间,必须是有间隔的,这个间隔,远远大于串口连续发送2个字符之间的时间. 一般协议里面规定:50ms一帧,或者20ms一帧.甚至10ms一帧.就是指发送完一帧后,至少再过10ms/20MS.50MS再发下一帧,假设你波特率为9600,那么2个字符之间的时间一般不会超过2ms,所以你很明显的,就可以判断这些数据属不属于一个帧. 即便你是半路出家,截取了帧的一部分,但是由于校验帧头等检测过不去...直接丢弃之.等待下一帧到来.
---------------------------------

正解。详细。感谢原子哥答疑解惑。
回复 支持 反对

使用道具 举报

2

主题

1446

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
2256
金钱
2256
注册时间
2010-12-16
在线时间
206 小时
发表于 2013-11-23 19:43:21 | 显示全部楼层
回复【4楼】lqz9057:
---------------------------------
你的例子,前一个帧已经被破坏了,无论是及时识别然后丢弃,还是等待下一个帧再识别,都是需要下一个帧来触发动作,有区别吗?

如果想提前丢弃,可以按照这个组织:

<头><长度><校验1(头,长度)><数据><校验2(头,长度,校验1,数据)>.

这样既可以识别长度是否合法,避免缓冲溢出,也可以提前丢弃数据.
技术讨论请发帖 , 需要我回复请点左下的 < 回复 > 让系统通知我 . 本人不通过其他方式返回任何参数.
回复 支持 反对

使用道具 举报

8

主题

31

帖子

0

精华

初级会员

Rank: 2

积分
84
金钱
84
注册时间
2012-12-4
在线时间
0 小时
 楼主| 发表于 2013-11-24 01:22:44 | 显示全部楼层
回复【7楼】shihantu:
---------------------------------

貌似挺复杂啊。不能改通信协议模式啊。因为人家已经定了,我只能接收,不能修改了。

如果可以修改的话,有个办法可以参考。
帧头(2字节)、地址(1字节)、命令(1字节)、长度(1字节)、数据(N字节)、校验(2字节)    协议格式可以自定义,非规定。
假如帧头是0xFF 0x00,则除开帧头外,以后出现的各字节,凡事有字节0xFF出现的,都后缀增加一个非0x00的字节,例如0x22,这样就成了编码了。避免了非帧头出现0xFF 0X00的情况。也就是只有帧头是0xFF 0x00,其他任何时候都看不到有这个数据出现。
例如:
    帧头     + 地址  + 命令 +  长度  +        数据区     +     校验
0xFF 0x00  +  0x00  + 0x00 +  0x0a   +   0xFF 0x22 0x00  +  CRC1 CRC2(其实数据区是0xFF 0x00,为了避免等同于帧头,所以加了0x22。)
这样,只要接收到0xFF 0x00就是一帧数据的开始了。。。。

还有 连帧头都不要的,直接命令即可。
帧格式:命令(1字节)+长度(1字节)+数据(N字节)+校验    这个的关键是要让除命令外,其他字节的内容不要与命令重复。这就要进行编码的。
回复 支持 反对

使用道具 举报

2

主题

1446

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
2256
金钱
2256
注册时间
2010-12-16
在线时间
206 小时
发表于 2013-11-24 15:26:34 | 显示全部楼层
回复【8楼】lqz9057:
---------------------------------
这样也可以,增加运算开销而已.

如前所述,不改通信格式的话,收到假的帧头后,无论是在获得校验前识别还是获得校验后识别,下一个有效数据都是在下一个帧过来后才获得,那就没必要纠结这个问题.
技术讨论请发帖 , 需要我回复请点左下的 < 回复 > 让系统通知我 . 本人不通过其他方式返回任何参数.
回复 支持 反对

使用道具 举报

8

主题

31

帖子

0

精华

初级会员

Rank: 2

积分
84
金钱
84
注册时间
2012-12-4
在线时间
0 小时
 楼主| 发表于 2013-11-24 23:30:55 | 显示全部楼层
回复【9楼】shihantu:
---------------------------------
回复【9楼】shihantu:
回复【8楼】lqz9057: --------------------------------- 这样也可以,增加运算开销而已. 如前所述,不改通信格式的话,收到假的帧头后,无论是在获得校验前识别还是获得校验后识别,下一个有效数据都是在下一个帧过来后才获得,那就没必要纠结这个问题.
---------------------------------

这个有些不懂,请指教:“(1)下一个有效数据”和前面的“(2)假帧头+无效数据+校验”如何区分。这(1)(2)两者之间应该是超时问题吧。不然,我怎么知道“下一个有效数据”是不是属于上一帧的呢?如果不判断时间,而串口一直在接收中,中间的时间间隔不考虑,那自然就会把下一帧的“正确帧头”给弄到了前一错误帧的“数据”去了。
“没必要纠结这个问题”能否给予个举例说明下。。。先表示感谢了。。。
(个人考虑:主要是这个串口通信协议仅仅是有一个帧头,没有帧尾,长度还是任意的,非定长。判断一个帧只能依靠帧头做开始,长度字节定义的值识别结束。除开超时判断,其他还有什么高招可以识别帧与帧呢?)
回复 支持 反对

使用道具 举报

2

主题

1446

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
2256
金钱
2256
注册时间
2010-12-16
在线时间
206 小时
发表于 2013-11-24 23:56:53 | 显示全部楼层
回复【10楼】lqz9057:
---------------------------------
1.没有超时.假头校验失败,把假头去掉,剩下的所有数据重新找头,也没有说把下一个头也去掉了.

2.只要有头用于同步就可以,校验是用于判断是否同步正确的.
技术讨论请发帖 , 需要我回复请点左下的 < 回复 > 让系统通知我 . 本人不通过其他方式返回任何参数.
回复 支持 反对

使用道具 举报

8

主题

31

帖子

0

精华

初级会员

Rank: 2

积分
84
金钱
84
注册时间
2012-12-4
在线时间
0 小时
 楼主| 发表于 2013-11-25 14:11:03 | 显示全部楼层
回复【11楼】shihantu:
回复【10楼】lqz9057: --------------------------------- 1.没有超时.假头校验失败,把假头去掉,剩下的所有数据重新找头,也没有说把下一个头也去掉了. 2.只要有头用于同步就可以,校验是用于判断是否同步正确的.
---------------------------------
我举个例子吧,本来需要接收的信息帧格式及内容如下(假如此条信息连续发送)
解释      帧头  地址号  命令号   帧长度            数据区            CRC16检验码
第一帧    0xFF   0X00     0X06      0x0A       0xFF  0x00  0x02  0x0A        0xD3  0x8B
                                                        (帧时间间隔)
解释          帧头  地址号  命令号   帧长度           数据区             CRC16检验码
第二帧    0xFF   0X00     0X06      0x0A       0xFF  0x00  0x02  0x0A        0xD3  0x8B

1 假如第一帧我接收的时刻是在帧长度处(前面的帧头丢失了,从一个信息帧的中间开始有效地串口使能接收),因此,程序判断出的帧头一定是 数据区0xFF  0x00  0x02 0x0A中的0xFF,咋校验呢?还没有接收完成呢!如何得知“假头校验失败”或“那个0xff是假头”呢?
2 假如继续接收,按照通信协议,应该还是0x0a个长度的信息帧,但是按照假头算起才有0xFF  0x00  0x02  0x0A   0xD3  0x8B共计6个字节的长度,不要等待凑够10个才能计算校验?(校验是用于判断是否同步正确的?不是很理解。如果说信息帧接收完整的话,我理解为校验是为了检验接收的信息是否正确?传输中有没有因干扰导致错误字节的出现。如果按照我的举例,从假头算起,信息帧的长度都不够规定的帧长度[按规定,一个有效帧头开始的第4个字节为长度],那进行CRC校验岂不是无中生有。[第一帧结束后,由于第二帧还没有到来,串口没有新数据,因此假帧从帧头开始算起已接收的长度为6,此时存放接收数据的接收缓冲区里有默认数据,这个我明白。难道拿后续的默认数据参与进行CRC校验?])

其实说白了,不管真帧头还是假帧头,如何有效地识别上面举例通信中的 前帧与后帧 才是本问题的关键(靠长度恐怕不行吧,靠校验就是不懂了)。(除开原子哥所提到的超时外)

真心不懂,请指导。再次表示感谢。
回复 支持 反对

使用道具 举报

2

主题

1446

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
2256
金钱
2256
注册时间
2010-12-16
在线时间
206 小时
发表于 2013-11-25 16:00:31 | 显示全部楼层
1.不判断.即使有办法判断,应用代码也收不到有效的数据,与不判断没有区别.

2.是,但要注意参数合法性检查.
技术讨论请发帖 , 需要我回复请点左下的 < 回复 > 让系统通知我 . 本人不通过其他方式返回任何参数.
回复 支持 反对

使用道具 举报

2

主题

1446

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
2256
金钱
2256
注册时间
2010-12-16
在线时间
206 小时
发表于 2013-11-25 16:30:13 | 显示全部楼层
回复【12楼】lqz9057:
---------------------------------
要搞清楚<校验>的意义....
<校验>本身只能说明,被校验内容不是一个合法的内容而已,可能是头有问题,也可能是数据被修改.无论如何,能完全确认的就是在当前位置是头的情况下,数据不对.至于如何不对,就要其他手段.仅仅是抛弃的话,把头抛弃掉就够了.
技术讨论请发帖 , 需要我回复请点左下的 < 回复 > 让系统通知我 . 本人不通过其他方式返回任何参数.
回复 支持 反对

使用道具 举报

8

主题

31

帖子

0

精华

初级会员

Rank: 2

积分
84
金钱
84
注册时间
2012-12-4
在线时间
0 小时
 楼主| 发表于 2013-11-25 23:00:16 | 显示全部楼层
回复【14楼】shihantu:
---------------------------------
是不是如下这样:
串口接收不断持续,将串口来的数据源源不断地接收到缓冲区。
然后搜索帧头0xFF,找到帧头后,根据协议格式,计算校验(CRC校验),如果错误,就丢弃刚刚搜索到的帧头0xFF,继续搜索下一个帧头标志位0xFF,然后根据协议格式计算校验(CRC校验),如果正确,获取该通信信息帧,如果错误,丢弃该0xFF,继续搜索,直到搜索到正确的信息帧。。。。
举例:原本应该接收帧如下:
解释      帧头  地址号  命令号   帧长度            数据区            CRC16检验码
第一帧    0xFF   0X00     0X06      0x0A       0xFF  0x00  0x02  0x0A        0xD3  0x8B 

解释          帧头  地址号  命令号   帧长度           数据区             CRC16检验码 
第二帧    0xFF   0X00     0X06      0x0A       0xFF  0x00  0x02  0x0A        0xD3  0x8B

假如接收从第一帧0x0A开始,那么自然认定0xFF为帧头,因此缓冲区的数据将识别为如下序列:
(0x0A不考虑,非帧头)  0xFF  0x00  0x02  0x0A  0xD3  0x8B  0xFF  0X00  0X06  0x0A  0xFF  0x00  0x02  0x0A   0xD3  0x8B.........

根据通信规则,0xFF  0x00  0x02  0x0A  0xD3  0x8B  0xFF  0X00  0X06  0x0A组成一个完整帧,此时,CRC16=0x06 0x0A,肯定是错误的,因此果断的丢弃0xFF,继续搜寻下一个帧头,那就是“第二帧”
0xFF  0X00  0X06  0x0A  0xFF  0x00  0x02  0x0A   0xD3  0x8B

以此类推。。。。
我的理解是否正确呢?
回复 支持 反对

使用道具 举报

2

主题

1446

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
2256
金钱
2256
注册时间
2010-12-16
在线时间
206 小时
发表于 2013-11-26 09:23:19 | 显示全部楼层
是这样.
回复 支持 反对

使用道具 举报

14

主题

80

帖子

1

精华

中级会员

Rank: 3Rank: 3

积分
339
金钱
339
注册时间
2013-1-1
在线时间
6 小时
发表于 2013-11-26 10:30:15 | 显示全部楼层
应该不会有源源不绝的数据传来吧.....如果是单片机接收外部设备的控制的话,一般是先规定好一次发送多少数据,如果一条指令16字节,外部设备每次就发送16字节数据,每条数据的间隔10ms,50ms或200ms,肯定要预留一定时间给单片机处理的,不然外部设备一直发,它的处理速度要是比单片机快,单片机就卡死了!...所以这样就不会出现楼主担心的从第一帧的中间开始接收。

所以每次接收数据有很多种方法,我用过两种,一种是边接收边判断是不是合法数据,合法后再处理。第二种是先接收了,再去判断长度,校验位,判断第一二位是否是头码,第N位是否是命令码,第N位是否是地址码,等等,无误就进行处理。楼主担心的头码从中间开始了,那肯定过不了这样的验证,肯定是错的,所以我觉得楼主重心偏到了数据接收错误这问题上,而没有考虑数据处理方法这一问题。所以楼主找到一个好的处理方法就不用担心那些问题了。
回复 支持 反对

使用道具 举报

8

主题

31

帖子

0

精华

初级会员

Rank: 2

积分
84
金钱
84
注册时间
2012-12-4
在线时间
0 小时
 楼主| 发表于 2013-11-26 18:12:18 | 显示全部楼层
回复【17楼】疯狂者:
---------------------------------
回答很详细,可惜我没有啥分数给你。
问题是 对方的数据已指定,并非我设计的(当然,对方的数据有可能和你讲的一样进行发送),我只能顺其自然,考虑些后果。
而对于长度,肯定是没有办法限定的。因为它测量的结果是未知的(未定的),所以它得到的结果也是可长可短的,短的信息帧比如有50字节,长的信息帧可能有100字节。
连续发送倒是不太至于,毕竟通信过程没有那么繁忙,我只是假设,充分考虑,做个学习,方便以后出问题了可以解决。
再次感谢你的答案。
回复 支持 反对

使用道具 举报

8

主题

31

帖子

0

精华

初级会员

Rank: 2

积分
84
金钱
84
注册时间
2012-12-4
在线时间
0 小时
 楼主| 发表于 2013-11-26 18:12:28 | 显示全部楼层
回复【17楼】疯狂者:
---------------------------------
欧也
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-7-8 17:33

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表