stm32f407使用官方库解析json数据
这个库使用还是比较简单的,没有什么困难的地方,json作为传输数据使用还是很方便的。
下载库并进行安装
首先去官网下载Keil.Jansson.1.0.0.pack
[[https://keilpack.azureedge.net/pack/Keil.Jansson.1.0.0.pack]]
下载后双击打开,安装到本地的keil5中,打开查看是否安装成功
jansson库优点
- 轻量级:代码量较小,适合资源受限的嵌入式系统(如 STM32)。
- 符合标准:严格遵循 JSON 标准(RFC 8259),支持 UTF-8 编码。
- 易用性:提供简洁的 API,支持 JSON 对象、数组、字符串、数值等数据类型的操作。
- 内存安全:自动管理内存分配和释放(但需注意嵌入式环境下的内存限制)。
- 跨平台:可移植到多种平台,包括 ARM Cortex-M 系列(如 STM32)。
配置jansson库
打开keil5的库管理,在Data Exchange中找到JSON,点击加号打开,找到Jansson,打勾,点击OK
在工程中如果发现下图,即代表配置成功
使用实例1-生成json格式数据
如果需要生成固定格式的json数据,使用snprintf即可,例如生成
{
"id":"a123",
"vaule":23
}
可以直接编写代码
char jsonbox[128];
snprintf(jsonbox,128,"{\"id\":\"%s\",\"value\": \"%d\"}","a123",23);
printf("%s\r\n",jsonbox);
编译后下载程序,观察串口助手输出
也可以将他上传到服务器中进行检验
也是可以被解析出
当然我们可以使用json库进行生成,还是生成同样结构的数据,代码如下
json_t *jsonbox = json_object();
json_object_set_new(jsonbox, "id", json_string("a123"));
json_object_set_new(jsonbox,"vaule",json_integer(23));
char* json_str = json_dumps(jsonbox, JSON_COMPACT); //printf无法直接打印json数据
printf("%s\r\n", json_str);
串口输出和服务器输出如下

那如果创建复杂的多重嵌套的数据格式呢?比如创建如下
{
"id": "a123",
"params": {
"model": {
"value": "deepseek"
},
"age": {
"value": 10
}
}
}
可以进行如下操作,分别创建对象,添加对应的值后,再将各个对象汇总在一个根对象下,代码如下
json_t *jsonbox = json_object();//创建根对象
json_object_set_new(jsonbox, "id", json_string("a123"));
json_t *jsonparams = json_object();//创建params对象
json_object_set_new(jsonparams,"model",json_string("deepseek"));
json_object_set_new(jsonparams,"age",json_integer(10));
json_object_set_new(jsonbox, "params", jsonparams); //将对象添加到其中
char* json_str = json_dumps(jsonbox, JSON_INDENT(0)); //printf无法直接打印json数据
printf("%s\r\n", json_str);
json_decref(jsonbox);
输出如下

介绍一下json转char格式的flag
格式控制类
主要用于调整 JSON 字符串的排版形式。
| 标志 | 作用 | 示例值及效果 |
|---|---|---|
JSON_MAX_INDENT (0x1F) |
缩进空格数的最大值(强制 JSON_INDENT(n) 中的 n 范围不超过31) |
- |
JSON_INDENT(n) |
设置缩进空格数(推荐值为 0-4) | JSON_INDENT(4) → {\n "key": "value"\n} |
JSON_COMPACT (0x20) |
紧凑模式:消除所有非必要空格和换行 | {"id":"a123","value":23} |
字符转义类
控制特殊字符的转义规则,确保 JSON 合法性或兼容性。
| 标志 | 作用 | 示例及说明 |
|---|---|---|
JSON_ENSURE_ASCII (0x40) |
强制 ASCII 转义:非 ASCII 字符转换为 \uXXXX 形式 |
“中文” → "\u4e2d\u6587" |
JSON_ESCAPE_SLASH (0x400) |
转义斜杠 / → \/(默认不转义) |
"path": "a/b" → "path":"a\/b" |
数据类型/编码控制
调整 JSON 元素的编码行为或数据精度。
| 标志 | 作用 | 注意事项 |
|---|---|---|
JSON_ENCODE_ANY (0x200) |
允许编码任意类型(包括未包装的 JSON 对象,慎用可能破坏格式) | 处理非标准类型时需谨慎(可能生成无效 JSON) |
JSON_REAL_PRECISION(n) |
设置浮点数精度(保留 n 位小数,范围 0-31) |
JSON_REAL_PRECISION(3) → 3.142(圆周率保留3位) |
键顺序控制
调整 JSON 对象键(Key)的输出顺序。
| 标志 | 作用 |
|---|---|
JSON_SORT_KEYS (0x80) |
按键名字母升序排列(默认顺序不可预测或按插入顺序) |
JSON_PRESERVE_ORDER (0x100) |
保留键的插入顺序(默认可能不保证顺序,需依据具体 Jansson 版本) |
使用实例2-解析json格式数据
实现了创建json数据,下一步就是解析从服务器等收到的json格式的数据,还是以简单的数据格式为例
{
"id":"a123",
"value":23
}
首先创建char格式的数组,调用son_object_get进行提取,但需要注意的是,提取出的数据需要json_string_value进行转换
const char *json_str = "{\"id\":\"a123\",\"value\":23}";
char id[10];
char value[10];
json_t *jsonbox;
json_error_t error;
jsonbox = json_loads(json_str, 0, &error);
json_t *id_obj = json_object_get(jsonbox, "id");
const char *id_val = json_string_value(id_obj);
snprintf(id, sizeof(id), "%s", id_val);
json_t *value_obj = json_object_get(jsonbox, "value");
int value_1 = json_integer_value(value_obj);
snprintf(value, sizeof(value), "%d", value_1);
printf("id: %s\r\n", id);
printf("value: %s\r\n", value);
输出结果如下:
对于接收服务器的数据,首先需要将接收到的数据复制保存,然后进行读取,在回调函数中加入以下代码,即可实现
static void
mqtt_incoming_data_cb(void *arg, const u8_t *data, u16_t len, u8_t flags)
{
char *jsonbox = (char *)malloc(len + 1);
if (jsonbox == NULL) {
printf("内存分配失败!\n");
return;
}
memcpy(jsonbox, data, len);
jsonbox[len] = '\0';
printf("JSON: %s\n", jsonbox);
char id[10];
char value[10];
json_t *json_val;
json_error_t error;
json_val = json_loads(jsonbox, 0, &error);
json_t *id_obj = json_object_get(json_val, "id");
const char *id_val = json_string_value(id_obj);
snprintf(id, sizeof(id), "%s", id_val);
json_t *value_obj = json_object_get(json_val, "value");
int value_1 = json_integer_value(value_obj);
snprintf(value, sizeof(value), "%d", value_1);
printf("id_out: %s\r\n", id);
printf("value_out: %s\r\n", value);
free(jsonbox);
}
编译通过后下载观察效果
可以看到数据丢失了,因为我们给的数组内存太小了,改大点就OK了
对于嵌套的数据,一样的操作逻辑,比如传入数据为
{
"id": "qaduhu37246",
"value": {
"age":374732
}
}
只需要增加一条代码即可
static void
mqtt_incoming_data_cb(void *arg, const u8_t *data, u16_t len, u8_t flags)
{
char *jsonbox = (char *)malloc(len + 1);
if (jsonbox == NULL) {
printf("内存分配失败!\n");
return;
}
memcpy(jsonbox, data, len);
jsonbox[len] = '\0';
printf("JSON: %s\n", jsonbox);
char id[20];
char age[10];
json_t *json_val;
json_error_t error;
json_val = json_loads(jsonbox, 0, &error);
json_t *id_obj = json_object_get(json_val, "id");
const char *id_val = json_string_value(id_obj);
snprintf(id, sizeof(id), "%s", id_val);
json_t *value_obj = json_object_get(json_val, "value");
json_t *age_obj = json_object_get(value_obj, "age");//新增代码
int value_1 = json_integer_value(age_obj);
snprintf(age, sizeof(age), "%d", value_1);
printf("id_out: %s\r\n", id);
printf("value_out: %s\r\n", age);
free(jsonbox);
}
编译后下载检测,成功
总结
这个库使用还是比较简单的,没有什么困难的地方,json作为传输数据使用还是很方便的。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐


所有评论(0)