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

  • 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接收的数据:
    在这里插入图片描述
    由数据可知,初步实现了数据的不定长接收。
参考资料
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值