You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

STM32F405 USART3中断中RXNE标志无故自动清除问题求助

STM32F405 USART3中断接收异常:RXNE/IDLE标志自动清除

问题现象

在CubeIDE中调试STM32F405的USART3中断读写功能,发送数据正常,但接收时出现异常:
PC向STM32发送数据后,STM32触发中断,RXNE和IDLE标志位被置位,但在调试器中单步执行(仍处于中断处理函数内)时,执行与清除标志无关的操作后,RXNE和IDLE标志竟被自动清除,导致无法针对RXNE标志执行相关操作。

初始化代码

LL_USART_InitTypeDef USART_InitStruct = {0};
LL_GPIO_InitTypeDef GPIO_InitStruct = {0};

LL_APB1_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART3);
LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOA);

GPIO_InitStruct.Pin = USART1_TX_MB1_Pin|USART1_RX_MB1_Pin;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
GPIO_InitStruct.Alternate = LL_GPIO_AF_7;
LL_GPIO_Init(GPIOA, &GPIO_InitStruct);

USART_InitStruct.BaudRate = 9600;
USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B;
USART_InitStruct.StopBits = LL_USART_STOPBITS_1;
USART_InitStruct.Parity = LL_USART_PARITY_NONE;
USART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX;
USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE;
USART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_16;
LL_USART_Init(USART3, &USART_InitStruct);
LL_USART_ConfigAsyncMode(USART3);
LL_USART_Enable(USART3);

NVIC_SetPriority(USART3_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0, 0));
NVIC_EnableIRQ(USART3_IRQn);

中断处理函数

void USART3_IRQHandler(void)
{
    uint8_t x = 0;
    if (USART3->SR & (USART_SR_NE | USART_SR_FE | USART_SR_PE | USART_SR_ORE))
    {
        LL_USART_ClearFlag_FE(USART3);
        LL_USART_ClearFlag_NE(USART3);
        LL_USART_ClearFlag_ORE(USART3);
    }

    if (LL_USART_IsActiveFlag_RXNE(USART3))
        x = LL_USART_ReceiveData8(USART3);

    if (LL_USART_IsActiveFlag_TC(USART3))
    {
        LL_USART_TransmitData8(USART3, 0x55);
        LL_USART_DisableIT_TC(USART3);
    }

}

问题分析与解决方案

1. 基础代码错误修正

  • 时钟使能错误:USART3挂载在APB1总线,初始化中LL_APB1_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART3);参数错误,应改为:
    LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_USART3);
    
  • GPIO引脚配置错误:当前代码使用了USART1的引脚定义,需根据STM32F405引脚映射,替换为USART3对应的引脚(例如PB10/PB11),并确保复用功能配置正确。

2. 中断使能缺失

当前初始化代码未开启USART3的RXNE和IDLE中断,这会导致标志位触发后无法进入正确的中断处理逻辑,甚至引发异常行为。需添加:

LL_USART_EnableIT_RXNE(USART3);
LL_USART_EnableIT_IDLE(USART3); // 若需要IDLE中断则添加

3. 标志自动清除原因与处理

根据STM32F4参考手册:

  • RXNE标志仅在读取USART_DR寄存器时自动清除;
  • IDLE标志需要先读取USART_SR寄存器,再读取USART_DR寄存器才能清除。

你遇到的单步执行时标志自动清除,可能是调试器自动刷新寄存器视图时,隐含读取了DR寄存器导致的。优化中断处理函数,确保标志清除逻辑符合手册要求:

void USART3_IRQHandler(void)
{
    uint8_t x = 0;
    volatile uint32_t dummy;

    // 处理错误标志
    if (USART3->SR & (USART_SR_NE | USART_SR_FE | USART_SR_PE | USART_SR_ORE))
    {
        LL_USART_ClearFlag_FE(USART3);
        LL_USART_ClearFlag_NE(USART3);
        LL_USART_ClearFlag_ORE(USART3);
        dummy = USART3->DR; // 读取DR清除错误相关状态
    }

    // 处理RXNE中断
    if (LL_USART_IsActiveFlag_RXNE(USART3))
    {
        x = LL_USART_ReceiveData8(USART3);
        // 添加自定义RXNE处理逻辑
    }

    // 处理IDLE中断
    if (LL_USART_IsActiveFlag_IDLE(USART3))
    {
        // 按手册要求清除IDLE标志:先读SR,再读DR
        dummy = USART3->SR;
        dummy = USART3->DR;
        // 添加自定义IDLE处理逻辑
    }

    // 处理发送完成中断
    if (LL_USART_IsActiveFlag_TC(USART3))
    {
        LL_USART_TransmitData8(USART3, 0x55);
        LL_USART_DisableIT_TC(USART3);
    }
}

4. 调试器设置调整

在CubeIDE调试时,关闭寄存器视图的自动刷新功能,手动刷新寄存器,避免调试器读取操作干扰标志位状态。

内容的提问来源于stack exchange,提问作者MatTab

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 22:32:08