消息队列方式实现串口数据不定长接收 ---- RT-threadSTM32

Peggy ·
更新时间:2024-09-21
· 627 次阅读

Life moves pretty fast. If you don’t stop and look around once in a while, you could miss it.
人生匆匆,若不偶尔停下来看看周围,便会错过许多风景。
一、串口数据不定长接收的实现

通常在裸机中,我们使用一个定时器来辅助串口实现串口数据不定长接收,也就是当串口接收数据时,定时器一直处于定时值(比如100ms),接收不断的把数据放入缓冲区(通常可使用数组),当串口空闲时,定时器开始计时,当计时时间到,读取缓冲区的数据即可,这样就实现了数据的不定长接收。

而使用RTOS,可以使用消息队列来作为缓冲区,串口每次就收到数据就放入消息队列中,然后别的对象(诸如线程),就可以读取消息队列里的数据,从而实现串口数据的不定长接收。

二、具体实现 这里使用串口2接收电脑发送的数据,然后将数据放入定义的消息队列。 同时建立一个线程,当消息队列有数据时,通过串口1发送消息队列的数据到电脑,已验证是否实现。 /* 消息队列控制块指针 */ static rt_mq_t uart2_mq = RT_NULL; /* 打印存储在消息队列中的uart2发来的数据 */ static void uart2_mq_tid_entry(void *parameter) { rt_err_t uwRet = RT_EOK; rt_uint8_t rx; while(1) { uwRet = rt_mq_recv(uart2_mq, &rx, sizeof(rx), RT_WAITING_FOREVER ); if(RT_EOK == uwRet) rt_kprintf("%c",rx); } } static rt_uint8_t RxBuffer; // 串口接收的数据 static rt_thread_t uart2_mq_tid = RT_NULL; int uart2_mq_rev_init(void) { uart2_mq = rt_mq_create("uart2_mq", //消息队列名字 5, //消息的最大长度, bytes 20, //消息队列的最大容量(个数) RT_IPC_FLAG_FIFO //队列模式 FIFO ); if(uart2_mq != RT_NULL) rt_kprintf("消息队列uart2_mq创建成功\n\n"); /* 创建电机线程*/ uart2_mq_tid = rt_thread_create("uart2_mq_tid", // 线程名字 uart2_mq_tid_entry, // 线程入口函数 RT_NULL, // 线程入口参数 512, // 堆栈大小, 5, // 线程优先级 5); // 时间片长度 /* 如果获得线程控制块,启动这个线程 */ if (uart2_mq_tid != RT_NULL) rt_thread_startup(uart2_mq_tid); return 0; } INIT_DEVICE_EXPORT(uart2_mq_rev_init); // 自动初始化 // 串口接收回调函数 // 注意初始化串口后,也要HAL_UART_Receive_IT(&huart2,&RxBuffer,1);才能开始接收数据 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if(huart->Instance == USART2) { rt_mq_send (uart2_mq, &RxBuffer, sizeof(RxBuffer)); HAL_UART_Receive_IT(&huart2,&RxBuffer,1); // 每次接收完后,必须使用这一句,且在别处容易卡死, // 否则下次无法接收中断 } } 串口2发送的数据:
在这里插入图片描述 串口1接收的数据:
在这里插入图片描述
由数据可知,初步实现了数据的不定长接收。 参考资料 RT-thread 官方文档: 消息队列 STM32CubeMX系列教程5:串行通信(USART)
作者:GlYoung



rt-thread stm32 队列 数据 串口 消息队列

需要 登录 后方可回复, 如果你还没有账号请 注册新账号