解析AT指令

注意

每个页面仅建议在一个定时器中读取串口缓冲区的数据,在多个定时器中读取串口缓冲区的数据容易照成逻辑混乱。

首先我们自定义了几个指令给屏幕赋值

1AT+n0=100\r\n   //给n0赋值100
2AT+n1=50\r\n   //给n1赋值50
3AT+n2=-30\r\n   //给n2赋值-30
4AT+n3333=9999\r\n   //给n3333赋值9999

控件是固定的n0,n1,n2,n3333,但是给他们赋值的参数是不固定的

program.s中的配置如图所示

1//以下代码只在上电时运行一次,一般用于全局变量定义和上电初始化数据
2//全局变量定义目前仅支持4字节有符号整形(int),不支持其他类型的全局变量声明,如需使用字符串类型可以在页面中使用变量控件来实现
3int sys0=0,sys1=0,sys2=0
4int length,totalLength,getFrameHead,getFrameEnd
5bauds=115200 //波特率115200
6recmod=1    //打开主动解析
7page 0                       //上电刷新第0页

界面布局如下图所示

../../../_images/recmod_ascii_1.jpg

注意

注意文本控件的txt_maxl属性,目前我都是设置为30

需要搭配sscom5.13.1使用

../../../_images/recmod_ascii_2.jpg

解析定时器(tim为50)中的代码如下图所示

 1while(usize>=2&&getFrameHead==0)
 2{
 3  if(u[0]==0x41&&u[1]==0x54)
 4  {
 5    //找到帧头"AT",退出循环
 6    getFrameHead=1
 7    getFrameEnd=0
 8  }else
 9  {
10    //如果帧头不对,就一直删除1个字节,直到不满足条件退出循环
11    udelete 1
12  }
13}
14//查找帧尾\r\n
15if(getFrameHead==1&&getFrameEnd==0)
16{
17  for(sys0=2;sys0<=usize;sys0++)
18  {
19    if(u[sys0]==0x0d&&u[sys0+1]==0x0a)
20    {
21      getFrameEnd=1
22      length=sys0
23      totalLength=sys0+2
24      sys0=usize+1
25    }
26  }
27}
28//AT开头,\r\n结尾
29if(getFrameHead==1&&getFrameEnd==1)
30{
31  getFrameHead=0
32  getFrameEnd=0
33  ucopy rxbuffer.txt,0,length,0
34  udelete totalLength
35  click b0,1
36  if(CMD.txt=="n0")
37  {
38    n0.val=param.val
39  }else if(CMD.txt=="n1")
40  {
41    n1.val=param.val
42  }else if(CMD.txt=="n2")
43  {
44    n2.val=param.val
45  }else if(CMD.txt=="n3333")
46  {
47    n3.val=param.val
48  }
49}

下面对代码进行逐行讲解

program.s中定义的变量

length:获取帧内数据长度

totalLength:通过length+结束符\r\n的长度

getFrameHead:是否获取到帧头的标志位,1为获取到帧头,0为未获取到帧头

getFrameEnd:是否获取到帧尾的标志位,1为获取到帧尾,0为未获取到帧尾

第1行为什么是判断usize>=2

代码中取“AT”作为帧头的判断标志,只要大于2字节,就有可能是AT这两个字母,当然也可以取“AT+”作为帧头的判断标志,那么第1行就是是判断usize>=3

第3-12行是判断帧头是否符合协议中的要求,如果不是,则删除串口缓冲区最前面1字节,直到找到帧头或者usize小于2

如何退出循环:当getFrameHead!=0或者usize<2,不满足while的条件,就会退出循环

第2行0x41是“A”对应的ASCII码表的16进制,0x54是“T”对应的ASCII码表的16进制

第17行,从u[2]开始查找帧尾\r\n,\r对应的ASCII码表的16进制是0x0d,\n对应的ASCII码表的16进制是0x0a

第22行,当查找到\r\n时,此时的sys0刚好就是除去\r\n的数据长度,

第23行,sys0+2则是加上\r\n的总的数据的长度

第24行,让sys0>usize,才能退出循环

第29行,已经找到了帧头和帧尾,可以开始解析了

第33行,使用ucopy指令将除了\r\n之外的数据拷贝至rxbuffer.txt进行解析

第34行,删除已经拷贝过的数据

第35行,在b0按钮中对数据进行解析,使用click去触发b0按钮,相当于调用了函数,具体如何解析请查看b0按钮

解析AT指令-样例工程下载

演示工程下载链接:

《AT指令解析》演示工程下载