18.7
在實際項目開發中,由于有些串口不具備FIFO(如SCI1和SCI2)或FIFO的buffer比較小,這可能會在數據處理速度小于數據接收速度的時候,導致數據的丟失。因此我們可以設計一個隊列來避免這一問題。在本實驗中,我們使用環形隊列來實現實驗1的串口收發回顯,將串口接收到的數據暫存在隊列中,待完成一次接收后再將隊列中的數據全部發出去。
隊列是一種特殊的線性表,只允許在隊列頭(head)刪除元素,在隊列尾(tail)添加元素。當隊列添加一個元素,隊列尾向后移動,當隊列刪除一個元素,同樣,刪除一個元素,隊列頭向后移動,如圖19_18。

圖19-18 隊列圖示
由于存儲空間是有限的,如果使用線性隊列,刪除元素后就會空出一段存儲空間,這會造成很大的浪費。因此實際上我們更多使用環形隊列。并不是說這段存儲空間是環形的,而是頭指針和尾指針到達存儲空間末尾后會回到存儲空間起點。因此在邏輯上這是循環的,如圖19_19。

圖19-19 環形隊列
18.7.1
硬件設計
本實驗使用到開發板的串口和LED燈,其原理圖在本章實驗1和前面的點亮LED燈章節有介紹,這里不進行贅述。
18.7.2
軟件設計
18.7.2.1
新建工程
因為本節的UART實驗例程與上一個實驗例程的FSP配置以及UART相關的一些代碼基本一致,因此我們可以直接以前面的“19_UART_Receive_Send”工程為基礎進行修改。
對于e2studio開發環境:拷貝一份我們之前的e2s工程模板“19_UART_Receive_Send”,然后將工程文件夾重命名為“19_UART_Circular_Queue”,最后再將它導入到我們的e2studio工作空間中。
對于Keil開發環境:拷貝一份我們之前的Keil工程模板“19_UART_Receive_Send”,然后將工程文件夾重命名為“19_UART_Circular_Queue”,并進入該文件夾里面雙擊Keil工程文件,打開該工程。
FSP配置完全一致,因此我們省略掉這部分。
18.7.2.2
環形隊列的實現
列表8:代碼清單19-7:環形隊列頭文件內容
左右滑動查看完整內容
#defineDATA_LEN300//隊列緩存大小 typedefstruct { uint16_thead;//頭指針 uint16_ttail;//尾指針 uint8_tdata[DATA_LEN];//隊列數據 }Circular_queue_t; externCircular_queue_tCircular_queue;//環形隊列全局變量 boolQueue_Init(Circular_queue_t*circular_queue);//初始化隊列 boolQueue_isEmpty(Circular_queue_t*circular_queue);//判斷隊列是否為空 boolQueue_isFull(Circular_queue_t*circular_queue);//判斷隊列是否已滿 boolQueue_Wirte(Circular_queue_t*circular_queue,uint8_t*string, uint16_ →t len);//寫數據 boolQueue_Read(Circular_queue_t*circular_queue,uint8_t*string,uint16_t? →len);//讀數據 uint16_tQueue_HadUse(Circular_queue_t *circular_queue);//返回隊列中數據的長度 uint16_tQueue_NoUse(Circular_queue_t*circular_queue);//返回未使用數據的長度
環形隊列相關函數的具體定義可以在例程的circular_queue.c中查看,這里就不贅述了。
18.7.2.3
串口中斷回調函數
debug_uart4_callback串口中斷回調函數的內容修改成如下所示。
列表9:代碼清單19-8:串口中斷回調函數
左右滑動查看完整內容
/*串口中斷回調*/
voiddebug_uart4_callback(uart_callback_args_t* p_args)
{
switch(p_args->event)
{
caseUART_EVENT_RX_CHAR:
{
/*接收到數據后馬上寫入隊列中*/
Queue_Wirte(&Circular_queue,(uint8_t*) &p_args->data,1);
break;
}
caseUART_EVENT_TX_COMPLETE:
{
uart_send_complete_flag=true;
break;
}
default:
break;
}
}
18.7.2.4
hal_entry入口函數
hal_entry入口函數的內容修改成如下所示。
列表10:代碼清單19-9:hal_entry入口函數
左右滑動查看完整內容
voidhal_entry(void)
{
/*TODO:add your own code here */
uint8_tRead_Buffer[DATA_LEN];
uint16_tRead_Length;
LED_Init();
// LED 初始化
Debug_UART4_Init();// SCI4 UART 調試串口初始化
Queue_Init((Circular_queue_t*)&Circular_queue);//環形隊列初始化
printf("這是一個串口環形隊列例程
");
printf("打開串口助手發送數據 5 個及以上的數據,接收窗口會打印所發送的數據
");
while(1)
{
if(Queue_isEmpty(&Circular_queue) ==false)//判斷隊列中的數據不為空
{
Read_Length =Queue_HadUse(&Circular_queue);
if( Read_Length >=5)
// 如果隊列中的數據大于等于 5 個,開始打印
隊列中的所有數據
{
printf("Read_Length=%d: ", Read_Length);
memset(Read_Buffer,0, DATA_LEN);
/* 讀出 Read_Length 個數據 */
Queue_Read(&Circular_queue, Read_Buffer, Read_Length);
printf("%s
", Read_Buffer);
}
}
R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_MILLISECONDS);
}
#ifBSP_TZ_SECURE_BUILD
/* Enter non-secure code */
R_BSP_NonSecureEnter();
#endif
}
18.7.3
下載驗證
保證開發板相關硬件連接正確,用Type-CUSB線連接開發板“USBTOUART”接口跟電腦。本次實驗需要使用到串口調試助手,配置好串口參數并打開串口后,在調試助手的發送區域輸入超過5個的任意字符并點擊發送,即可在接收區看見返回字符,不一定馬上全部返回全部的已發送的字符,可以多發送幾次數據觀察,數據并沒有丟失。
-
led燈
+關注
關注
22文章
1603瀏覽量
111005 -
fifo
+關注
關注
3文章
405瀏覽量
45441 -
串口
+關注
關注
15文章
1604瀏覽量
81785 -
uart
+關注
關注
22文章
1302瀏覽量
106019
原文標題:實驗3:基于環形隊列的UART收發回顯——瑞薩RA系列FSP庫開發實戰指南(49)
文章出處:【微信號:瑞薩嵌入式小百科,微信公眾號:瑞薩嵌入式小百科】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
UART波特率計算及UART收發回顯實驗
環形隊列在串口數據接收中的使用
環形隊列的相關資料分享
深度解析數據結構與算法篇之隊列及環形隊列的實現
【STM32+cubemx】0005 HAL庫開發:uart串口中斷和fifo環形隊列

基于環形隊列的UART收發回顯實驗
評論