最近在寫串口接收功能,在使用以下函式時遇到收發錯位的情況,導致串口通信故障:
HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);
此函式在接受到指定量資料時觸發中斷,呼叫的中斷函式為
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);
但是,如果資料在發送程序中丟失了一個位元組,那接下來收到的所有資料都會錯位,導致串口資訊無法按協議正常決議,甚至出現決議錯誤的情況,網上找到的辦法之一是,在 HAL_UART_Receive_DMA 的基礎上使能串口空閑中斷,拿串口1舉例:
__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);
以上函式的功能是,讓串口1每次接收完資料空閑下來時,觸發stm32_fxxx_it.c 中的void USART1_IRQHandler 函式:
void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
/* USER CODE END USART1_IRQn 0 */
HAL_UART_IRQHandler(&huart1);
/* USER CODE BEGIN USART1_IRQn 1 */
/* USER CODE END USART1_IRQn 1 */
}
在user code區域加入代碼,清空串口快取中已有資料,重新開始接收,就可以了,但是這種方法需要手動改動IDLEFLAG,涉及較多的HAL庫函式,HAL庫中其實有現成的函式可以處理串口丟位元組的情況,此函式在
controllerstech的這篇文章有有提到(全英文),這個函式為:
HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
這個函式的用法在stm32官方論壇中沒有解釋,作者鼓勵了我們自己探索,
在原始碼中查看void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)這個函式可以發現,這個函式,如果接收到指定數量的位元組,則會呼叫
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
如果還沒接收到指定數量的位元組,串口就空閑了,則會呼叫以下函式:
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
在自己的代碼中使用以上兩個函式(會覆寫driver中_weak 開頭的函式)就可以在不手動改動IDLE FLAG的前提下,同時實作定長資料的接收和空閑中斷的處理,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/335295.html
標籤:其他
上一篇:為JY61加入OLED顯示系統
