/*处理网络数据的时候往往需要用到JSON数据格式,单片机如果不用cJSON库,处理起来会非常吃力
以下程序与注释讲解了cJSON在STM32F103C8T6上移植并使用案例
使用cJSON只需要在工程里添加cJSON.c与cJSON.h文件即可,方便快捷
*/
//cJSON使用的结构体
typedef struct cJSON //cJSON结构体
{
struct cJSON*next,*prev; /* 遍历数组或对象链的前向或后向链表指针*/
struct cJSON *child; /*数组或对象的孩子节点*/
int type; /* key的类型*/
char *valuestring; /*字符串值*/
int valueint; /* 整数值*/
double valuedouble; /* 浮点数值*/
char *string; /* key的名字*/
} cJSON;
//四个常用的函数
/*
*描述:将一个JSON数据包,按照cJSON结构体整理成数据包,并在开辟一块内存存储cJSON机构提
*参数:JSON格式数据包
*
*返回:成功返回一个指向内存块种的cJSON的指针,失败返回NULL
*/
cJSON *cJSON_Parse(const char *value);
/*
*描述:获取JSON字符串段值
*参数:
*
*返回:成功返回一个指向内存块种的cJSON的指针,失败返回NULL
*/
cJSON *cJSON_GetObjectItem(cJSON *object,const char *string);
/*
*描述:将cJSON数据解析成JSON字符串,并在堆中开辟一块char*的内存空间存储JSON字符串
*参数:
*
*返回:成功返回一个char*指针该指针指向位于堆中JSON字符串,失败返回NULL
*/
char *cJSON_Print(cJSON *item);
/*
*描述:释放位于堆中cJSON结构体内存
*参数:结构体
*
*返回:成功返回一个char*指针该指针指向位于堆中JSON字符串,失败返回NULL
*/
void cJSON_Delete(cJSON *c);
/*
*描述:判断字符串是否可以按照cJSON格式解析
*参数:无
*
*返回:无
*/
void Get_cJSON_Data(void)
{
//定义一个JSON格式字符串 "\"是转义的意思
char * str = "{\"M\":\"say\",\"ID\":\"U10751\",\
\"NAME\":\"\\u672a\\u96e8\\u7ef8\\u7f2a(web)\",\
\"C\":\"up\",\"T\":\"1590990563\"}";
//定义三个字符串变量用于存储cJSON读取的数据
char *string1;
char *string2;
char *string3;
cJSON *cjson; //定义cJSON结构体
cjson = cJSON_Parse(str); //将需要解析的字符串导入到cJSON结构体中,并判断是否可以解析
if(cjson == NULL)
{
printf("json pack into cjson error"); //cJSON数据格式错误
}
else
{
string1 = cJSON_GetObjectItem(cjson,"ID")->valuestring; //获取ID
string2 = cJSON_GetObjectItem(cjson,"C")->valuestring; //获取命令
string3 = cJSON_GetObjectItem(cjson,"T")->valuestring; //获取时间
//打印出数据
printf("ID = %s,C = %s,T = %s\r\n",string1,string2.string3);
}
cJSON_Delete(cjson); //一定记得释放内存。
}
/*
*描述:STM32单片机串口接收中断接收字符串,判断以\r\n结束
*参数:无
*
*返回:无
*/
void USART1_IRQHandler(void)
{
u8 res;//定义串口接收的中间变量
static u8 index = 0;//定义串口接收数据数量
if(UART_GetITStatus(USART1,USART_IT_RXNE) != RESET)
{
res = USART_ReceiveData(USART1); //串口1接收一字节数据
USART_RX_BUF[index] = res;//将数据存放到数组中
if(USART_RX_BUF[index] == '\n') //如果最后一个字符是\n
{
USART_RX_BUF[index] = '\0'
USART_RX_BUF[index-1] = '\0'
index = 0; //清零开始下一轮数据接收
USART_RX_STA = 1; //接收成功标志位置1
return; //接收结束直接返回
}
else
{
USART_RX_STA = 0; //接收成功标志位清零
}
index++;
}
}
/*
*用cJSON处理数据要修改 Heap_Size 大小 一般修改为 0x00000c00
*Heap_Size位置在startup_stm32f10x_md.s 汇编启动文件 第44行
*/
//上述完成后,调试程序,总是会报下面这个错误
//.\Objects\0.96OLED: Error: L6915E: Library reports error:
// __use_no_semihosting was requested, but _ttywrch was referenced
/*
*在百度上查了半天,感觉程序也没有错误,最后发现少了下面这一段
*在sys.h文件中加了下面这一段就好了。
*具体是干什么用的,暂时也不知道,只是知道加上就不报错了。
*欢迎大佬批评指正
*/
_ttywrch(int ch)
{
ch = ch;
}