OpenEdv-开源电子网

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

【求助】关于232通信协议用数组判断头尾校验帧,求一个完整有详细注解的例程,真的有困难!

[复制链接]

8

主题

50

帖子

0

精华

初级会员

Rank: 2

积分
119
金钱
119
注册时间
2017-3-12
在线时间
27 小时
发表于 2017-6-11 02:09:00 | 显示全部楼层 |阅读模式
10金钱
找了很久资料,真的难学,感觉要炸了
希望原子哥能够加上 如何自制串口协议的教程!真的很有必要,不搞协议的232等于没搞,现在随便什么通信都要有协议保证稳定
真的学了好久 还没搞懂!
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

50

主题

1805

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
6662
金钱
6662
注册时间
2016-5-29
在线时间
910 小时
发表于 2017-6-11 09:00:32 | 显示全部楼层
如何事实证明你不适合.放弃它也不是坏的选择.你会发现,在另一片天地才是你的舞台.
回复

使用道具 举报

24

主题

695

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1666
金钱
1666
注册时间
2016-4-29
在线时间
266 小时
发表于 2017-6-11 09:15:02 | 显示全部楼层
原子的全程中不就有校验吗?
回复

使用道具 举报

8

主题

50

帖子

0

精华

初级会员

Rank: 2

积分
119
金钱
119
注册时间
2017-3-12
在线时间
27 小时
 楼主| 发表于 2017-6-11 10:08:13 来自手机 | 显示全部楼层
d1z1y2 发表于 2017-6-11 09:15
原子的全程中不就有校验吗?

什么全程?只校验了0x0a和0x0D啊 提供上位机发烧一串数组 我32来判断数组中的第2个字符 来执行相应的代码 要怎么改?
回复

使用道具 举报

8

主题

50

帖子

0

精华

初级会员

Rank: 2

积分
119
金钱
119
注册时间
2017-3-12
在线时间
27 小时
 楼主| 发表于 2017-6-11 10:09:17 来自手机 | 显示全部楼层
操作系统 发表于 2017-6-11 09:00
如何事实证明你不适合.放弃它也不是坏的选择.你会发现,在另一片天地才是你的舞台.

不能放弃 为了生活!
回复

使用道具 举报

50

主题

1805

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
6662
金钱
6662
注册时间
2016-5-29
在线时间
910 小时
发表于 2017-6-11 10:26:14 | 显示全部楼层
yinqirui9 发表于 2017-6-11 10:09
不能放弃 为了生活!

这说明你对它还是有点兴趣的.CRC校验是很简单的.多看一下另外的例程.会明白的.另外串口的奇偶校验也是其中方法之一.你可以看看,理解理解.
回复

使用道具 举报

8

主题

50

帖子

0

精华

初级会员

Rank: 2

积分
119
金钱
119
注册时间
2017-3-12
在线时间
27 小时
 楼主| 发表于 2017-6-11 10:29:29 来自手机 | 显示全部楼层
操作系统 发表于 2017-6-11 10:26
这说明你对它还是有点兴趣的.CRC校验是很简单的.多看一下另外的例程.会明白的.另外串口的奇偶校验也是其 ...

后面的视频还会讲通信协议吗 第几课呢?
回复

使用道具 举报

50

主题

1805

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
6662
金钱
6662
注册时间
2016-5-29
在线时间
910 小时
发表于 2017-6-11 10:56:41 | 显示全部楼层
不知道呢.我不是原子团队成员.
回复

使用道具 举报

11

主题

216

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1124
金钱
1124
注册时间
2015-2-27
在线时间
485 小时
发表于 2017-6-11 11:50:46 | 显示全部楼层
判断任何头尾帧都是徒劳的(你无法保障数据内不含跟头尾帧一样的数据),时间约定才是王道,
回复

使用道具 举报

8

主题

50

帖子

0

精华

初级会员

Rank: 2

积分
119
金钱
119
注册时间
2017-3-12
在线时间
27 小时
 楼主| 发表于 2017-6-11 12:12:18 | 显示全部楼层
enan 发表于 2017-6-11 11:50
判断任何头尾帧都是徒劳的(你无法保障数据内不含跟头尾帧一样的数据),时间约定才是王道,

怎么约定?有例子吗
回复

使用道具 举报

11

主题

216

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1124
金钱
1124
注册时间
2015-2-27
在线时间
485 小时
发表于 2017-6-11 12:23:45 | 显示全部楼层
yinqirui9 发表于 2017-6-11 12:12
怎么约定?有例子吗

