【STM32】串口中断收发
串口中断提高了系统效率,减少了轮询等待时间;使用 HAL 库开发时要充分利用回调函数机制,实现收发逻辑与业务逻辑的解耦;注意在发送最后一个字节后手动关闭中断,避免中断空转。📌 建议结合调试工具(如串口调试助手或逻辑分析仪)观察串口行为,加深理解。
·
STM32 串口
本笔记主要总结 STM32 使用串口中断方式进行数据发送和接收的机制与代码实现,使用 HAL 库进行举例,适用于初学者理解串口中断的原理与用法。
一、串口中断发送流程
当使用串口中断方式发送数据时,整体流程如下:
- CPU 将一个待发送字节写入
USARTx->TDR(发送数据寄存器)。 - 然后 CPU 立即返回执行其他任务。
- 此时硬件会自动将
TDR中的数据移入发送移位寄存器。 - 当
TDR为空时,会触发一次TXE(Transmit Data Register Empty)中断。 - CPU 响应中断,在中断处理函数中再次将下一个字节写入
TDR。 - 重复上述流程,直到数据全部发送。
- 最后一个字节写入后会再次触发
TXE,必须手动关闭TXEIE避免空中断持续触发。
🔧 提示:发送是否真正完成,可以查看
TC(Transmission Complete)标志。
✅ 示例代码:中断方式发送数据
uint8_t txData[] = "Hello, UART!";
HAL_UART_Transmit_IT(&huart1, txData, sizeof(txData)-1);
HAL库会自动开启 TXEIE,当发送完成后会自动调用回调函数:
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) {
if (huart->Instance == USART1) {
// 发送完成后的处理逻辑
}
}
二、串口中断接收流程
- 当串口接收移位寄存器接收到完整的一帧数据后,会将数据转移至
USARTx->RDR(接收数据寄存器)。 - 此时触发
RXNE(Receive Data Register Not Empty)中断。 - CPU 被中断叫回,并读取
RDR中的数据存入变量中(👉 这一步很关键)。 - CPU 随后继续处理其他任务。
✅ 示例代码:中断方式接收数据
uint8_t rxBuffer[10];
HAL_UART_Receive_IT(&huart1, rxBuffer, sizeof(rxBuffer));
当接收到设定数量的数据后,会调用回调函数:
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
if (huart->Instance == USART1) {
// 处理接收到的数据 rxBuffer
}
}
三、中断机制说明与回调函数
- STM32 的串口中断向量只有一个(例如
USART1_IRQHandler()),但可以由多个事件触发(如 TXE、RXNE、OE、FE 等)。 - HAL库封装了中断处理函数
HAL_UART_IRQHandler(),并提供了**弱定义(__weak)**的回调函数接口,供用户实现具体逻辑。
🔁 常用回调函数原型
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart);
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart);
🧠 回调函数使用说明
- 若用户需要自定义处理逻辑,需重写上述函数。
- 若不重写,则默认的弱定义函数什么都不做。
四、底层流程图(发送流程举例)

五、关键中断标志说明
| 中断标志 | 含义 | 触发条件 |
|---|---|---|
| TXE | 发送数据寄存器空 | TDR 为空,表示可写入新数据 |
| RXNE | 接收数据寄存器非空 | 接收到数据到 RDR |
| TC | 发送完成标志(非中断) | 所有数据已发送并移出移位寄存器 |
⚠ 使用中断方式必须手动控制
TXEIE和RXNEIE,否则可能导致空中断频繁触发。
六、总结
- 串口中断提高了系统效率,减少了轮询等待时间;
- 使用 HAL 库开发时要充分利用回调函数机制,实现收发逻辑与业务逻辑的解耦;
- 注意在发送最后一个字节后手动关闭中断,避免中断空转。
❤️ 你的点赞与评论是我持续更新的最大动力!
更多推荐



所有评论(0)