[STM32]HAL庫實現DMA+串口idle接收


說來慚愧,玩了一年多的單片機,但是卻一直沒有一個非常好的串口接收策略,之前同學推薦了idle閑時中斷接收,當時也是因為時間原因沒有自己去嘗試,寒假准備完善自己的基礎代碼庫的時候才想起這回事。其實發的這篇文章並沒有什么技術含量,只是因為我的實現方案相較於網上的都比較簡單,和HAL庫結合比較緊密。同時也感嘆一下HAL庫和CUBEMX的組合實在是方便。

介紹一下串口的Idle中斷,參考手冊是這么說的:

When an idle frame is detected, there is the same procedure as a data received character plus an interrupt if the IDLEIE bit is set.

意思是,如果IDLEIE被設置后,那么當接收數據后的空閑幀被檢測到之后才會觸發一個中斷

關於網上也有不少配置DMA+串口idle的教程,我看了不少,感覺都挺麻煩,要自己配置不少東西。不過出於習慣,我經常直接去HAL庫的.h文件里翻函數寫,於是我發現了下面這套函數:
image
這不就是HAL庫封裝的關於閑時中斷的三個接收函數嗎,而且還把阻塞中斷DMA三種接收方式都封裝了。

這三個函數網上找了找幾乎就沒找到資料,不過好在HAL庫的注釋夠全,光看注釋也看的通。
那么我們核心的函數就是這個了:
HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
下面是它的注釋

/**
  * @brief Receive an amount of data in DMA mode till either the expected number of data is received or an IDLE event occurs.
  * @note   Reception is initiated by this function call. Further progress of reception is achieved thanks
  *         to DMA services, transferring automatically received data elements in user reception buffer and
  *         calling registered callbacks at half/end of reception. UART IDLE events are also used to consider
  *         reception phase as ended. In all cases, callback execution will indicate number of received data elements.
  * @note   When the UART parity is enabled (PCE = 1), the received data contain
  *         the parity bit (MSB position).
  * @note   When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M = 01),
  *         the received data is handled as a set of uint16_t. In this case, Size must indicate the number
  *         of uint16_t available through pData.
  * @param huart UART handle.
  * @param pData Pointer to data buffer (uint8_t or uint16_t data elements).
  * @param Size  Amount of data elements (uint8_t or uint16_t) to be received.
  * @retval HAL status
  */

從注釋也是可以看出來他會通過DMA接收數據,超出我們指定的長度或者發生了串口閑時中斷,可以說是一步到位了。
我們要做的只是調用這個函數,然后寫個接收事件回調函數即可。
這個事件回調函數也是HAL庫預先幫我們做好的weak函數,要用的時候自己找個地方定義即可。
下面是函數調用棧,可以看到HAL庫寫的還是很復雜的
image

配置

挺簡單的,自己搗鼓去,我不想詳細寫。
主要就幾點:

  • CUBEMX里面配置好串口和DMA,然后記得開啟串口的中斷
  • 調用函數HAL_UARTEx_ReceiveToIdle_DMA
  • 在回調函數HAL_UARTEx_RxEventCallback中記錄下此次接收到的數據長度
  • 要想再接收數據就必須再次調用接收函數


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM