一、数据包优缺点
① HEX数据包
优 点:传输直接,解析数据非常简单
缺 点:灵活性不够,载荷数据容易和包头包尾重复
使用场景:比较适合一些模块发送的原始数据,例如;陀螺仪,温湿度传感器等【注】这些模块使 用的是UARST串口通信
② 文本数据包
优 点:数据直观易理解,非常灵活
缺 点:解析效率低
使用场景:适合输入指令进行人机交互的场合,例如蓝牙模块的AT指令,CNC和3D打印机常用的 G代码等
总结:根据使用场景选择具体的数据包格式。
二、数据包分类
① hex数据包:里面数据都是以原始的字节数据本身呈现的:例如0X41,0X42等
可变包长和固定包长,同时包含包头包尾(可以自己设计)
如果不确定包头包尾和载荷数据是否会出现冲突,那么选择固定包长
② 文本数据包:里面每个字节都经过了一层编码和译码,最终呈现的是文本格式:例如 A 、B、 C 、D等
1)呈现形式是字符串,在软件中再对字符串进行操作和判断,就可以实现各种指令控制的功能了(接受模式)
2)由于数据译码成了字符形式,这就会存在大量的字符可以作为包头包尾,可以有效避免载荷和 包头包尾重复的问题,因此,文本数据包不用担心包头包尾和载荷数据重复的情况
串口发送:自主可控, 编程简单,例如发送数组,定义一个数组填充数据,用【SendArray】函数进行发送,同理发送字符串也是一样的
串口接受:可以分为查询方式和中断方式,一般采用中断方式 【编程方式比较复杂】
三、数据包接受流程
- 由于数据包具有前后关联性,包头之后是数据,数据之后是包尾
- 处理含有包头、数据和包尾这3种状态时,需要有不同的处理逻辑, 这就需要在程序中设计一个能记住不同状态的机制,在不同状态执行不同的操作,同时还要进行状态的合理转移,这种程序设计思维叫做【状态机】
状态机编程流程:①先根据项目要求定义状态,画几个圈
②考虑好各个状态在说明情况下会进行转移,如何转移,画好线和转移条件
③最后根据这个图来进行编程
1、HEX数据包接收【固定包长HEX数据包的接收方法】
- 状态机编程流程
- 考虑到固定包长数据包, 有包头、数据 以及包尾。考虑定义三个状态变量来分别表示,依次是S=0、S=1、S=2
单片机刚收到一个数据,S=0,进入中断,判断数据是不是包头【FF】
- 如果是,代表收到包头,置S=1,退出中断,结束(下次进中断根据S=1进行接收数据程序)
- 如果不是,则说明没有收到包头,继续等待包头出现,状态仍然是S=0(下次进中断根据S=0判断包头)
转移到接收数据的状态,收到数据将其存在数组中, 再用一个变量记录收了多少个数据
-
如果没收够4个数据就一直是接收状态
-
如果收够了就置【S=2】(下次进中断就可以进入下一个状态了)
等待包尾,判断数据是不是【FE】
-
如果是【FE】置【S=0】回到最初的状态,开始下一个轮回
-
如果不是【FE】进入重复等待包尾的状态,直到接收到真正的包尾
2、文本数据包接收【可变包长文本数据包的接收方法】
因为是可变包长,在接收数据的时候也要时刻监视是否收到包尾,一但收到包尾,数据接收就结束
考虑到可变包长文本数据包, 有包头、数据 以及包尾【两个】。考虑定义三个状态变量来分别表示,依次是S=0、S=1、S=2
1.因为数据包有两个包尾【\r】【\n】,所以需要第三个状态
2.如果只有一个包尾,在出现包尾【\r】后就可以直接回到初始状态了
最开始S=0,收到一个数据即进中断,判断数据是不是包头【@】
- 如果收到【@】进入接收状态,在这个状态下依次接收数据,同时这个状态还应该兼具【等待包尾】的功能
S=1,收到一个数据判断是不是【\r】
-
如果不是则正常接收
- 如果是【\r】则不接收,同时跳到下一个状态S=2,等待包尾【\n】
【注】接收数据和等待包尾需要在一个状态里同时进行