飞道的博客

STM32HAL 移植 cJSON开源库 (裸机开发神器)

196人阅读  评论(0)

目录

 

概述

一、使用方法

二、STM32CubeMx配置

三、Examples

四、运行结果

五、总结


 

概述


        本篇文章介绍如何使用STM32引用 cJSON开源库,JSON格式在互联网数据交互时常用的一个格式,现嵌入式物联网方向,经常使用到,如:MQTT协议,LwM2M协议等等,只要是把数据上传到后台,方便格式查阅与统一处理,终端设备有必要使用JSON格式来封装数据。

GitHub:https://github.com/DaveGamble/cJSON

硬件:STM32F103CBT6最小系统板
软件:Keil 5.29  + STM32CubeMX6.01

 

一、使用方法

详细步骤请移步到官网介绍,不过也没有关系,按照下面的步骤来也行。

二、STM32CubeMx配置

三、Examples

打开STM32CubeMx生成的keil工程,新建cJSON文件夹,把代码仓库cJSON下载下来的代码,添加cJSON.c、cJSON_Utils.c、test.c 3个文件即可,test.c文件是开源库,编写的json格式字符的测试示例。

在keil添加上图的文件即可。

添加包含头文件路径

添加完后,编译项目。

打开test.c文件,修改以下地方

再次编译

 

 

修改堆栈大小
方式1

方式2

生成代码后,startup_stm32f103xb.s汇编文件就会修改,跟方式1 一个样。

