300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > STM32HAL 移植 cJSON开源库 (裸机开发神器)

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

时间:2021-04-12 21:13:01

相关推荐

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

目录

概述

一、使用方法

二、STM32CubeMx配置

三、Examples

四、运行结果

五、总结

概述

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

GitHub:/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文件

/*Copyright (c) - Dave Gamble and cJSON contributorsPermission is hereby granted, free of charge, to any person obtaining a copyof this software and associated documentation files (the "Software"), to dealin the Software without restriction, including without limitation the rightsto use, copy, modify, merge, publish, distribute, sublicense, and/or sellcopies of the Software, and to permit persons to whom the Software isfurnished to do so, subject to the following conditions:The above copyright notice and this permission notice shall be included inall copies or substantial portions of the Software.THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS ORIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THEAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHERLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS INTHE SOFTWARE.*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include "cJSON.h"/* We don't do anything about it */#define exit(a) \if(#a == "1")\;\else\;\/* Used by some code below as an example datatype. */struct record{const char *precision;double lat;double lon;const char *address;const char *city;const char *state;const char *zip;const char *country;};/* Create a bunch of objects as demonstration. */static int print_preallocated(cJSON *root){/* declarations */char *out = NULL;char *buf = NULL;char *buf_fail = NULL;size_t len = 0;size_t len_fail = 0;/* formatted print */out = cJSON_Print(root);/* create buffer to succeed *//* the extra 5 bytes are because of inaccuracies when reserving memory */len = strlen(out) + 5;buf = (char*)malloc(len);if (buf == NULL){printf("Failed to allocate memory.\n");exit(1);}/* create buffer to fail */len_fail = strlen(out);buf_fail = (char*)malloc(len_fail);if (buf_fail == NULL){printf("Failed to allocate memory.\n");exit(1);}/* Print to buffer */if (!cJSON_PrintPreallocated(root, buf, (int)len, 1)) {printf("cJSON_PrintPreallocated failed!\n");if (strcmp(out, buf) != 0) {printf("cJSON_PrintPreallocated not the same as cJSON_Print!\n");printf("cJSON_Print result:\n%s\n", out);printf("cJSON_PrintPreallocated result:\n%s\n", buf);}free(out);free(buf_fail);free(buf);return -1;}/* success */printf("%s\n", buf);/* force it to fail */if (cJSON_PrintPreallocated(root, buf_fail, (int)len_fail, 1)) {printf("cJSON_PrintPreallocated failed to show error with insufficient memory!\n");printf("cJSON_Print result:\n%s\n", out);printf("cJSON_PrintPreallocated result:\n%s\n", buf_fail);free(out);free(buf_fail);free(buf);return -1;}free(out);free(buf_fail);free(buf);return 0;}/* Create a bunch of objects as demonstration. */static void create_objects(void){/* declare a few. */cJSON *root = NULL;cJSON *fmt = NULL;cJSON *img = NULL;cJSON *thm = NULL;cJSON *fld = NULL;int i = 0;/* Our "days of the week" array: */const char *strings[7] ={"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"};/* Our matrix: */int numbers[3][3] ={{0, -1, 0},{1, 0, 0},{0 ,0, 1}};/* Our "gallery" item: */int ids[4] = { 116, 943, 234, 38793 };/* Our array of "records": */struct record fields[2] ={{"zip",37.7668,-1.223959e+2,"","SAN FRANCISCO","CA","94107","US"},{"zip",37.371991,-1.22026e+2,"","SUNNYVALE","CA","94085","US"}};volatile double zero = 0.0;/* Here we construct some JSON standards, from the JSON site. *//* Our "Video" datatype: */root = cJSON_CreateObject();cJSON_AddItemToObject(root, "name", cJSON_CreateString("Jack (\"Bee\") Nimble"));cJSON_AddItemToObject(root, "format", fmt = cJSON_CreateObject());cJSON_AddStringToObject(fmt, "type", "rect");cJSON_AddNumberToObject(fmt, "width", 1920);cJSON_AddNumberToObject(fmt, "height", 1080);cJSON_AddFalseToObject (fmt, "interlace");cJSON_AddNumberToObject(fmt, "frame rate", 24);/* Print to text */if (print_preallocated(root) != 0) {cJSON_Delete(root);exit(EXIT_FAILURE);}cJSON_Delete(root);/* Our "days of the week" array: */root = cJSON_CreateStringArray(strings, 7);if (print_preallocated(root) != 0) {cJSON_Delete(root);exit(EXIT_FAILURE);}cJSON_Delete(root);/* Our matrix: */root = cJSON_CreateArray();for (i = 0; i < 3; i++){cJSON_AddItemToArray(root, cJSON_CreateIntArray(numbers[i], 3));}/* cJSON_ReplaceItemInArray(root, 1, cJSON_CreateString("Replacement")); */if (print_preallocated(root) != 0) {cJSON_Delete(root);exit(EXIT_FAILURE);}cJSON_Delete(root);/* Our "gallery" item: */root = cJSON_CreateObject();cJSON_AddItemToObject(root, "Image", img = cJSON_CreateObject());cJSON_AddNumberToObject(img, "Width", 800);cJSON_AddNumberToObject(img, "Height", 600);cJSON_AddStringToObject(img, "Title", "View from 15th Floor");cJSON_AddItemToObject(img, "Thumbnail", thm = cJSON_CreateObject());cJSON_AddStringToObject(thm, "Url", "http:/*/image/481989943");cJSON_AddNumberToObject(thm, "Height", 125);cJSON_AddStringToObject(thm, "Width", "100");cJSON_AddItemToObject(img, "IDs", cJSON_CreateIntArray(ids, 4));if (print_preallocated(root) != 0) {cJSON_Delete(root);exit(EXIT_FAILURE);}cJSON_Delete(root);/* Our array of "records": */root = cJSON_CreateArray();for (i = 0; i < 2; i++){cJSON_AddItemToArray(root, fld = cJSON_CreateObject());cJSON_AddStringToObject(fld, "precision", fields[i].precision);cJSON_AddNumberToObject(fld, "Latitude", fields[i].lat);cJSON_AddNumberToObject(fld, "Longitude", fields[i].lon);cJSON_AddStringToObject(fld, "Address", fields[i].address);cJSON_AddStringToObject(fld, "City", fields[i].city);cJSON_AddStringToObject(fld, "State", fields[i].state);cJSON_AddStringToObject(fld, "Zip", fields[i].zip);cJSON_AddStringToObject(fld, "Country", fields[i].country);}/* cJSON_ReplaceItemInObject(cJSON_GetArrayItem(root, 1), "City", cJSON_CreateIntArray(ids, 4)); */if (print_preallocated(root) != 0) {cJSON_Delete(root);exit(EXIT_FAILURE);}cJSON_Delete(root);root = cJSON_CreateObject();cJSON_AddNumberToObject(root, "number", 1.0 / zero);if (print_preallocated(root) != 0) {cJSON_Delete(root);exit(EXIT_FAILURE);}cJSON_Delete(root);}int CJSON_CDECL cJSON_main(void){/* print the version */printf("Version: %s\n", cJSON_Version());/* Now some samplecode for building objects concisely: */create_objects();return 0;}

