接收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解析-样例工程下载
演示工程下载链接: