cJSON在单片机中的使用

转自:https://mp.weixin.qq.com/s/MxdhndcWy0etK32zWkKN9g
小技巧 | cJSON在单片机中的使用
原创 煜拓老刘 数独机 2023-08-25 09:57 发表于北京
图片

引:

  在使用MQTT传输数据的时候,经常使用到JSON包,来进行数据的交互,这篇文章讲一下该如何使用。

图片

一、JSON和cJSON

JSON:全称 JavaScript Object Notation,轻量级的数据格式。

cJSON:是一个用c语言编写的JSON数据解析器,超级轻便,可以移植,单文件MIT源协议。

cJSON的源码文件只有两个:

cJSON.c
cJSON.h
下载地址可以在github下载,地址如下:

https://github.com/DaveGamble/cJSON
将这两个文件下载之后,添加到项目中,其它.C文件调用的时候,需要包含头文件cJSON.h即可,文件在MDK中的位置如下:

图片

二、cJSON是如何表示JSON数据的

cJSON是用一个结构体来表示一个JSON数据,定义在cJSON.h中,查看如下源码:

图片

/* The cJSON structure: /
typedef struct cJSON
{
/
next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
struct cJSON *next;
struct cJSON prev;
/
An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
struct cJSON *child;

/* The type of the item, as above. */
int type;

/* The item's string, if type==cJSON_String  and type == cJSON_Raw */
char *valuestring;
/* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */
int valueint;
/* The item's number, if type==cJSON_Number */
double valuedouble;

/* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
char *string;

} cJSON;
不是存贮整片的JSON数据,而是按照每条数据进行存储的。使用next指针和prev指针进行链表,存储整片的JSON数据。

三、如何封装完整的JSON数据

   说了这么多,我们实际操作一下,找一块STM32F开发板,测试一下。

图片

   先将串口打通,方便电脑查看log日志。

uart_init(115200);
增加cjson.c文件,已经在main.c中

#include “cJSON.h”
图片

  准备打包如下的JSON包

{
“我的名字”: “老刘”,
“公众号”: “数独机”,
“年龄”: 11,
“性别”: “男”,
“电话”: 186,
“地址”: “一般人不告诉”,
“我是嵌套的cJSON”: {
“号码”: 9527,
“传真”: 5510,
“淘宝店”: “This熏”
},
“我是嵌套的数组”: [{
“我是奇数循环”: 0
}, {
“我是偶数循环”: “12365”
}, {
“我是奇数循环”: 2
}, {
“我是偶数循环”: “12365”
}, {
“我是奇数循环”: 4
}]
}
代码部分,先将几个部分初始化指针

cJSON* main_root = NULL;
cJSON* main_m_root = NULL;
cJSON* main_l_root = NULL;
cJSON* obj=NULL;
char* response_str = NULL;
   创建链表

main_root = cJSON_CreateObject();
豪横的在链表中添加节点

cJSON_AddStringToObject(main_root, “我的名字”, “老刘”);
cJSON_AddStringToObject(main_root, “公众号”, “数独机”);
cJSON_AddNumberToObject(main_root, “年龄”, 11);
cJSON_AddStringToObject(main_root, “性别”, “男”);
cJSON_AddNumberToObject(main_root, “电话”, 186);
cJSON_AddStringToObject(main_root, “地址”, “一般人不告诉”);

main_m_root = cJSON_CreateObject();
cJSON_AddNumberToObject(main_m_root, “号码”, 9527);
cJSON_AddNumberToObject(main_m_root, “传真”, 5510);
cJSON_AddStringToObject(main_m_root, “淘宝店”, “This熏”);
cJSON_AddItemToObject(main_root, “我是嵌套的cJSON”, main_m_root);

main_l_root=cJSON_CreateArray();
cJSON_AddItemToObject(main_root,“我是嵌套的数组”,main_l_root);
for(i=0;i<5;i++)
{
obj=cJSON_CreateObject();
cJSON_AddItemToArray(main_l_root,obj);
if(i%2 == 0) cJSON_AddNumberToObject(obj, “我是奇数循环”, i);
else cJSON_AddStringToObject(obj, “我是偶数循环”, “12365”);
}
我们查看添加的是否正确,可以将链表通过串口打印出来。

response_str = cJSON_Print(main_root);
printf(“%s\n”,response_str);
效果如下:

图片

四、解包

  解包的函数只有一个:

CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value);
还是用例子进行讲解:

 将串口的数据完全接收到一个大的缓冲区里面,当然这个数据也可以来自wifi或者网络。      

if(GET_STOP_flag)
{
for(i=0;i<(cJSON_pack_StopP-cJSON_pack_FistP)+1;i++)
{
MessageTmp[i] =WIFI_RC_buf[cJSON_pack_FistP-1+i];
}
}
GET_STOP_flag //为停止接收标志;
cJSON_pack_StopP //停止指针位置
cJSON_pack_FistP //开始指针位置
MessageTmp //临时的数组
只需要对临时的数组进行操作即可。开辟内存空间,将数组转换为字符串。

MessageStrTmp = (char *)cJSON_malloc(sizeof(char) * (sizeof(MessageTmp) + 1));
strncpy(MessageStrTmp, MessageTmp, sizeof(MessageTmp));
使用解包函数

//接收解包过程
Thisxun_root = cJSON_Parse(MessageStrTmp);
Thisxun_root_type = cJSON_GetObjectItem(hiss_root,“type”)->valuestring;
if(strcmp(Thisxun_root_type,TYPE_USER_INFO_SYNC)==0)
{
Thisxun_insDetail = cJSON_GetObjectItem(Thisxun_root,“insDetail”);
userID = cJSON_GetObjectItem(Thisxun_insDetail,“userId”)->valuestring;
password = cJSON_GetObjectItem(Thisxun_insDetail,“password”)->valuestring;
}
结:

  每次封包和解包结束之后,都要及时释放内存:

cJSON_Delete(Thisxun_root);
cJSON_free(MessageStrTmp);
对于单片机而言,需要修改Heap_Size,不知道如何修改的,可以联系我。

   认为文章有帮助,帮忙点一下“在看”和“点赞”。

延续阅读

  1. 玩转开发板 | ESP8266及ESP32固件生成及烧录方法

  2. 小技巧 | JDY-34蓝牙SPP模块烧录工艺

  3. 小技巧 | J-link如何烧录芯片

  4. 小技巧 | ST-LINK/V2如何在keil下仿真烧录(附驱动程序)

  5. 玩转开发板 | nRF52832开发板之环境搭建及烧录等

  6. 小技巧 | 带你了解H5、CSS3

  7. 小技巧 | STM32对文件系统FATFS(SDIO接口SD卡)的操作

  8. 淘宝店铺:https://thisxun.taobao.com


喜欢此内容的人还喜欢
专用芯片IC | 串口转网口芯片CH9121
数独机
不喜欢

小技巧 | FreeRTOS最简源码在STM32F1上应用
数独机
不喜欢

微信扫一扫
关注该公众号

人划线

你可能感兴趣的:(单片机,嵌入式硬件)