STM32
直播中

caokyo

12年用户 522经验值
私信 关注
[问答]

如何向stm32f103的串口3发送并解析一个简单的json数据呢

何为json?如何去使用json?
如何向STM32f103的串口3发送并解析一个简单的json数据呢?

回帖(1)

陈畅妮

2021-12-13 09:53:16
stm32f103C8T6使用cjson库

本章文章主要是记录一下最近学习的keil解析cjson数据,如有不对的地方请各位前辈指正。做了一个简单的demo,基本功能是使用串口助手,向stm32f103的串口3发送一个简单的json数据,数据包括两个键值对ed0、led1,当led0键值为1时电路板上面LED灯由熄灭变亮(由灭变亮),led1同理
一、何为json?


JSON是一种基于文本,独立于语言的轻量级数据交换格式,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。
JSON的两种表示结构对象、数组。
对象结构:
        以 “{”开始
        以 “}”结束
        中间部分由0或多个以”,”分隔的”key(关键字)/value(值)”对构成,关键字和值之间以”:”分隔

{
    key1:value1,
    key2:value2,
    ...
}
数组结构:
        以”[”开始
        以”]”结束
        中间由0或多个以”,”分隔的值列表组成,
[
    {
        key1:value1,
        key2:value2
    },
    {
         key3:value3,
         key4:value4   
    }
]


二、使用步骤

1.下载cjson文件

2.移植库

1.将cJSON,malloc源文件到工程的根目录下:





2.将cJSON,malloc文件添加至头文件路径、项目文件内:







3.修改cJSON.c
由于这个工程使用正点原子的工程模板,里面定义的有malloc.c、malloc.h,我们需要把cJSON的malloc 和free替换成我们自己的。
在cJSON.c添加头文件:
#include "malloc.h"
将cJSON.c文件46、47行修改为:
static void *(*cJSON_malloc)(size_t sz) = mymalloc;
static void (*cJSON_free)(void *ptr) = myfree;
4.修改malloc.h





3.cjson解析函数


void parse_led(const char *JSON)
{
        cJSON *json,*led0 , *led1;
        printf("解析前的数据:%srn",JSON);
        json = cJSON_Parse(JSON);//解析串口的JSON数据
        if(json==NULL)
        {
                printf("json语法错误:[%s] rn",cJSON_GetErrorPtr());//输出语法错误的位置
        }
        else
        {
                led0 = cJSON_GetObjectItem(json,"led0");
                led1 = cJSON_GetObjectItem(json,"led1");
                printf("led0=%d rn",led0->valueint);
                printf("led1=%d rn",led1->valueint);
                if(led0->valueint == 1)LED0=~LED0;
                if(led1->valueint == 1)LED1=~LED1;
        }
        cJSON_Delete(json); // 释放内存
}


4.串口中断函数

void USART3_IRQHandler(void)                        //串口1中断服务程序
        {
        u8 Res;
#if SYSTEM_SUPPORT_OS                 //如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
        OSIntEnter();   
#endif
                if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾)
                {
                        Res = USART_ReceiveData(USART3);
                        USART_RX_BUF[USART_RX_STA++] = Res;                   
                }               
         if(USART_GetITStatus(USART3, USART_IT_IDLE) != RESET)  //接收中断(接收到的一帧数据)
                {               
                        Res =  USART3->SR; //读SR寄存器
                        Res =  USART3->DR; //读DR寄存器  先读SR再度DR目的是清除IDLE中断标志。       
                        USART_RX_STA=0;        //LED0=!LED0;
                        uart3_flag = 1;                       
                }
//                                parse_led((const char *)USART_RX_BUF);
#if SYSTEM_SUPPORT_OS         //如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
        OSIntExit();                                                                                           
#endif
}


5.主函数


int main()
{
    uart3_init(115200);
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
        delay_init();
        LED_Init();
    while(1)
        {
                if(uart3_flag==1)
                {
                        uart3_flag=0;
                        delay_ms(10);
                        parse_led((const char*)USART_RX_BUF);       
                }
    }
}
三、工程测试

打开串口助手,波特率打到115200发送:
{"led0":1.23,"led1":1}




打开串口,以文本发送数据后,可以看到led灯变化,串口返回:
解析前的数据:
解析前的数据:{"led0":1.23,"led1":1}}
led0=1
led1=1


四.测试工程下载

stm32_test.zip
举报

更多回帖

发帖
×
20
完善资料,
赚取积分