当前位置: 首页 > news >正文

九、5 USART串口数据包

数据包作用:把一个个单独的数据给打包起来,将同一批的数据进行打包和分割,方便接收方进行识别,方便我们进行多字节的数据通信。

1、串口收发HEX数据包

(1)数据包的格式是个人规定的,如以FF为包头,FE为包尾,用于控制接收

防止数据与包头包尾重复的处理方法:

1)限制载荷数据的范围:可以在发送的时候,对数据进行限幅,如X、Y、Z三个数据,变化范围都可以是0~100;

2)若无法避免载荷数据和包头包尾重复,就尽量使用固定长度的数据包

3)增加包头包尾的数量,让它尽量呈现出载荷数据出现不了的状态,如使用FF、FE作为包头,FD、FC作为包尾

(2)包头包尾并不是全部都需要的,比如我们可以只要一个包头,把包尾删掉(但载荷和包头重复的可能性更大)

(3)固定包长和可变包长的选择问题

HEX数据包:如果载荷会出现与包头包尾重复的情况,最好选择固定包长。

(4)各种数据转换为字节流问题

这里的数据包都是一个字节一个字节组成的, 如果想发送16位或32位整型数据、float、double,甚至结构体,其实都没有问题,因为它们内部其实都是由一个字节一个字节组成的,只需要一个uint8_t的指针指向它,把它们当做一个字节数组发送就行

2、文本数据包

由于数据译码成了字符形式,就会存在大量的字符可以作为包头包尾,可以有效避免载荷和包头包尾重复的问题。

文本数据包一般以换行为包尾

当接收到载荷数据后,得到的是一个字符串,在软件中再对字符串进行操作和判断,就可以实现各种指令控制的功能了

3、优缺点

(1)HEX数据包优点是传输直接,解析数据非常简单,比较适合一些模块发送原始数据,如使用串口通信的陀螺仪、温湿度传感器。

缺点是灵活性不足、载荷容易与包头包尾重复

(2)文本数据包优点是数据直观易理解、非常灵活,适合一些输入指令进行人机交互的场合,如蓝牙模块常用的AT指令、CNC和3D打印机常用的G代码。

缺点是解析效率低

4、数据包收发流程

对于包头、数据、包尾这3种状态,我们都需要有不同的处理逻辑,所以在程序中需要设计一个能记住不同状态的机制,在不同状态执行不同的操作,同时还要进行状态的合理转移,这种程序设计思维,叫做“状态机”。

状态机使用的基本步骤:先根据项目要求定义状态,画几个圈,然后考虑好各个状态在什么情况下会进行转移,如何转移,画好线和转移条件,最后根据这个图来进行编程。

(1)HEX数据包接收流程

执行流程:

最开始S=0,收到一个数据,进中断,根据S=0,进入第一个状态的程序,判断数据是不是包头FF,如果是FF,则代表收到包头,之后置S=1,退出中断,结束,下次再进中断,根据S=1,就可以进行接收数据的程序了(若第一个状态接收到的不是FF,就证明数据包没有对齐,我们应该等待数据包包头的出现,这是状态仍然是0,下次进中断,就还是判断包头的逻辑,直到出现FF,才能转到下一个状态,之后出现了FF,就可以转移到接收数据的状态了);

这时再接收数据,我们就直接把它存在数组中,另外再用一个变量,记录收了多少个数据,如果没收够4个数据,就一直是接收状态,如果收够了,就置S=2,下次进中断时,就可以进入下一个状态了;

最后一个状态就是等待包头包尾,判断数据是不是FE,若是FE,就置S=0,回到最初的状态,开始下一个轮回(若不是FE,比如数据与包头重复,导致包头位置判断错了,那这个包尾位置就有可能不是FE,这时就可以进入重复等待包尾的状态,直到接收到真正的包尾,这样加入包尾的判断,更能预防因数据和包头重复造成的错误)

(2)文本数据包接收流程

同样也是利用状态机,定义3个状态

第一个状态,等待包头,判断收到的是不是我们规定的@符号,如果收到@,就进入接收状态;

在接收状态下,依次接收数据,同时,这个状态还应该要兼具等待包尾的功能,(因为这是可变包长,我们接收数据的时候,也要时刻监视,是不是收到包尾了,一旦收到包尾了,就结束。这里的逻辑应该是,收到一个数据,判断是不是 \r,如果不是,则正常接收,如果是,则不接收,同时跳到下一个状态,等待包尾 \n如果只有一个包尾,那么在出现包尾之后,就可以直接回到初始状态了,只需要两个状态

http://www.lryc.cn/news/455876.html

相关文章:

  • SQL第12课——联结表
  • CentOS7 虚拟机操作系统安装及相关配置教程
  • 『网络游戏』窗口基类【06】
  • 04_23 种设计模式之《单例模式》
  • 视频加字幕用什么软件最快?12款工具快速添加字幕!
  • C++:string (用法篇)
  • 力扣随机题
  • CSS样式基础样式选择器(案例+代码实现+效果图)
  • Linux系统编程—I/O缓冲区(C语言实现)
  • MySQL多表查询:行子查询
  • .NET CORE程序发布IIS后报错误 500.19
  • Qt 6 相比 Qt 5 的主要提升与更新
  • 【数据结构】介绍
  • 论医疗类系统全国运营推广策略
  • Redis入门第一步:认识Redis与快速安装配置
  • ES postman操作全量修改,局部修改,删除
  • 社区交流礼仪 | 提问的艺术
  • 极客兔兔Gee-Cache Day5
  • 【IPv6】IPv6地址格式及地址分类(组播、单播、任播)整理
  • Linux数据备份
  • 回到原点再出发
  • SimpleFoc以及SVPWM学习补充记录
  • 免费 Oracle 各版本 离线帮助使用和介绍
  • 刷题 二叉树
  • 操作系统 | 学习笔记 | 王道 | 4.1 文件系统基础
  • var let const 之间的区别
  • 【springboot】简易模块化开发项目整合Swagger2
  • 【Linux第五课-进程概念下】环境变量、程序地址空间
  • mysql学习教程,从入门到精通,SQL 临时表(37)
  • 算法闭关修炼百题计划(四)