接收json数据字符串

注意

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

以下面的json为例

1 {
2     "name": "test",
3     "info": {
4         "age": 16,
5         "pass": false
6     }
7 }

json数据中,左括号和右括号是成对出现的,因此我们可以通过这个特性,将第一个左括号当做帧头,最后一个右括号当做帧尾

新建一个空白工程

在工程中新建一个定时器tmDecode,tim设置为50,en设置为1,用于定时解析串口数据

新建数字控件n1,n2,n3,n4,用于显示解析出来的数据

program.s中的配置如图所示

 1//以下代码只在上电时运行一次,一般用于全局变量定义和上电初始化数据
 2//全局变量定义目前仅支持4字节有符号整形(int),不支持其他类型的全局变量声明,如需使用字符串类型可以在页面中使用变量控件来实现
 3int sys0=0,sys1=0,sys2=0
 4int jsonIndex=1
 5//frameLength:每帧数据长度
 6//getFullJson:是否找到完整的json
 7//getFrameFlag:帧头的数量
 8//jsonLength:json数据实际长度
 9int frameLength=2,getFullJson=0,getFrameFlag,jsonLength
10//breakFlag:防止解析卡死在while中
11int breakFlag
12//键和值是否存在
13int isKeyExist,isValueExist
14bauds=115200 //波特率115200
15recmod=1    //打开主动解析
16page 0                       //上电刷新第0页

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

 1breakFlag=0
 2while(usize>=frameLength&&getFullJson==0&&breakFlag==0)
 3{
 4  if(u[0]!=0x7B)
 5  {
 6    //如果帧头不对,就一直删除1个字节,直到不满足条件退出循环
 7    //0x7B是左括号{对应的ascii码值
 8    udelete 1
 9  }else
10  {
11    getFrameFlag=0
12    for(sys0=0;sys0<usize;sys0++)
13    {
14      if(u[sys0]==0x7B)
15      {
16        //找到左括号,帧头数量自增
17        getFrameFlag++
18      }else if(u[sys0]==0x7D)
19      {
20        //找到右括号,帧头数量自减
21        getFrameFlag--
22      }
23      //当getFrameFlag==0时,说明左右括号数量相等,接收到了完整数据
24      if(getFrameFlag==0)
25      {
26        getFullJson=1
27        jsonLength=sys0
28        //让for循环不满足条件退出
29        sys0=usize+1
30      }
31    }
32    //已经解析过整个数据,退出while循环
33    breakFlag=1
34  }
35}
36if(getFullJson==1)
37{
38  //拷贝指定长度到myJson.txt
39  ucopy myJson.txt,0,jsonLength,0
40  //删除指定长度的串口缓冲区
41  udelete jsonLength
42  getFullJson=0
43}

以上代码仅演示如何接收json。代码本身的健壮性存在问题,请勿直接使用

建议参考以下方法发送和接收json字符串,可以降低接收json字符串的难度 传输不定长的字符串

json解析-样例工程下载

演示工程下载链接:

《json解析》演示工程下载