接收json数据字符串

注意

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

以下面的json为例

{
    "name": "test",
    "info": {
        "age": 16,
        "pass": false
    }
}

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

新建一个空白工程

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

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

program.s中的配置如图所示

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

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

breakFlag=0
while(usize>=frameLength&&getFullJson==0&&breakFlag==0)
{
  if(u[0]!=0x7B)
  {
    //如果帧头不对,就一直删除1个字节,直到不满足条件退出循环
    //0x7B是左括号{对应的ascii码值
    udelete 1
  }else
  {
    getFrameFlag=0
    for(sys0=0;sys0<usize;sys0++)
    {
      if(u[sys0]==0x7B)
      {
        //找到左括号,帧头数量自增
        getFrameFlag++
      }else if(u[sys0]==0x7D)
      {
        //找到右括号,帧头数量自减
        getFrameFlag--
      }
      //当getFrameFlag==0时,说明左右括号数量相等,接收到了完整数据
      if(getFrameFlag==0)
      {
        getFullJson=1
        jsonLength=sys0
        //让for循环不满足条件退出
        sys0=usize+1
      }
    }
    //已经解析过整个数据,退出while循环
    breakFlag=1
  }
}
if(getFullJson==1)
{
  //拷贝指定长度到myJson.txt
  ucopy myJson.txt,0,jsonLength,0
  //删除指定长度的串口缓冲区
  udelete jsonLength
  getFullJson=0
}

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

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

json解析-样例工程下载

演示工程下载链接:

《json解析》演示工程下载