1、test.c文件


  
  1. /*
  2. Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
  3. Permission is hereby granted, free of charge, to any person obtaining a copy
  4. of this software and associated documentation files (the "Software"), to deal
  5. in the Software without restriction, including without limitation the rights
  6. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7. copies of the Software, and to permit persons to whom the Software is
  8. furnished to do so, subject to the following conditions:
  9. The above copyright notice and this permission notice shall be included in
  10. all copies or substantial portions of the Software.
  11. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  12. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  13. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  14. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  15. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  16. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  17. THE SOFTWARE.
  18. */
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include "cJSON.h"
  23. /* We don't do anything about it */
  24. #define exit(a) \
  25. if(#a == "1") \
  26. ; \
  27. else \
  28. ; \
  29. /* Used by some code below as an example datatype. */
  30. struct record
  31. {
  32. const char *precision;
  33. double lat;
  34. double lon;
  35. const char *address;
  36. const char *city;
  37. const char *state;
  38. const char *zip;
  39. const char *country;
  40. };
  41. /* Create a bunch of objects as demonstration. */
  42. static int print_preallocated(cJSON *root)
  43. {
  44. /* declarations */
  45. char *out = NULL;
  46. char *buf = NULL;
  47. char *buf_fail = NULL;
  48. size_t len = 0;
  49. size_t len_fail = 0;
  50. /* formatted print */
  51. out = cJSON_Print(root);
  52. /* create buffer to succeed */
  53. /* the extra 5 bytes are because of inaccuracies when reserving memory */
  54. len = strlen(out) + 5;
  55. buf = ( char*) malloc(len);
  56. if (buf == NULL)
  57. {
  58. printf( "Failed to allocate memory.\n");
  59. exit( 1);
  60. }
  61. /* create buffer to fail */
  62. len_fail = strlen(out);
  63. buf_fail = ( char*) malloc(len_fail);
  64. if (buf_fail == NULL)
  65. {
  66. printf( "Failed to allocate memory.\n");
  67. exit( 1);
  68. }
  69. /* Print to buffer */
  70. if (!cJSON_PrintPreallocated(root, buf, ( int)len, 1)) {
  71. printf( "cJSON_PrintPreallocated failed!\n");
  72. if ( strcmp(out, buf) != 0) {
  73. printf( "cJSON_PrintPreallocated not the same as cJSON_Print!\n");
  74. printf( "cJSON_Print result:\n%s\n", out);
  75. printf( "cJSON_PrintPreallocated result:\n%s\n", buf);
  76. }
  77. free(out);
  78. free(buf_fail);
  79. free(buf);
  80. return -1;
  81. }
  82. /* success */
  83. printf( "%s\n", buf);
  84. /* force it to fail */
  85. if (cJSON_PrintPreallocated(root, buf_fail, ( int)len_fail, 1)) {
  86. printf( "cJSON_PrintPreallocated failed to show error with insufficient memory!\n");
  87. printf( "cJSON_Print result:\n%s\n", out);
  88. printf( "cJSON_PrintPreallocated result:\n%s\n", buf_fail);
  89. free(out);
  90. free(buf_fail);
  91. free(buf);
  92. return -1;
  93. }
  94. free(out);
  95. free(buf_fail);
  96. free(buf);
  97. return 0;
  98. }
  99. /* Create a bunch of objects as demonstration. */
  100. static void create_objects(void)
  101. {
  102. /* declare a few. */
  103. cJSON *root = NULL;
  104. cJSON *fmt = NULL;
  105. cJSON *img = NULL;
  106. cJSON *thm = NULL;
  107. cJSON *fld = NULL;
  108. int i = 0;
  109. /* Our "days of the week" array: */
  110. const char *strings[ 7] =
  111. {
  112. "Sunday",
  113. "Monday",
  114. "Tuesday",
  115. "Wednesday",
  116. "Thursday",
  117. "Friday",
  118. "Saturday"
  119. };
  120. /* Our matrix: */
  121. int numbers[ 3][ 3] =
  122. {
  123. { 0, -1, 0},
  124. { 1, 0, 0},
  125. { 0 , 0, 1}
  126. };
  127. /* Our "gallery" item: */
  128. int ids[ 4] = { 116, 943, 234, 38793 };
  129. /* Our array of "records": */
  130. struct record fields[2] =
  131. {
  132. {
  133. "zip",
  134. 37.7668,
  135. -1.223959e+2,
  136. "",
  137. "SAN FRANCISCO",
  138. "CA",
  139. "94107",
  140. "US"
  141. },
  142. {
  143. "zip",
  144. 37.371991,
  145. -1.22026e+2,
  146. "",
  147. "SUNNYVALE",
  148. "CA",
  149. "94085",
  150. "US"
  151. }
  152. };
  153. volatile double zero = 0.0;
  154. /* Here we construct some JSON standards, from the JSON site. */
  155. /* Our "Video" datatype: */
  156. root = cJSON_CreateObject();
  157. cJSON_AddItemToObject(root, "name", cJSON_CreateString( "Jack (\"Bee\") Nimble"));
  158. cJSON_AddItemToObject(root, "format", fmt = cJSON_CreateObject());
  159. cJSON_AddStringToObject(fmt, "type", "rect");
  160. cJSON_AddNumberToObject(fmt, "width", 1920);
  161. cJSON_AddNumberToObject(fmt, "height", 1080);
  162. cJSON_AddFalseToObject (fmt, "interlace");
  163. cJSON_AddNumberToObject(fmt, "frame rate", 24);
  164. /* Print to text */
  165. if (print_preallocated(root) != 0) {
  166. cJSON_Delete(root);
  167. exit(EXIT_FAILURE);
  168. }
  169. cJSON_Delete(root);
  170. /* Our "days of the week" array: */
  171. root = cJSON_CreateStringArray(strings, 7);
  172. if (print_preallocated(root) != 0) {
  173. cJSON_Delete(root);
  174. exit(EXIT_FAILURE);
  175. }
  176. cJSON_Delete(root);
  177. /* Our matrix: */
  178. root = cJSON_CreateArray();
  179. for (i = 0; i < 3; i++)
  180. {
  181. cJSON_AddItemToArray(root, cJSON_CreateIntArray(numbers[i], 3));
  182. }
  183. /* cJSON_ReplaceItemInArray(root, 1, cJSON_CreateString("Replacement")); */
  184. if (print_preallocated(root) != 0) {
  185. cJSON_Delete(root);
  186. exit(EXIT_FAILURE);
  187. }
  188. cJSON_Delete(root);
  189. /* Our "gallery" item: */
  190. root = cJSON_CreateObject();
  191. cJSON_AddItemToObject(root, "Image", img = cJSON_CreateObject());
  192. cJSON_AddNumberToObject(img, "Width", 800);
  193. cJSON_AddNumberToObject(img, "Height", 600);
  194. cJSON_AddStringToObject(img, "Title", "View from 15th Floor");
  195. cJSON_AddItemToObject(img, "Thumbnail", thm = cJSON_CreateObject());
  196. cJSON_AddStringToObject(thm, "Url", "http:/*www.example.com/image/481989943");
  197. cJSON_AddNumberToObject(thm, "Height", 125);
  198. cJSON_AddStringToObject(thm, "Width", "100");
  199. cJSON_AddItemToObject(img, "IDs", cJSON_CreateIntArray(ids, 4));
  200. if (print_preallocated(root) != 0) {
  201. cJSON_Delete(root);
  202. exit(EXIT_FAILURE);
  203. }
  204. cJSON_Delete(root);
  205. /* Our array of "records": */
  206. root = cJSON_CreateArray();
  207. for (i = 0; i < 2; i++)
  208. {
  209. cJSON_AddItemToArray(root, fld = cJSON_CreateObject());
  210. cJSON_AddStringToObject(fld, "precision", fields[i].precision);
  211. cJSON_AddNumberToObject(fld, "Latitude", fields[i].lat);
  212. cJSON_AddNumberToObject(fld, "Longitude", fields[i].lon);
  213. cJSON_AddStringToObject(fld, "Address", fields[i].address);
  214. cJSON_AddStringToObject(fld, "City", fields[i].city);
  215. cJSON_AddStringToObject(fld, "State", fields[i].state);
  216. cJSON_AddStringToObject(fld, "Zip", fields[i].zip);
  217. cJSON_AddStringToObject(fld, "Country", fields[i].country);
  218. }
  219. /* cJSON_ReplaceItemInObject(cJSON_GetArrayItem(root, 1), "City", cJSON_CreateIntArray(ids, 4)); */
  220. if (print_preallocated(root) != 0) {
  221. cJSON_Delete(root);
  222. exit(EXIT_FAILURE);
  223. }
  224. cJSON_Delete(root);
  225. root = cJSON_CreateObject();
  226. cJSON_AddNumberToObject(root, "number", 1.0 / zero);
  227. if (print_preallocated(root) != 0) {
  228. cJSON_Delete(root);
  229. exit(EXIT_FAILURE);
  230. }
  231. cJSON_Delete(root);
  232. }
  233. int CJSON_CDECL cJSON_main(void)
  234. {
  235. /* print the version */
  236. printf( "Version: %s\n", cJSON_Version());
  237. /* Now some samplecode for building objects concisely: */
  238. create_objects();
  239. return 0;
  240. }

2、main.c文件


  
  1. /* USER CODE BEGIN Header */
  2. /**
  3. ******************************************************************************
  4. * @file : main.c
  5. * @brief : Main program body
  6. ******************************************************************************
  7. * @attention
  8. *
  9. * <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
  10. * All rights reserved.</center></h2>
  11. *
  12. * This software component is licensed by ST under BSD 3-Clause license,
  13. * the "License"; You may not use this file except in compliance with the
  14. * License. You may obtain a copy of the License at:
  15. * opensource.org/licenses/BSD-3-Clause
  16. *
  17. ******************************************************************************
  18. */
  19. /* USER CODE END Header */
  20. /* Includes ------------------------------------------------------------------*/
  21. #include "main.h"
  22. #include "usart.h"
  23. #include "gpio.h"
  24. /* Private includes ----------------------------------------------------------*/
  25. /* USER CODE BEGIN Includes */
  26. #include "stdio.h"
  27. #include "cJSON.h"
  28. /* USER CODE END Includes */
  29. /* Private typedef -----------------------------------------------------------*/
  30. /* USER CODE BEGIN PTD */
  31. /* USER CODE END PTD */
  32. /* Private define ------------------------------------------------------------*/
  33. /* USER CODE BEGIN PD */
  34. /* USER CODE END PD */
  35. /* Private macro -------------------------------------------------------------*/
  36. /* USER CODE BEGIN PM */
  37. extern int CJSON_CDECL cJSON_main(void);
  38. /* USER CODE END PM */
  39. /* Private variables ---------------------------------------------------------*/
  40. /* USER CODE BEGIN PV */
  41. /* USER CODE END PV */
  42. /* Private function prototypes -----------------------------------------------*/
  43. void SystemClock_Config(void);
  44. /* USER CODE BEGIN PFP */
  45. /* USER CODE END PFP */
  46. /* Private user code ---------------------------------------------------------*/
  47. /* USER CODE BEGIN 0 */
  48. //__use_no_semihosting was requested, but _ttywrch was
  49. //void _ttywrch(int ch)
  50. //{
  51. // ch = ch;
  52. //}
  53. #ifdef __GNUC__
  54. /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
  55. set to 'Yes') calls __io_putchar() */
  56. #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
  57. #else
  58. #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
  59. #endif /* __GNUC__ */
  60. /**
  61. * @brief Retargets the C library printf function to the USART.
  62. * @param None
  63. * @retval None
  64. */
  65. PUTCHAR_PROTOTYPE
  66. {
  67. /* Place your implementation of fputc here */
  68. /* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */
  69. HAL_UART_Transmit(&huart1, ( uint8_t *)&ch, 1, 0xFFFF);
  70. return ch;
  71. }
  72. int fgetc(FILE * f)
  73. {
  74. uint8_t ch = 0;
  75. HAL_UART_Receive(&huart1, ( uint8_t *)&ch, 1, 0xffff);
  76. return ch;
  77. }
  78. //PM2.5接口 https://www.nowapi.com/api/weather.pm25
  79. //使用天气预报接口测试程序 http://api.k780.com/?app=weather.pm25&weaid=1&appkey=10003&sign=b59bc3ef6191eb9f747dd4e83c99f2a4&format=json
  80. //json 格式预览网址 https://www.sojson.com/
  81. int cJSON_Parse_Test(void)
  82. {
  83. const char *line = "{ \"success\": \"1\", \
  84. \"result\": { \
  85. \"weaid\": \"1\", \
  86. \"cityno\": \"beijing\", \
  87. \"citynm\": \"北京\", \
  88. \"cityid\": \"101010100\", \
  89. \"aqi\": \"96\", \
  90. \"aqi_scope\": \"50-100\", \
  91. \"aqi_levid\": 2, \
  92. \"aqi_levnm\": \"良\", \
  93. \"aqi_remark\": \"可以正常进行室外活动\" \
  94. } \
  95. }";
  96. cJSON *json;
  97. //char *out;
  98. json = cJSON_Parse( line ); //
  99. if(json == NULL)
  100. printf( "json fmt error:%s\r\n.", cJSON_GetErrorPtr());
  101. else
  102. {
  103. cJSON *object = cJSON_GetObjectItem(json, "result");
  104. cJSON *item = cJSON_GetObjectItem(object, "citynm");
  105. printf( "result->citynm: %s\r\n", item->valuestring);
  106. item = cJSON_GetObjectItem(object, "cityid");
  107. printf( "result->cityid: %s\r\n", item->valuestring);
  108. item = cJSON_GetObjectItem(object, "aqi_levid");
  109. printf( "result->aqi_levid: %d\r\n", item->valueint);
  110. item = cJSON_GetObjectItem(object, "aqi_remark");
  111. printf( "result->aqi_remark: %s\r\n", item->valuestring);
  112. cJSON_Delete(json);
  113. }
  114. return 0;
  115. }
  116. /* 生成字符串 */
  117. void cJSON_Creat(void)
  118. {
  119. cJSON* cjson_test = NULL;
  120. cJSON* cityInfo = NULL;
  121. cJSON* cjson_week = NULL;
  122. char* str = NULL;
  123. /* 创建一个JSON数据对象(链表头结点) */
  124. cjson_test = cJSON_CreateObject();
  125. /* 添加一条字符串类型的JSON数据(添加一个链表节点) */
  126. cJSON_AddStringToObject(cjson_test, "time", "2021-04-16 12:37:21"); //系统更新时间
  127. /* 添加一条整数类型的JSON数据(添加一个链表节点) */
  128. cJSON_AddNumberToObject(cjson_test, "date", 20210416); //当前天气的当天日期
  129. /* 添加一条浮点类型的JSON数据(添加一个链表节点) */
  130. cJSON_AddNumberToObject(cjson_test, "pm25", 15.0); //pm2.5
  131. /* 添加一条字符串类型的JSON数据(添加一个链表节点) */
  132. cJSON_AddStringToObject(cjson_test, "quality", "优"); //空气质量
  133. /* 添加一个嵌套的JSON数据(添加一个链表节点) */
  134. cityInfo = cJSON_CreateObject();
  135. cJSON_AddStringToObject(cityInfo, "country", "China");
  136. cJSON_AddStringToObject(cityInfo, "city", "Shenzhen");
  137. cJSON_AddNumberToObject(cityInfo, "cityid", 440303);
  138. cJSON_AddStringToObject(cityInfo, "updateTime", "12:32");
  139. cJSON_AddItemToObject(cjson_test, "cityInfo", cityInfo);
  140. /* 添加一个数组类型的JSON数据(添加一个链表节点) */
  141. cjson_week = cJSON_CreateArray();
  142. cJSON_AddItemToArray(cjson_week, cJSON_CreateString( "星期日" ));
  143. cJSON_AddItemToArray(cjson_week, cJSON_CreateString( "星期一" ));
  144. cJSON_AddItemToArray(cjson_week, cJSON_CreateString( "星期二" ));
  145. cJSON_AddItemToArray(cjson_week, cJSON_CreateString( "星期三" ));
  146. cJSON_AddItemToArray(cjson_week, cJSON_CreateString( "星期四" ));
  147. cJSON_AddItemToArray(cjson_week, cJSON_CreateString( "星期五" ));
  148. cJSON_AddItemToArray(cjson_week, cJSON_CreateString( "星期六" ));
  149. cJSON_AddItemToObject(cjson_test, "week", cjson_week);
  150. /* 添加一个值为 False 的布尔类型的JSON数据(添加一个链表节点) */
  151. cJSON_AddFalseToObject(cjson_test, "message");
  152. /* 打印JSON对象(整条链表)的所有数据 */
  153. str = cJSON_Print(cjson_test);
  154. printf( "%s\n", str);
  155. }
  156. /* USER CODE END 0 */
  157. /**
  158. * @brief The application entry point.
  159. * @retval int
  160. */
  161. int main(void)
  162. {
  163. /* USER CODE BEGIN 1 */
  164. /* USER CODE END 1 */
  165. /* MCU Configuration--------------------------------------------------------*/
  166. /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  167. HAL_Init();
  168. /* USER CODE BEGIN Init */
  169. /* USER CODE END Init */
  170. /* Configure the system clock */
  171. SystemClock_Config();
  172. /* USER CODE BEGIN SysInit */
  173. /* USER CODE END SysInit */
  174. /* Initialize all configured peripherals */
  175. MX_GPIO_Init();
  176. MX_USART1_UART_Init();
  177. /* USER CODE BEGIN 2 */
  178. cJSON_main();
  179. printf( "\r\n");
  180. cJSON_Parse_Test();
  181. printf( "\r\n");
  182. cJSON_Creat();
  183. /* USER CODE END 2 */
  184. /* Infinite loop */
  185. /* USER CODE BEGIN WHILE */
  186. while ( 1)
  187. {
  188. HAL_Delay( 1000);
  189. HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
  190. /* USER CODE END WHILE */
  191. /* USER CODE BEGIN 3 */
  192. }
  193. /* USER CODE END 3 */
  194. }
  195. /**
  196. * @brief System Clock Configuration
  197. * @retval None
  198. */
  199. void SystemClock_Config(void)
  200. {
  201. RCC_OscInitTypeDef RCC_OscInitStruct = { 0};
  202. RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0};
  203. /** Initializes the RCC Oscillators according to the specified parameters
  204. * in the RCC_OscInitTypeDef structure.
  205. */
  206. RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  207. RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  208. RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  209. RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  210. RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  211. RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  212. RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  213. if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  214. {
  215. Error_Handler();
  216. }
  217. /** Initializes the CPU, AHB and APB buses clocks
  218. */
  219. RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
  220. |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  221. RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  222. RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  223. RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  224. RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  225. if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  226. {
  227. Error_Handler();
  228. }
  229. }
  230. /* USER CODE BEGIN 4 */
  231. /* USER CODE END 4 */
  232. /**
  233. * @brief This function is executed in case of error occurrence.
  234. * @retval None
  235. */
  236. void Error_Handler(void)
  237. {
  238. /* USER CODE BEGIN Error_Handler_Debug */
  239. /* User can add his own implementation to report the HAL error return state */
  240. __disable_irq();
  241. while ( 1)
  242. {
  243. }
  244. /* USER CODE END Error_Handler_Debug */
  245. }
  246. #ifdef USE_FULL_ASSERT
  247. /**
  248. * @brief Reports the name of the source file and the source line number
  249. * where the assert_param error has occurred.
  250. * @param file: pointer to the source file name
  251. * @param line: assert_param error line source number
  252. * @retval None
  253. */
  254. void assert_failed(uint8_t *file, uint32_t line)
  255. {
  256. /* USER CODE BEGIN 6 */
  257. /* User can add his own implementation to report the file name and line number,
  258. ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  259. /* USER CODE END 6 */
  260. }
  261. #endif /* USE_FULL_ASSERT */
  262. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

