UART ORE:串口为什么会溢出?
2026/10/3大约 3 分钟
UART ORE:串口为什么会溢出?
UART 的 ORE(Overrun Error,溢出错误) 本质就一句话:
上一字节还没被软件取走,下一字节又到了,把接收数据寄存器顶掉了。
一、ORE 怎么产生?
假设 UART 接收寄存器一次只能保存 1 个字节。
UART收到 A
↓
接收寄存器 = A
↓
CPU还没读取
↓
UART又收到 B
↓
接收寄存器还没空
↓
ORE = 1所以 ORE 的本质是:
接收速度 > 软件读取速度例如波特率很高:
A → B → C → D → E但 CPU/中断一直没及时处理:
A到了 → 没取
B到了 → ORE
C到了 → 继续异常风险二、为什么会 ORE?
最常见的原因不是“UART坏了”,而是:
1. 中断响应太慢
2. ISR 里干了太多事情
3. 长时间关中断
4. 高优先级中断长期占用 CPU
5. DMA/接收程序设计不合理
6. 波特率太高,软件处理不过来例如中断里写:
void USART_IRQHandler(void)
{
printf("recv!\n"); // ❌
complex_function(); // ❌
}很容易导致后续字节来不及读取。
三、ORE 和“数据丢了”是什么关系?
例如:
发送端:
A B C D如果:
A → 软件没及时读
B → 到来时发生 ORE那么你不能再认为接收数据完整。
ORE 本身就是一个警告:接收链路已经出现过处理不及时的问题。
所以协议数据通常要:
检测 ORE
↓
清除 ORE
↓
丢弃/重新同步当前错误帧
↓
继续接收具体怎么恢复,取决于你的协议。
四、怎么处理?
1. 优先保证“尽快取数据”
中断里只做最必要的事:
void USART_IRQHandler(void)
{
uint8_t data = USART_ReadData();
buffer_put(data);
}不要在 ISR 里:
printf
复杂计算
延时
大量协议解析
阻塞等待正确思路:
UART中断
↓
快速取走数据
↓
放入环形缓冲区
↓
退出中断
↓
任务再慢慢解析五、为什么环形缓冲区特别适合 UART?
UART 中断负责:
“快收”任务负责:
“慢处理”结构:
UART
↓
中断
↓
读取数据寄存器
↓
环形缓冲区
↓
任务
↓
协议解析这样就把:
实时接收
和:
业务处理
分开了。
六、HAL 中怎么处理?
在 STM32 HAL 中,通常由:
HAL_UART_IRQHandler()统一处理 UART 中断和错误。
具体芯片系列的 ORE 标志位和清除方式可能不同,但原则都是:
检测 ORE
↓
清除错误
↓
恢复接收因此实际项目中优先使用对应系列 HAL 提供的错误处理机制,不要直接照搬别的 STM32 系列寄存器操作。
七、最重要的一点:ORE 不是“单纯的错误码”
不要把它理解成:
ORE = UART坏了而应该理解成:
ORE
↓
数据来了
↓
软件没及时处理
↓
接收能力跟不上输入速度所以排查 ORE 时,优先查:
中断有没有被长时间屏蔽?
ISR是不是太重?
有没有高优先级中断长期占用?
DMA配置是否正确?
波特率是不是过高?
接收缓冲区是不是太小?最终记忆
UART收到数据
↓
接收寄存器
↓
软件及时读取 → 正常
↓
软件没读取
↓
下一字节到来
↓
OREUART ORE 的本质:接收数据到得太快,而软件取得太慢。
解决 ORE 的核心:让“取数据”足够快,再把耗时处理放到主循环或 RTOS 任务里。

