天天看點

STM32開發---USART接收不定長資料 (空閑中斷+DMA)

今天翻出之前的USART學習總結,  重溫STM32 的 USART 接收處理,然後根據使用更新一些資料。 

先上最終代碼下載下傳:https://download.csdn.net/download/zhouml_msn/12396522

實驗環境:

STM32F429IG(魔女開發闆) + Keil_5.27 + 寄存器操作

STM32開發---USART接收不定長資料 (空閑中斷+DMA)

實驗效果如下

STM32開發---USART接收不定長資料 (空閑中斷+DMA)

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初始化

  1. 聲明緩沖區:  u8 RxTemp[255];     // 比接收的資料位元組數大些就成;另外注意避免使用char類型
  2. GPIO 初始化
  3. UART 初始化                                // 使能發送, 使能IDLE
  4. 使能UART接收                             // 這一步已開始工作
  5. 使能中斷通道,配置優先級          // 使用了魔女的NVICSet函數,一行代碼搞掂
STM32開發---USART接收不定長資料 (空閑中斷+DMA)

2) DMA初始化

代碼中的參數都是比較容易了解的,注意打開STM32的資料手冊, 翻查DMA資源表格,确定使用哪個資料流、通道就成。

STM32開發---USART接收不定長資料 (空閑中斷+DMA)

3)中斷服務函數

STM32開發---USART接收不定長資料 (空閑中斷+DMA)

繼續閱讀