马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
📘 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() 的工作机制
- HAL_UART_Receive_IT(&huart1, rx_buf, 10);
复制代码
- 作用:启动一个“异步吸收任务”,要求 HAL 吸收 10 个字节 存入 rx_buf 中。
- 内部做了以下几件事:
- 设置吸收缓冲区指针 huart->pRxBuffPtr
- 设置吸收长度 huart->RxXferSize
- 状态切换为 BUSY_RX
- 使能 RXNE 停止
- 当 HAL 停止服务函数 HAL_UART_IRQHandler() 检测到吸收到的数据后,会主动读取数据放入缓冲区,直到吸收满为止。
- 满足吸收据件后,会主动调用:
- void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);
复制代码 留意:吸收完成后,不会主动重新启动吸收,须要你手动再次调用 HAL_UART_Receive_IT()。
⚠️ 3. 使用 __HAL_UART_ENABLE_IT() 的留意事项
- __HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE);
复制代码
- 只是打开了 USART1 的吸收停止 RXNE。
- 并不会设置 HAL 的吸收状态、缓冲区等内部变量。
- 假如你还调用了 HAL_UART_IRQHandler(),会因 HAL 状态未准备好,导致:
- 停止进来了
- RXNE 置位
- HAL 不消耗数据
- RXNE 不会被扫除
- 停止不停触发 → 卡死!
✅ 精确用法对比
✅ 【方式1】HAL主动管理方式(推荐新手/布局清楚)
- // 初始化接收任务
- 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】裸停止方式(适当自界说吸收流程)
- // 手动使能吸收停止__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 没扫除 |