STM32F4(Weact Black Pill)UART溢出标志(ORE)无法清除问题求助
STM32F4 UART溢出标志(ORE)无法清除的问题排查
问题背景
基于STM32F4(Weact Black Pill开发板)做纯寄存器开发,未使用HAL库。使用UART1时发现FIFO溢出标志(ORE)置位后,按照手册要求的先读USART_SR寄存器,再读USART_DR寄存器的操作无法清除该标志,只能重新初始化整个UART才能恢复,ORE置位前代码运行正常。
核心代码片段
中断处理中的关键代码如下:
volatile U32 regSR = rxB->uartInfo.baseReg->SR; // 读取状态寄存器 volatile U8 b = rxB->uartInfo.baseReg->DR; // 读取接收数据 .... if ((regSR & USART_SR_ORE) == USART_SR_ORE) // 记录溢出错误 rxB->errorFlags |= RX_OVERRUNERROR;
注:rxB->uartInfo.baseReg->SR对应USART1->SR,所有外设寄存器均已声明为volatile类型。
问题分析与解决方向
手册明确ORE位需要通过读SR → 读DR的顺序操作复位,但实际操作中未生效,调整代码结构后问题解决,推测核心原因是编译器优化打乱了操作顺序:
- 尽管变量加了
volatile,但编译器可能对结构体成员的访问顺序进行重排,或对局部变量的存储进行优化,导致实际执行顺序不符合预期。 - 可尝试以下验证和修复方式:
- 切换编译优化等级(如从-O2改回-O0测试),确认是否是优化导致的顺序问题。
- 在读SR和读DR之间添加内存屏障指令(如
__DSB()或__ISB()),强制保证指令执行顺序。 - 将SR和DR的读取操作放在同一个代码块内,避免编译器跨块优化。
- 使用STM32标准头文件中的
__IO宏(本质是volatile)替代自定义的volatile声明,确保编译器正确识别外设寄存器特性。
现状更新
调整代码结构后ORE标志已能正常清除,后续需进一步排查具体是哪种优化行为导致原代码失效。
内容的提问来源于stack exchange,提问作者nmw01223
相关产品推荐
相关产品推荐

