You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

STM32同一HAL_UART_RxCpltCallback获取多UART数据及中断异常问题

故障原因排查
  • 核心逻辑错误:回调函数的入参huart是本次触发接收完成中断的串口句柄,你现有代码的判断条件写死了huart2.Instance == USART2,该判断结果永远为真,不管是UART2还是UART3触发的回调,都会进入UART2的处理分支,永远不会执行UART3的分支逻辑。
  • 直接后果:UART3第一次触发中断进入回调后,没有重新调用HAL_UART_Receive_IT()开启下一次接收中断,因此后续UART3有数据到来也不会触发中断。
  • 潜在隐患:需要确认两个串口的接收缓存为各自独立的变量,避免不同串口的数据互相覆盖。
正确实现方案

修改回调函数的判断条件,将入参huart的Instance成员和对应的串口外设基地址比较即可:

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    if(huart->Instance == USART2) // 判断传入句柄对应的外设为UART2
    {
        gsm.RxData[gsm.RxDataCnt] = Uart_Rx_Buffer;
        gsm.RxDataCnt = (1 + gsm.RxDataCnt) % MAX_Buff_Size;
        HAL_UART_Receive_IT(&huart2, &Uart_Rx_Buffer, 1);
    }
    else if(huart->Instance == USART3) // 判断传入句柄对应的外设为UART3
    {
        lidar.RxData[lidar.RxDataCnt] = uart3_RX_Data;
        lidar.RxDataCnt = (1 + lidar.RxDataCnt) % MAX_LIDAR_BUFFER;
        HAL_UART_Receive_IT(&huart3, &uart3_RX_Data, 1);
        if(lidar.RxDataCnt > MAX_COUNT_BUFFER)
        {
            lidar.received = true;
        }
    }
}

额外注意事项

  • 初始化阶段要分别对UART2、UART3调用一次HAL_UART_Receive_IT()开启首次接收中断,回调才会被正常触发。
  • 确保Uart_Rx_Buffer和uart3_RX_Data是两个独立的变量,不要共用同一块内存。
  • 如果有更高优先级的中断长时间占用CPU,可能会导致UART接收溢出,可根据实际需求添加溢出错误回调处理逻辑。

内容的提问来源于stack exchange,提问作者Pankaj Verma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 15:09:05