今天翻出之前的USART學習總結, 重溫STM32 的 USART 接收處理,然後根據使用更新一些資料。
先上最終代碼下載下傳:https://download.csdn.net/download/zhouml_msn/12396522
實驗環境:
STM32F429IG(魔女開發闆) + Keil_5.27 + 寄存器操作
實驗效果如下
USART 的兩種資料接收方式
1:RENE - 非空中斷
- 最常用!代碼簡單!
- 但資料處理時稍麻煩,常配合簡單的資料協定,如判斷某字元為接收結束标志。正點原子的代碼中USART接收就是使用這種方式。每個位元組中斷一次。系統實時性要求較高時得注意, 如無人機等.
2:IDLE - 空閑中斷 + DMA
- 最好用!
- DMA接收:無需代碼幹預,DMA自動把接收到的位元組,順序存放到指定數組緩存!
- 空閑中斷:自接收到上個位元組完成起(RXNE=1),超過一個位元組周期時長沒收到新資料,産生硬體中斷(USART的SR第4位IDLE被置1),這時USART_IRQHANDLER()函數被調用,使用者可在這裡識别中斷的類型,并做資料處理。
空閑中斷-使用場景
适用:絕大部分場景都适用。
不适用:接收的位元組資料間隔,大于1位元組周期時長的! 如正點原子的LORA子產品,硬體機制1ms傳送1個位元組,即115200波特率下接收一位元組用90us,但後面900us左右間隔是閑置的,這類機制,不适合使用空閑中斷。
代碼編寫注意坑點
1. IDLE的中斷清理方式.
- USART的非空中斷标志位, 是自動清理的, 你隻要讀出資料, 标志會就自動被清, 不用自己費心.
- 但IDLE的中斷标志位, 必須通過軟體序列清零, 步驟如下:
- u32 temp;
- temp=USART1->SR;
- temp=USART1->DR;
- 這兩句順序還不能錯, 之前沒細心看手冊, 調試差點爆血管. 前人不說, 撞牆也想不出來這前因後果!!
2. DMA 設定
- 使用DMA時, 一般會設定明确的傳輸資料量, 就是長度是已知道的; 而IDLE 空閑中斷 , 最友善的就是接收不定長資料.
- 是以NDTR(傳輸數量)要設得比實際數量要大, 注意機關:你的字長, 如200. 大多少沒關系.
- 中斷處理時, 要重新設定DMA的NDTR. 另外: DMA是在關閉的時候才能修改!!
代碼結構
整個功能分三小部代碼進行編寫,USART的初始化、DMA的初始化、中斷服務函數;
fputc()的重定向就不貼出來了,可下載下傳完整示例代碼。
1)USART初始化
- 聲明緩沖區: u8 RxTemp[255]; // 比接收的資料位元組數大些就成;另外注意避免使用char類型
- GPIO 初始化
- UART 初始化 // 使能發送, 使能IDLE
- 使能UART接收 // 這一步已開始工作
- 使能中斷通道,配置優先級 // 使用了魔女的NVICSet函數,一行代碼搞掂
2) DMA初始化
代碼中的參數都是比較容易了解的,注意打開STM32的資料手冊, 翻查DMA資源表格,确定使用哪個資料流、通道就成。
3)中斷服務函數