STM32 串口中断接收方式笔记:HAL_UART_Receive_IT vs __HAL_UART_ENABLE_IT

📘 STM32 串口中断接收方式笔记:HAL_UART_Receive_IT vs __HAL_UART_ENABLE_IT


🧠 1. 两者作用简述

函数/宏 作用 是否配置HAL状态 是否调用Rx回调
HAL_UART_Receive_IT() 启动一次基于中断的串口接收任务 ✅ 是 ✅ 是
__HAL_UART_ENABLE_IT() 手动使能某个串口中断(如RXNE) ❌ 否 ❌ 否(除非配合HAL函数)

🔧 2. HAL_UART_Receive_IT() 的工作机制

c 复制代码
HAL_UART_Receive_IT(&huart1, rx_buf, 10);
  • 作用:启动一个"异步接收任务",要求 HAL 接收 10 个字节 存入 rx_buf 中。

  • 内部做了以下几件事:

    1. 设置接收缓冲区指针 huart->pRxBuffPtr
    2. 设置接收长度 huart->RxXferSize
    3. 状态切换为 BUSY_RX
    4. 使能 RXNE 中断
  • 当 HAL 中断服务函数 HAL_UART_IRQHandler() 检测到接收到的数据后,会自动读取数据放入缓冲区,直到接收满为止。

  • 满足接收条件后,会自动调用:

    c 复制代码
    void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);

注意:接收完成后,不会自动重新启动接收 ,需要你手动再次调用 HAL_UART_Receive_IT()。


⚠️ 3. 使用 __HAL_UART_ENABLE_IT() 的注意事项

c 复制代码
__HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE);
  • 只是打开了 USART1 的接收中断 RXNE。
  • 并不会设置 HAL 的接收状态、缓冲区等内部变量。
  • 如果你还调用了 HAL_UART_IRQHandler(),会因 HAL 状态未准备好,导致:
    • 中断进来了
    • RXNE 置位
    • HAL 不消费数据
    • RXNE 不会被清除
    • 中断一直触发 → 卡死!

✅ 正确用法对比

✅ 【方式1】HAL自动管理方式(推荐新手/结构清晰)
c 复制代码
// 初始化接收任务
HAL_UART_Receive_IT(&huart1, rx_buf, 1);

// 实现接收完成回调
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    if (huart->Instance == USART1) {
        // 处理数据 rx_buf[0]
        HAL_UART_Receive_IT(&huart1, rx_buf, 1);  // 继续接收
    }
}
✅ 【方式2】裸中断方式(适合自定义接收流程)
c 复制代码
// 手动使能接收中断
__HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE);

void USART1_IRQHandler(void)
{
    if (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_RXNE)) {
        uint8_t ch = (uint8_t)(huart1.Instance->RDR);
        // 自定义缓冲区存储、协议解析等
    }
}

🔄 4. 总结对比表

项目 HAL_UART_Receive_IT() __HAL_UART_ENABLE_IT() + 手动处理
接收管理 HAL帮你管理接收缓冲 你自己处理
接收长度 固定长度 可灵活按字节
回调机制 自动调用 RxCpltCallback 你自己写中断函数
中断使能 内部自动配置 你自己配置
出错风险 小 大(忘记清标志位或缓冲区会卡死)
场景推荐 简单数据帧、串口透传 协议解析、环形缓冲、实时性要求高

🧪 5. 常见问题

问题 原因
程序卡在中断里出不来 只使能了 RXNE 中断,没有初始化接收任务,RXNE 一直为 1
接收不到数据 没有调用 HAL_UART_Receive_IT(),或中断未使能
回调函数不触发 没有使用 HAL 接收函数,或 HAL 状态机异常
中断乱跳、多次进中断 收数据没及时读 RDR,或 RXNE 没清除
相关推荐
Zw-awa3 小时前
电机家族:有的电机听“目标”,有的电机听“力气”
stm32
FakeOccupational5 小时前
【电路笔记 信号】DBPSK 波形查找表+脉冲成形(升余弦+根升余弦滤波)
开发语言·笔记
FPGA小徐6 小时前
STM32五路气敏传感器阵列电路详解:从HHC1000分压到AD8606跟随器和ADC采样
stm32·单片机·嵌入式硬件
Horn Still Sounds8 小时前
IMX6ULL裸机|I2C通信协议 + ADC模数转换学习笔记
arm开发·笔记·单片机·嵌入式硬件
新晨单片机设计10 小时前
S011C-基于STM32智能灯光控制系统(光强、声音、人体)【Proteus仿真+Keil程序+原理图】
stm32·嵌入式硬件·proteus·智能灯光控制系统
无敌贵点大王11 小时前
RTThread学习记录13——关于要使用一个外设,RTThread与cubemx到底要怎么配合?
c语言·stm32·学习·rtthread
有范先生11 小时前
这次户外断粮危机后,我更在意主食能不能扛住极端环境了
笔记
喜欢打篮球的普通人12 小时前
MiniMind 学习笔记(十二):Pretrain 实操——从版本梳理到 8GB 显卡上的真实训练
人工智能·笔记·学习
女神下凡12 小时前
芯参谋(26):DDR4_软件设计规范
arm开发·单片机·嵌入式硬件
坤坤子吖14 小时前
算法学习——高精度加减乘除
c++·笔记·学习·算法