STM32 UART发送一段时间后停止响应问题求助
问题:UART发送功能运行一段时间后停止响应
我使用搭载FreeRTOS和STM32 iCUBE LoRaWAN栈的STM32L476RG NUCLEO开发板,通过UART接口与树莓派连接,实现两者间的周期性数据收发。由于接收数据量不固定,采用带DMA和空闲线检测的环形缓冲区实现接收,相关回调函数代码如下:
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size) { if (huart->Instance == USART3) { oldPos = newPos; // Update the last position before copying new data /* If the data in large and it is about to exceed the buffer size, we have to route it to the start of the buffer * This is to maintain the circular buffer * The old data in the main buffer will be overlapped */ if (oldPos+Size > MainBuf_SIZE) // If the current position + new data size is greater than the main buffer { uint16_t datatocopy = MainBuf_SIZE-oldPos; // find out how much space is left in the main buffer memcpy ((uint8_t *)MainBuf+oldPos, RxBuf, datatocopy); // copy data in that remaining space oldPos = 0; // point to the start of the buffer memcpy ((uint8_t *)MainBuf, (uint8_t *)RxBuf+datatocopy, (Size-datatocopy)); // copy the remaining data newPos = ((Size)-datatocopy); // update the position } /* if the current position + new data size is less than the main buffer * we will simply copy the data into the buffer and update the position */ else { memcpy (MainBuf+oldPos, RxBuf, Size); newPos = Size+oldPos; } } print_mem_hex(RxBuf, Size); //HAL_UARTEx_ReceiveToIdle_DMA(&huart3, RxBuf, RxBuf_SIZE); }
但运行一段时间后,UART发送功能会停止响应。我已尝试停止并重启HAL_UART_Receive_IT()的方法,问题仍未解决,恳请提供解决方案建议。
解决方案建议
- 检查并处理UART/DMA错误状态:在回调函数或定时任务中,定期检查
huart3->ErrorCode,排查是否存在帧错误、溢出错误或DMA传输错误。一旦检测到错误,需在HAL_UART_ErrorCallback中执行错误复位逻辑,比如停止DMA、清除错误标志后重新启动接收。 - 恢复DMA接收的重启逻辑:当前代码中注释掉了
HAL_UARTEx_ReceiveToIdle_DMA(&huart3, RxBuf, RxBuf_SIZE);,这会导致处理完一次空闲中断后,DMA接收未重新开启,后续无法触发新的接收事件,甚至可能引发发送链路的同步异常。必须在回调末尾重新启动DMA接收,同时增加错误处理:// 在回调函数末尾添加 if (HAL_UARTEx_ReceiveToIdle_DMA(&huart3, RxBuf, RxBuf_SIZE) != HAL_OK) { HAL_DMA_Abort(&hdma_usart3_rx); HAL_UARTEx_ReceiveToIdle_DMA(&huart3, RxBuf, RxBuf_SIZE); } - 保证环形缓冲区的线程安全:由于使用FreeRTOS,全局变量
oldPos和newPos的读写操作需通过互斥锁(如xSemaphoreHandle)保护,避免中断与任务同时操作导致数据混乱,进而引发后续处理异常影响发送功能。 - 规范UART发送的调用逻辑:如果使用
HAL_UART_Transmit_DMA发送数据,需确保每次发送前DMA处于空闲状态,避免重复启动DMA导致传输错误;如果使用阻塞式发送,需合理设置任务优先级,防止高优先级任务长时间占用CPU导致发送任务无法调度。 - 排查硬件层面干扰:检查UART引脚的电平稳定性,排查是否存在电磁干扰导致通信错误;同时测试树莓派的UART发送功能是否正常,排除对方设备故障的可能性。
内容的提问来源于stack exchange,提问作者busybee
相关产品推荐
相关产品推荐

