STM32使用串口DMA空闲中断遇到问题解决
1. 触发1-2次空闲中断后便不再触发
在空闲接收中断使用以下处理:
__HAL_UART_CLEAR_IDLEFLAG(huart); // 先清标志
HAL_UART_DMAStop(huart); //停止传输
2. 断点在中断中暂停后不再触发
暂停 MCU 的时候:串口依旧在接收数据(比如 PC 还在发)
DMA 接口没关,仍在工作。当你恢复运行时,串口状态/标志位与 DMA 缓存不一致了,导致:
1. DMA 溢出
2. IDLE 中断错过或没法再次触发
3. UART 错误标志未处理(如 ORE,Overrun Error)
__HAL_UART_CLEAR_OREFLAG(huart); // 清除 Overrun 错误
3. 总代码
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size){
//__HAL_UART_CLEAR_IDLEFLAG(huart); // 先清标志
__HAL_UART_CLEAR_OREFLAG(huart); // 清除 Overrun 错误
__HAL_UART_CLEAR_FEFLAG(huart);
__HAL_UART_CLEAR_NEFLAG(huart);
//HAL_UART_DMAStop(huart);
if(huart == &huart2){ //uwb1
uwbDecodeISR(0,Size);
HAL_UARTEx_ReceiveToIdle_DMA(huart,uwb_buff[0],60);
__HAL_DMA_DISABLE_IT(&hdma_usart2_rx,DMA_IT_HT);
//memset(uwb_buff[0], 0, 60); // 清除接收缓存、非必须
}
}
/* 串口错误回调函数 */
void HAL_UART_ErrorCallback(UART_HandleTypeDef * huart)
{
if(huart->Instance == USART2)
{
HAL_UARTEx_ReceiveToIdle_DMA(huart,uwb_buff[0],60);
__HAL_DMA_DISABLE_IT(&hdma_usart2_rx,DMA_IT_HT);
//memset(uwb_buff[0], 0, 60); // 清除接收缓存
}
}
如上述代码所示,需要实现HAL_UART_ErrorCallback函数,否则在触发该函数后、未重新启动中断将导致此后不触发。