约定每帧数据之间的间隔,
例如约定每帧数据的间隔10ms,接收到第一个字节开个5ms定时器,之后你每接收到1个字节复位定时器为5ms,5ms到后表示接收完成。

那个什么串口空闲中断DMA去接收MODBUS就是个比较**的想法,有些低端MCU自己本身就几把很忙,串口发送的时候被打断了,出现了停顿的情况,串口空闲中断就判断接收完成了。
回复

使用道具 举报

8

主题

50

帖子

0

精华

初级会员

Rank: 2

积分
119
金钱
119
注册时间
2017-3-12
在线时间
27 小时
 楼主| 发表于 2017-6-11 12:38:43 | 显示全部楼层
enan 发表于 2017-6-11 12:23
约定每帧数据之间的间隔,
例如约定每帧数据的间隔10ms,接收到第一个字节开个5ms定时器,之后你每接收 ...

那上位机怎么发间隔10ms的数据呢?有实际的例程吗,光那么看新手不是很懂啊
回复

使用道具 举报

11

主题

216

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1124
金钱
1124
注册时间
2015-2-27
在线时间
485 小时
发表于 2017-6-11 12:45:20 | 显示全部楼层
yinqirui9 发表于 2017-6-11 12:38
那上位机怎么发间隔10ms的数据呢?有实际的例程吗,光那么看新手不是很懂啊

不是上位机间隔10ms发送数据,你这完全是崭新的新手啊

是说的这个10ms是两帧数据之间的最小间隔10ms,你拿5ms时间来判断收到数据后接下来的5ms有没有再次收到数据,如果没有就是一帧数据结束了
回复

使用道具 举报

63

主题

305

帖子

1

精华

高级会员

Rank: 4

积分
853
金钱
853
注册时间
2012-8-3
在线时间
79 小时
发表于 2017-6-11 12:58:22 | 显示全部楼层
都有帧尾了,为什么要用时间来判断帧结束?时间是用来判断超时的,超过一定时间丢弃当前帧,当然,如果你硬要设计成永久等待帧尾也行,不过实际开发中很少这么做,至于超时时间,用计数就搞定了。

论坛都有类似的帖子了:
http://www.openedv.com/posts/list/53066.htm
回复

使用道具 举报

8

主题

50

帖子

0

精华

初级会员

Rank: 2

积分
119
金钱
119
注册时间
2017-3-12
在线时间
27 小时
 楼主| 发表于 2017-6-11 13:00:20 | 显示全部楼层
enan 发表于 2017-6-11 12:45
不是上位机间隔10ms发送数据,你这完全是崭新的新手啊

是说的这个10ms是两帧数据之间的最小间隔10ms ...

那打开定时器是 用定时中断 来扫描吗?
回复

使用道具 举报

11

主题

216

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1124
金钱
1124
注册时间
2015-2-27
在线时间
485 小时
发表于 2017-6-11 13:07:27 | 显示全部楼层
yinqirui9 发表于 2017-6-11 13:00
那打开定时器是 用定时中断 来扫描吗?

是滴,当收到第一个字节打开一个定时器,之后每次收到一个字节重新手动装填定时器,如果发生中断了就是表示接收完成了。
不过一般不会用硬件定时器来做,如果有8个串口要开8个定时器,一般自己写个软件定时器
回复

使用道具 举报

11

主题

216

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1124
金钱
1124
注册时间
2015-2-27
在线时间
485 小时
发表于 2017-6-11 13:11:25 | 显示全部楼层
EDA3rd 发表于 2017-6-11 12:58
都有帧尾了,为什么要用时间来判断帧结束?时间是用来判断超时的,超过一定时间丢弃当前帧,当然,如果你硬 ...

对于发送16进制数的时候,特别是浮点数的时候,你敢保证数据里不会带有你所约定的尾帧。
单用超时一项可以完成结束判断与超时判断,而且提高鲁棒性
回复

使用道具 举报

8

主题

45

帖子

0

精华

高级会员

Rank: 4

积分
548
金钱
548
注册时间
2015-1-18
在线时间
173 小时
发表于 2017-6-11 13:12:19 | 显示全部楼层
自己定通信协议啊,比如:
序号        字段名称        位宽        字段功能
0        起始标志        1        约定为fa
1        长度                1      表示操作命令+内容的长度
2        操作命令         1        00h(设置) / 01h(获取) /02h(返回)
3        内容                n       
4        校验字节        1        除字头字尾外的所有字节ODD校验
5        结束标志位        1        约定为0xFB


这样在串口中断里收到头后,开始计数,等收到尾字节后判断(计数-4)和长度是否相等,判断自己计算的校验和校验字节是否相等,然后做相应处理,是丢弃,继续接受,还是保存
回复

使用道具 举报

63

主题

305

帖子

1

精华

高级会员

Rank: 4

积分
853
金钱
853
注册时间
2012-8-3
在线时间
79 小时
发表于 2017-6-11 13:28:06 | 显示全部楼层
一个爱做梦的人 发表于 2017-6-11 13:12
自己定通信协议啊,比如:
序号        字段名称        位宽        字段功能
0        起始标志        1        约定为fa

同意楼上,帧头+命令+数据+帧尾+校验和,这是标准做法。
enan提出的超时判断帧结束,个人感觉不如帧尾+校验的判断方法实用。
用帧间隔来判断帧结束,又如何能保证数据完整性呢?
回复

使用道具 举报

11

主题

216

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1124
金钱
1124
注册时间
2015-2-27
在线时间
485 小时
发表于 2017-6-11 13:28:51 | 显示全部楼层
呵呵,我的目的就是严厉打击那些定义首尾帧的协议。
如果通讯中产生一次错误,可能会导致永久性的通讯失败,比如数据中有与首尾帧一致的数据,然后导致的是每次接收数据的帧错位,错位后协议数据长度字段如果是个很大的数,导致接收方死等,等回来了还是个错的,而且又错位了。
回复

使用道具 举报

11

主题

216

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1124
金钱
1124
注册时间
2015-2-27
在线时间
485 小时
发表于 2017-6-11 13:34:36 | 显示全部楼层
EDA3rd 发表于 2017-6-11 13:28
同意楼上,帧头+命令+数据+帧尾+校验和,这是标准做法。
enan提出的超时判断帧结束,个人感觉不如帧尾+ ...

串口数据一般是连续发送的,用时间来判断怎么不能保障完整性?
一般上一个字节与下一个字节间隔不会超过5ms,超过了肯定是出现问题了,完整性来说我并没有说数据校验可以去掉。
回复

使用道具 举报

63

主题

305

帖子

1

精华

高级会员

Rank: 4

积分
853
金钱
853
注册时间
2012-8-3
在线时间
79 小时
发表于 2017-6-11 13:37:35 | 显示全部楼层
enan 发表于 2017-6-11 13:28
呵呵,我的目的就是严厉打击那些定义首尾帧的协议。
如果通讯中产生一次错误,可能会导致永久性的通讯失败 ...

如果担心长度过长,永久失败,可以增加长度检查机制。而且长数据应当拆开成帧

回复

使用道具 举报

8

主题

50

帖子

0

精华

初级会员

Rank: 2

积分
119
金钱
119
注册时间
2017-3-12
在线时间
27 小时
 楼主| 发表于 2017-6-11 13:40:25 | 显示全部楼层
enan 发表于 2017-6-11 13:07
是滴,当收到第一个字节打开一个定时器,之后每次收到一个字节重新手动装填定时器,如果发生中断了就是表 ...

软件定时和硬件定时器 原子教程里有讲吗( ⊙ o ⊙ )…… 表示不知道怎么区分
回复

使用道具 举报

11

主题

216

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1124
金钱
1124
注册时间
2015-2-27
在线时间
485 小时
发表于 2017-6-11 13:45:04 | 显示全部楼层
EDA3rd 发表于 2017-6-11 13:37
如果担心长度过长,永久失败,可以增加长度检查机制。而且长数据应当拆开成帧

老哥,要下次再来个数据跟首尾帧一样的列?
串口收发个数而已,如果本身我就只是发个浮点数,加上这么多什么首尾帧、长度、冗余的东西来提高鲁棒性,这些个数据传输也得耗费时间,浪费MCU时间,为什么不用一个定时器搞定它
回复

使用道具 举报

11

主题

216

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1124
金钱
1124
注册时间
2015-2-27
在线时间
485 小时
发表于 2017-6-11 13:48:16 | 显示全部楼层
yinqirui9 发表于 2017-6-11 13:40
软件定时和硬件定时器 原子教程里有讲吗( ⊙ o ⊙ )…… 表示不知道怎么区分

原子教程里面没有,软件定时器是自己写的,网上有,很简单的东西
回复

使用道具 举报

8

主题

50

帖子

0

精华

初级会员

Rank: 2