2、main.c文件

/* USER CODE BEGIN Header *//********************************************************************************* @file : main.c* @brief: Main program body******************************************************************************* @attention** <h2><center>&copy; Copyright (c) STMicroelectronics.* All rights reserved.</center></h2>** This software component is licensed by ST under BSD 3-Clause license,* the "License"; You may not use this file except in compliance with the* License. You may obtain a copy of the License at:* /licenses/BSD-3-Clause********************************************************************************//* USER CODE END Header *//* Includes ------------------------------------------------------------------*/#include "main.h"#include "usart.h"#include "gpio.h"/* Private includes ----------------------------------------------------------*//* USER CODE BEGIN Includes */#include "stdio.h"#include "cJSON.h"/* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*//* USER CODE BEGIN PTD *//* USER CODE END PTD *//* Private define ------------------------------------------------------------*//* USER CODE BEGIN PD *//* USER CODE END PD *//* Private macro -------------------------------------------------------------*//* USER CODE BEGIN PM */extern int CJSON_CDECL cJSON_main(void);/* USER CODE END PM *//* Private variables ---------------------------------------------------------*//* USER CODE BEGIN PV *//* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/void SystemClock_Config(void);/* USER CODE BEGIN PFP *//* USER CODE END PFP *//* Private user code ---------------------------------------------------------*//* USER CODE BEGIN 0 *///__use_no_semihosting was requested, but _ttywrch was //void _ttywrch(int ch)//{//ch = ch;//}#ifdef __GNUC__/* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printfset to 'Yes') calls __io_putchar() */#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)#else#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)#endif /* __GNUC__ *//*** @brief Retargets the C library printf function to the USART.* @param None* @retval None*/PUTCHAR_PROTOTYPE{/* Place your implementation of fputc here *//* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);return ch;}int fgetc(FILE * f){uint8_t ch = 0;HAL_UART_Receive(&huart1, (uint8_t *)&ch, 1, 0xffff);return ch;}//PM2.5接口 /api/weather.pm25//使用天气预报接口测试程序 /?app=weather.pm25&weaid=1&appkey=10003&sign=b59bc3ef6191eb9f747dd4e83c99f2a4&format=json//json 格式预览网址 /int cJSON_Parse_Test(void) {const char *line = "{\"success\": \"1\",\\"result\": {\\"weaid\": \"1\",\\"cityno\": \"beijing\",\\"citynm\": \"北京\",\\"cityid\": \"101010100\",\\"aqi\": \"96\",\\"aqi_scope\": \"50-100\",\\"aqi_levid\": 2, \\"aqi_levnm\": \"良\",\\"aqi_remark\": \"可以正常进行室外活动\"\}\}";cJSON *json;//char *out;json = cJSON_Parse( line );//if(json == NULL)printf("json fmt error:%s\r\n.", cJSON_GetErrorPtr());else{cJSON *object = cJSON_GetObjectItem(json, "result");cJSON *item = cJSON_GetObjectItem(object, "citynm");printf("result->citynm: %s\r\n", item->valuestring);item = cJSON_GetObjectItem(object, "cityid");printf("result->cityid: %s\r\n", item->valuestring);item = cJSON_GetObjectItem(object, "aqi_levid");printf("result->aqi_levid: %d\r\n", item->valueint);item = cJSON_GetObjectItem(object, "aqi_remark");printf("result->aqi_remark: %s\r\n", item->valuestring);cJSON_Delete(json);}return 0;}/*生成字符串*/void cJSON_Creat(void){cJSON* cjson_test = NULL;cJSON* cityInfo = NULL;cJSON* cjson_week = NULL;char* str = NULL;/* 创建一个JSON数据对象(链表头结点) */cjson_test = cJSON_CreateObject();/* 添加一条字符串类型的JSON数据(添加一个链表节点) */cJSON_AddStringToObject(cjson_test, "time", "-04-16 12:37:21"); //系统更新时间/* 添加一条整数类型的JSON数据(添加一个链表节点) */cJSON_AddNumberToObject(cjson_test, "date", 0416);//当前天气的当天日期/* 添加一条浮点类型的JSON数据(添加一个链表节点) */cJSON_AddNumberToObject(cjson_test, "pm25", 15.0);//pm2.5/* 添加一条字符串类型的JSON数据(添加一个链表节点) */cJSON_AddStringToObject(cjson_test, "quality", "优"); //空气质量/* 添加一个嵌套的JSON数据(添加一个链表节点) */cityInfo = cJSON_CreateObject();cJSON_AddStringToObject(cityInfo, "country", "China");cJSON_AddStringToObject(cityInfo, "city", "Shenzhen");cJSON_AddNumberToObject(cityInfo, "cityid", 440303);cJSON_AddStringToObject(cityInfo, "updateTime", "12:32");cJSON_AddItemToObject(cjson_test, "cityInfo", cityInfo);/* 添加一个数组类型的JSON数据(添加一个链表节点) */cjson_week = cJSON_CreateArray();cJSON_AddItemToArray(cjson_week, cJSON_CreateString( "星期日" ));cJSON_AddItemToArray(cjson_week, cJSON_CreateString( "星期一" ));cJSON_AddItemToArray(cjson_week, cJSON_CreateString( "星期二" ));cJSON_AddItemToArray(cjson_week, cJSON_CreateString( "星期三" ));cJSON_AddItemToArray(cjson_week, cJSON_CreateString( "星期四" ));cJSON_AddItemToArray(cjson_week, cJSON_CreateString( "星期五" ));cJSON_AddItemToArray(cjson_week, cJSON_CreateString( "星期六" ));cJSON_AddItemToObject(cjson_test, "week", cjson_week);/* 添加一个值为 False 的布尔类型的JSON数据(添加一个链表节点) */cJSON_AddFalseToObject(cjson_test, "message");/* 打印JSON对象(整条链表)的所有数据 */str = cJSON_Print(cjson_test);printf("%s\n", str);}/* USER CODE END 0 *//*** @brief The application entry point.* @retval int*/int main(void){/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_USART1_UART_Init();/* USER CODE BEGIN 2 */cJSON_main();printf("\r\n");cJSON_Parse_Test();printf("\r\n");cJSON_Creat();/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){HAL_Delay(1000);HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */}/*** @brief System Clock Configuration* @retval None*/void SystemClock_Config(void){RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};/** Initializes the RCC Oscillators according to the specified parameters* in the RCC_OscInitTypeDef structure.*/RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState = RCC_HSE_ON;RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;RCC_OscInitStruct.HSIState = RCC_HSI_ON;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){Error_Handler();}/** Initializes the CPU, AHB and APB buses clocks*/RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK){Error_Handler();}}/* USER CODE BEGIN 4 *//* USER CODE END 4 *//*** @brief This function is executed in case of error occurrence.* @retval None*/void Error_Handler(void){/* USER CODE BEGIN Error_Handler_Debug *//* User can add his own implementation to report the HAL error return state */__disable_irq();while (1){}/* USER CODE END Error_Handler_Debug */}#ifdef USE_FULL_ASSERT/*** @brief Reports the name of the source file and the source line number* where the assert_param error has occurred.* @param file: pointer to the source file name* @param line: assert_param error line source number* @retval None*/void assert_failed(uint8_t *file, uint32_t line){/* USER CODE BEGIN 6 *//* User can add his own implementation to report the file name and line number,ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) *//* USER CODE END 6 */}#endif /* USE_FULL_ASSERT *//************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

在线解析JSON格式数据工具

/

/

四、运行结果

参考文章:

1、/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、/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、/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、/qq_42263055/article/details/114852446?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_baidulandingword-9&spm=1001.2101.3001.4242

传送门->代码

五、总结

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

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。