STM32 之九 HAL 库串口(USART/UART)驱动 BUG 及解决方法
寫在前面
??在工作中,部分產(chǎn)品使用了ST最新的 HAL驅(qū)動(dòng)庫,發(fā)現(xiàn) HAL 庫 BUG 還是挺多的!本文重點(diǎn)針對(duì)在使用HAL庫的 UART / USART 部分時(shí),發(fā)現(xiàn)的以下幾個(gè)個(gè)比較嚴(yán)重Bug。其嚴(yán)重影響正常產(chǎn)品中使用!特此備注說明。
??不過需要說明的是,HAL庫的串口驅(qū)動(dòng)確實(shí)很好使用,絕大部分繁雜的工作都被封裝在了 HAL 庫 函數(shù)之中。但是,這種封裝也存在一定的弊端,因?yàn)樽鳛榍度胧疆a(chǎn)品,我不需要大而全的東西,只求精簡高效!
??在使用 USB部分驅(qū)動(dòng)時(shí),BUG也是不少(目前產(chǎn)品已全部替換使用舊版獨(dú)立版本的USB庫了),后續(xù)文章在說明!HAL庫的USB部分是真的難用!與舊版差多了!
分析解決
針對(duì)這一點(diǎn),網(wǎng)上很多文章說,在獲取DMA收到的數(shù)據(jù)長度時(shí),最好先關(guān)閉DMA,這種情況不適用于循環(huán)模式!
在之前的使用中,我曾認(rèn)為DMA的接收中斷沒有用到就刪除了,后來發(fā)現(xiàn)無法處理錯(cuò)誤情況!
由上可知,想要清除錯(cuò)誤標(biāo)志(FE、PE、NE等)必須先讀取USART_SR register,緊接著讀取USART_DR register。但是中斷處理函數(shù)中沒有該過程!因此,必須在錯(cuò)誤處理函數(shù)中顯示執(zhí)行以上步驟。HAL庫給出了本身清除以上標(biāo)志對(duì)應(yīng)的宏(其實(shí),任意調(diào)用一個(gè)即可!) ,如下:
/** @brief Clear the UART PE pending flag. * @param __HANDLE__ specifies the UART Handle. * This parameter can be UARTx where x: 1, 2, 3, 4, 5, 6, 7 or 8 to select the USART or * UART peripheral. * @retval None */ #define __HAL_UART_CLEAR_PEFLAG(__HANDLE__) \ do{ \__IO uint32_t tmpreg = 0x00U; \tmpreg = (__HANDLE__)->Instance->SR; \tmpreg = (__HANDLE__)->Instance->DR; \UNUSED(tmpreg); \ } while(0U)/** @brief Clear the UART FE pending flag. * @param __HANDLE__ specifies the UART Handle. * This parameter can be UARTx where x: 1, 2, 3, 4, 5, 6, 7 or 8 to select the USART or * UART peripheral. * @retval None */ #define __HAL_UART_CLEAR_FEFLAG(__HANDLE__) __HAL_UART_CLEAR_PEFLAG(__HANDLE__)/** @brief Clear the UART NE pending flag. * @param __HANDLE__ specifies the UART Handle. * This parameter can be UARTx where x: 1, 2, 3, 4, 5, 6, 7 or 8 to select the USART or * UART peripheral. * @retval None */ #define __HAL_UART_CLEAR_NEFLAG(__HANDLE__) __HAL_UART_CLEAR_PEFLAG(__HANDLE__)/** @brief Clear the UART ORE pending flag. * @param __HANDLE__ specifies the UART Handle. * This parameter can be UARTx where x: 1, 2, 3, 4, 5, 6, 7 or 8 to select the USART or * UART peripheral. * @retval None */ #define __HAL_UART_CLEAR_OREFLAG(__HANDLE__) __HAL_UART_CLEAR_PEFLAG(__HANDLE__)/** @brief Clear the UART IDLE pending flag. * @param __HANDLE__ specifies the UART Handle. * This parameter can be UARTx where x: 1, 2, 3, 4, 5, 6, 7 or 8 to select the USART or * UART peripheral. * @retval None */ #define __HAL_UART_CLEAR_IDLEFLAG(__HANDLE__) __HAL_UART_CLEAR_PEFLAG(__HANDLE__)在不同芯片的HAL庫中,其處理稍有不同。例如:在STM32F407的庫中,在函數(shù)HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)中會(huì)有調(diào)用__HAL_UART_CLEAR_OREFLAG(huart);,但是,在STM32F205對(duì)應(yīng)的庫中則沒有調(diào)用。具體如下圖:
STM32F205最新版本(1.7.0)的HAL庫中,對(duì)以上問題(5)已經(jīng)進(jìn)行了修復(fù)!建議更新到最新版本!!!
總結(jié)
以上是生活随笔為你收集整理的STM32 之九 HAL 库串口(USART/UART)驱动 BUG 及解决方法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ARM 之五 发展史及各时期内核(ARM
- 下一篇: 常用算法 之三 详解 SHA1 实现(基