积分
119
金钱
119
注册时间
2017-3-12
在线时间
27 小时
 楼主| 发表于 2017-6-11 14:30:49 | 显示全部楼层
enan 发表于 2017-6-11 13:48
原子教程里面没有,软件定时器是自己写的,网上有,很简单的东西

是不是就是原子里面的 delay_ms()?
回复

使用道具 举报

11

主题

216

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1124
金钱
1124
注册时间
2015-2-27
在线时间
485 小时
发表于 2017-6-11 15:06:58 | 显示全部楼层
delay_ms()是阻塞性延时,不能用这个,而且任何程序里面不到万不得已的情况下不能用它,如IO模拟总线的情况下用一下,或硬件上电初始化的时候非要用的情况下用下。
至此,任何情况下都不要用这个函数,包括按键扫描,跑马灯。
也就是说在进入while循环后,任何情况下都不要用他,只要用到他就表明你的程序需要改进。
回复

使用道具 举报

8

主题

50

帖子

0

精华

初级会员

Rank: 2

积分
119
金钱
119
注册时间
2017-3-12
在线时间
27 小时
 楼主| 发表于 2017-6-11 15:47:16 | 显示全部楼层
enan 发表于 2017-6-11 15:06
delay_ms()是阻塞性延时,不能用这个,而且任何程序里面不到万不得已的情况下不能用它,如IO模拟总线的情况 ...

那如果我要延时怎么办?直接判断定时器是否等于相应的倍数吗?
回复

使用道具 举报

11

主题

216

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1124
金钱
1124
注册时间
2015-2-27
在线时间
485 小时
发表于 2017-6-11 16:14:59 | 显示全部楼层
yinqirui9 发表于 2017-6-11 15:47
那如果我要延时怎么办?直接判断定时器是否等于相应的倍数吗?

这个问题已经无法结帖了,你能把原子那本书学完了再来考虑这些事情吗,很多东西是需要经验积累的,不管原子其他的例程跟这个串口例程有没有关系,但总能开阔你的视野,回过头来你自然而然的会明白我说的这些东西。
不要因为一个串口通讯就把你卡在这里,把自己的自信心摧毁了,本来像这种串口问题我都不想回答的,看了你那句为了生活,跟你讲了这么多,确实论坛里很多像二楼大神一样上来就摧毁了新人幼小的心灵。但你的现在视野局限性没办法理解。
串口通讯这块可以学到很多的东西,串口可以挖得很深,包括后续的TCP也是一样。但建议你现在跳过它。
回复

使用道具 举报

8

主题

50

帖子

0

精华

初级会员

Rank: 2

积分
119
金钱
119
注册时间
2017-3-12
在线时间
27 小时
 楼主| 发表于 2017-6-11 16:26:57 | 显示全部楼层
enan 发表于 2017-6-11 16:14
这个问题已经无法结帖了,你能把原子那本书学完了再来考虑这些事情吗,很多东西是需要经验积累的,不管原 ...

谢谢 老铁扎心了
回复

使用道具 举报

8

主题

50

帖子

0

精华

初级会员

Rank: 2

积分
119
金钱
119
注册时间
2017-3-12
在线时间
27 小时
 楼主| 发表于 2017-6-11 16:29:41 | 显示全部楼层
yklstudent 发表于 2017-6-11 02:09
参考网上的modbus协议啊,范例就有免费的freemodbus啊

哪一课有讲?范例在哪?
回复

使用道具 举报

2

主题

130

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1884
金钱
1884
注册时间
2011-9-16
在线时间
423 小时
发表于 2017-6-11 22:11:07 | 显示全部楼层
目前我这边的做法是开辟一个大的接收数据缓存区(1200字节)),中断接收的数据直接写入缓存,任务中间隔一定时间不断的去检索帧头和帧尾的关键字,然后根据帧头和帧尾在缓存区的位置确认数据块的偏移量,读出数据校验后和帧尾前的校验位比较,处理完后清空接收缓存,返回应答数据给发送方,这样通过GPRS模块接收服务器下发的1000字节的数据貌似都没有什么问题,即使有问题也可以通过错误应答来判断是什么类型的错误,是否需要重发等等。
回复

使用道具 举报

10

主题

271

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1236
金钱
1236
注册时间
2015-5-14
在线时间
352 小时
发表于 2017-6-15 22:52:11 来自手机 | 显示全部楼层
看看这个,http://m.blog.csdn.net/wuhenyouyuyouyu/article/details/54377176
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-8-18 04:54

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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