消息隊列方式實現串口數據不定長接收 ---- 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接收的數據:
    在這裏插入圖片描述
    由數據可知,初步實現了數據的不定長接收。

參考資料

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章