解析不定长hex协议-海陵科LD-2410生命存在感应模组
注意
每个页面仅建议在一个定时器中读取串口缓冲区的数据,在多个定时器中读取串口缓冲区的数据容易照成逻辑混乱。
海陵科LD-2410生命存在感应模组的协议如下所示
program.s中的配置如图所示
1//以下代码只在上电时运行一次,一般用于全局变量定义和上电初始化数据
2//全局变量定义目前仅支持4字节有符号整形(int),不支持其他类型的全局变量声明,如需使用字符串类型可以在页面中使用变量控件来实现
3int sys0=0,sys1=0,sys2=0
4
5int length,totalLength,getFrameHead
6
7//波特率256000
8bauds=256000
9
10//打开主动解析
11recmod=1
12page 0 //上电刷新第0页
界面布局如下图所示
解析定时器(tim为50)中的代码如下图所示
1while(usize>=10&&getFrameHead==0)
2{
3 if(u[0]==0xF4&&u[1]==0xF3&&u[2]==0xF2&&u[3]==0xF1)
4 {
5 //找到帧头,退出循环
6 getFrameHead=1
7 length=0
8 ucopy length,4,2,0
9 totalLength=length+10
10 }else
11 {
12 //如果帧头不对,就一直删除1个字节,直到不满足条件退出循环
13 udelete 1
14 }
15}
16if(getFrameHead==1)
17{
18 if(usize>=totalLength)
19 {
20 if(u[totalLength-4]==0xF8&&u[totalLength-3]==0xF7&&u[totalLength-2]==0xF6&&u[totalLength-1]==0xF5)
21 {
22 if(u[6]==0x02&&u[7]==0xAA&&u[17]==0x55&&u[18]==0x00)
23 {
24 if(u[8]==0x00)
25 {
26 t0.txt="无目标"
27 }else if(u[8]==0x01)
28 {
29 t0.txt="运动目标"
30 ucopy distance.val,9,2,0
31 ucopy energy.val,11,1,0
32 }else if(u[8]==0x02)
33 {
34 t0.txt="静止目标"
35 ucopy distance.val,12,2,0
36 ucopy energy.val,14,1,0
37 }else if(u[8]==0x03)
38 {
39 t0.txt="运动&静止目标"
40 ucopy distance.val,15,2,0
41 }
42 }
43 udelete totalLength
44 }else
45 {
46 udelete 4
47 }
48 getFrameHead=0
49 }
50}
下面对代码进行逐行讲解
program.s中定义的变量
length:获取帧内数据长度
totalLength:通过length计算出一整帧的数据长度
getFrameHead:是否获取到帧头的标志位,1为获取到帧头,0为未获取到帧头
第1行为什么是判断usize>=10
当帧内数据长度为 00 00 时,理论上这是长度是最短的一帧,此时数据变成了
F4 F3 F2 F1 00 00 F8 F7 F6 F5
此时共有10个字节,因此要求进入解析时应该最少大于等于最短的一帧数据
第3-14行是判断帧头是否符合协议中的要求,如果不是,则删除串口缓冲区最前面1字节,直到找到帧头或者usize小于10
如何退出循环:当getFrameHead!=0或者usize<10,不满足while的条件,就会退出循环
第16行,判断是否获取到帧头,获取到了才会进入解析
第18行,判断当前串口缓冲区的数据是否大于完整1帧的长度
第20行,判断帧尾是否符合
第22行,判断02、0A、55、00这四个标志位是否符合
第24行,通过第8位判断目标状态,随后将数据一一提取出来放入对应的控件中
第43行,解析完毕,删除1帧的数据长度
第46行,帧头符合但是其他数据不符合,删除串口缓冲区前4字节(之前已经确认过是帧头),等待进入下一轮判断
第48行,解析完毕或者帧头已经被删除,将获取帧头标志清除
海陵科生命存在感应模组hex协议解析下载
演示工程下载链接: