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