通常我們在設計串口協議的時候會有幾種規格:
一、包頭+長度+數據+校驗位+包尾
二、數據+\r\n
三、數據
對於第一、第二種處理起來非常容易,直接採用串口接收中斷即可,如果覺得效率不夠高,那麼就讓串口接收中斷+DMA的方式來處理,給CPU減負。
之前也寫過類似的文章:
stm32f429 HAL庫處理串口接收–如何接收帶\r\n的串口數據
對於第三種,也就是不帶包頭、包尾的,只有數據,這種我們之前沒有介紹過,在我看來它的設計有些不太合理,但在數據量不大的情況下,確實也可以這麼做,STM32 HAL提供了串口空閒中斷+DMA的方式來處理,在數據量較大且容易出錯的情況下,建議還是採用自定義協議的方式去處理。
空閒中斷+DMA具體實現思路如下:
1、在初始化的時候即開啓DMA接收
__HAL_UART_ENABLE_IT(&huart5, UART_IT_IDLE);
2、在中斷服務函數中判斷空閒中斷標誌,一旦觸發了空閒中斷標誌,此時表示數據已經接收完成了,這時候要關DMA接收,等到下一次我們需要接收的時候再開啓接收即可。
//停止DMA接收
HAL_UART_DMAStop(&huart5);
//開啓DMA接收
HAL_UART_Receive_DMA(&huart5, (uint8_t*)USART5_RX_BUF, USART_REC_LEN);
處理空閒中斷服務函數:
void UART5_IRQHandler(void)
{
/* USER CODE BEGIN UART5_IRQn 0 */
//開啓uart5空閒中斷接收
if(RESET != __HAL_UART_GET_FLAG(&huart5, UART_FLAG_IDLE))
{
__HAL_UART_CLEAR_IDLEFLAG(&huart5);
HAL_UART_DMAStop(&huart5);
}
}
如上代碼示例,當我們開啓了DMA接收,當觸發了空閒中斷以後,我們就可以將USART5_RX_BUF這裏面的數據取出來,如果要繼續接收,那就再重新開啓DMA接收即可。