高效解析单片机通讯协议,最实用的一个方法

Posted 小麦大叔

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了高效解析单片机通讯协议,最实用的一个方法相关的知识,希望对你有一定的参考价值。

点击上方“小麦大叔”,选择“置顶/星标公众号”

福利干货,第一时间送达

大家好,我是小麦,今天推荐一个通讯协议解析的方法。

前阵子一朋友使用单片机与某外设进行通信时,外设返回的是一堆格式如下的数据:

AA AA 04 80 02 00 02 7B AA AA 04 80 02 00 08 75 AA AA 04 80 02 00 9B E2 AA AA 04 80 02 00 F6 87 AA AA 04 80 02 00 EC 91

其中 AA AA 04 80 02 是数据校验头,后面三位是有效数据,问我怎么从外设不断返回的数据中取出有效的数据。

对于这种问题最容易想到的就是使用一个标志位用于标志当前正解析到一帧数据的第几位,然后判断当前接收的数据是否与校验数据一致,如果一致则将标志位加一,否则将标志位置0重新判断,使用这种方法解析数据的代码如下:

使用上述方法是最容易想到的也是最简单的方法了,百度了一下基本上也都是使用类似的方法进行数据解析,但是使用这种方法有如下几个缺点:

1、 大量使用了判断,容易导致出现逻辑混乱。

2、 代码重复率高,抽象程度低。从上述代码可以看到一大堆代码仅仅是判断的数据不同,其他代码都完全一致。

3、 代码可复用性差。写好的代码无法用在其他类似的外设上,如果有多个外设就需要编写多份类似的代码。

4、 可扩展性低。如果外设还有一个数据校验尾需要校验或者数据校验头发生改变,就需要再次写多个判断重新用于校验,无法在原有的代码上进行扩展。

5、 容易出现误判  。

对此,这里提出了一种新的解决方案,可以通用与所有类似的数据解析,原理如下:

使用一个固定容量的队列用来缓存接收到的数据,队列容量等于一帧数据的大小,每来一个数据就将数据往队列里面加,当完整接收到一帧数据时此时队列中的全部数据也就是一帧完整的数据,因此只需要判断队列是否是数据校验头,队列尾是否是数据校验尾就可以得知当前是否已经接收到了一帧完整的数据,然后在将数据从队列中取出即可。原理图如下:

每来一个数据就往队列里面加:

当接收到一帧完整数据时队列头和数据校验头重合:

此时只需要从队列中取出有效数据即可。

如果有数据尾校验,仅仅只需要添加一个校验尾即可,如下图所示:

好,分析结束,开始编码。

首先需要一个队列,为了保证通用性,队列底层使用类似于双向链表的实现(当然也可以使用数组实现),需要封装的结构有队列容量、队列大小、队头节点和队尾节点,需要实现的操作有队列初始化、数据入队、数据出队、清空队列和释放队列,具体代码如下:

其次是解析器,需要封装的结构有解析数据队列、数据校验头、数据校验尾、解析结果以及指向解析结果的指针,需要实现的操作有解析器初始化、添加数据解析、获取解析结果、重置解析器和释放解析器,具体代码如下:

接下来编写测试代码测试一下:

测试结果如下:

从上面可以看出,解析的结果与目标一致。

github地址:

https://github.com/528787067/DataFrameParser

原文地址:https://blog.csdn.net/XR528787067/article/details/52822377

转自公众号:嵌入式大杂烩

版权声明:本文来源网络,版权归原作者所有。版权问题,请联系删除。

—— The End ——

往期推荐

最适合单片机的通信协议,如何设计?

4600万台销量!树莓派炼成之路

好工具,不私藏!介绍一个提高效率的利器

这个c语言技巧,刷新了我对结构体的认知!

C语言还可以这么玩,你绝对想不到!

好项目,不私藏!适用于单片机开发的开源轮子

你点的每个好看,我都认真当成了喜欢

以上是关于高效解析单片机通讯协议,最实用的一个方法的主要内容,如果未能解决你的问题,请参考以下文章

好项目,不私藏!适用于单片机开发的开源轮子

一份开源的单片机串口高效通讯方案

非常实用,推荐一种面向对象思维的单片机程序框架

非常实用,推荐一种面向对象思维的单片机程序框架

单片机固件自更新,可靠实用的一个方法

单片机的底层通讯协议是指啥?