首页
学习
活动
专区
圈层
工具
发布

通用代码模板,使用环形队列和自定义协议接收串口数据。

在嵌入式软件开发领域,串口通信或网络通信,对不定长数据进行收发是比较常见的需求之一。

因为直接在串口中断函数里面处理数据,可能会导致阻塞/丢包/数据错乱等问题,而环形队列是解决异步数据缓存的最优方案。

搭配上自定义的数据通信协议,可以精准地解析帧头/帧尾/数据长度/校验位,完美地解决了不定长数据的分包/粘包问题。

本文提供一个可以直接移植的C语言代码模板,讲解一下环形队列+自定义协议的核心原理,设计一个串口数据收发的完整流程,适用于单片机(比如STM32、C51、ESP32)、Linux串口编程、网络Socket等数据接收场景。

01

核心原理

(1)为什么要用环形队列?

因为数据通常是连续和不定长的,中断接收的速度比较快,如果主程序处理数据比较慢,就需要使用先进先出(FIFO)的环形队列进行数据缓冲,并且在中断里面做入队操作,主程序进行出队解析。

(2)为什么要自定义协议?

如果不对数据进行协议封包,就无法判断一帧数据从哪里开始、到哪里结束、是否完整、是否出错。

自定义协议可以标准化数据格式,实现帧定位(帧头+帧尾)、数据长度标识、数据校验(防止传输错误)、精准解析不定长数据。

02

设计自定义通信协议

协议帧数据字段格式如下:

【帧头】【数据长度】【数据内容】【校验位】【帧尾】

字段定义:

协议优势:

采用双帧头+帧尾设计,抗干扰能力强,避免错误解析,长度字段可以明确知道需要接收多少数据,校验位用来保证数据传输的完整性,完美地适配了不定长数据的解析。

03

环形队列的代码实现

环形队列是整个代码模板的核心,支持入队、出队、判空、判满、查询长度等基础操作。

04

串口驱动+环形队列对接

在串口中断里面,将接收到的字节压入队列,不做任何解析处理,保证中断函数的执行时间极短。

串口中断服务函数

05

自定义协议的解析函数

主程序的大循环从环形队列里面读取数据,按照自定义协议进行解析,自动识别完整的数据帧,处理粘包和分包问题。

1、协议解析配置

2、协议解析主函数

06

串口数据发送函数

按照自定义协议对数据进行封装然后发送,确保收发双方的数据格式统一。

07

主程序使用示例

主程序无限循环调用解析函数,对数据进行解析成功后,处理业务逻辑,非阻塞并且不丢包。

08

代码模板的优势

(1)数据接收与处理已经解耦,中断只做入队操作,主程序进行数据解析。

(2)通过协议长度字段,自动适配任意长度的数据,完美支持不定长数据。

(3)采用帧头+帧尾+校验位,抗干扰防粘包,解决串口数据传输问题。

(4)C语言编写的代码非常通用,无平台依赖,方便移植。

(5)资源占用极少,非常适合在MCU等嵌入式环境中使用。

09

总结

总的来说,本文提供了环形队列+自定义协议的代码模板,是串口和网络不定长数据接收的通用解决方案。

环形队列解决了异步数据缓存、丢包、阻塞等问题,自定义协议解决了不定长数据解析、粘包分包、数据校验等问题。

代码结构清晰并且可以直接移植,适配了大多数嵌入式通信场景,可以直接将代码复制到项目中使用,也可以根据业务需求扩展协议功能。

  • 发表于:
  • 原文链接https://page.om.qq.com/page/OUA3fImrap_ewyiLPpTYNQAA0
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。
领券