在线解析JSON格式数据工具

https://www.bejson.com/
https://www.sojson.com/
 

 

四、运行结果

参考文章:

1、https://blog.csdn.net/weixin_45488643/article/details/107148438?utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2~aggregatepage~first_rank_v2~rank_aggregation-9-107148438.pc_agg_rank_aggregation&utm_term=CJSON%E5%BA%93%E7%A7%BB%E6%A4%8D&spm=1000.2123.3001.4430

2、https://blog.csdn.net/penglijiang/article/details/52831080?utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2~aggregatepage~first_rank_v2~rank_aggregation-4-52831080.pc_agg_rank_aggregation&utm_term=cjson+stm32%E7%A7%BB%E6%A4%8D&spm=1000.2123.3001.4430

拓展文章:

1、https://blog.csdn.net/zhengnianli/article/details/101178024?utm_medium=distribute.pc_relevant_download.none-task-blog-2~default~blogcommendfrombaidu~default-2.nonecase&depth_1-utm_source=distribute.pc_relevant_download.none-task-blog-2~default~blogcommendfrombaidu~default-2.nonecas

2、https://blog.csdn.net/qq_42263055/article/details/114852446?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_baidulandingword-9&spm=1001.2101.3001.4242

 

传送门->代码

五、总结

      好了,就介绍到此,有了这个神器,解决JSON格式的数据就变得简单很多了,特别适合物联网终端设备开发引用,上报数据到后台非常方便。

 

 

 


转载:https://blog.csdn.net/qq_36075612/article/details/115754746
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场