中断里不读DR,RXNE不清,系统卡死

📅 2026/7/31 4:48:49 👁️ 阅读次数 📝 编程学习
中断里不读DR,RXNE不清,系统卡死

短文标题:中断里不读DR,RXNE不清,系统卡死

你有没有想过一个问题:USART接收中断配置好了,一上电程序就卡死,一直在中断里出不来。很可能你没读DR。RXNE标志置1后,只有读DR才能清除。RXNE:接收数据寄存器非空,USART收到一个字节,硬件把数据存入DR,同时RXNE标志置1。如果RXNEIE使能,触发中断。中断里必须读DR,硬件才自动清除RXNE。

void USART1_IRQHandler(void)

{

if (USART1->SR & USART_SR_RXNE) {

uint8_t data = USART1->DR; // 读DR,硬件自动清RXNE

// 处理数据...

}

}

不读DR,RXNE永远为1,退出中断立即再进,系统卡死。ORE溢出错误:第二个陷阱,上一字节还没读,下一字节又收到了,ORE标志置1。ORE置1后,USART停止接收新数据,直到软件清除。清除ORE的正确顺序:先读SR,再读DR。

if (USART1->SR & USART_SR_ORE) {

volatile uint32_t tmp = USART1->SR; // 读SR

tmp = USART1->DR; // 再读DR

}

顺序错了,ORE清不掉。

回环实验,通过串口回环理解中断收发:

  1. 配置USART接收中断
  2. PC发送数据,单片机在中断中接收
  3. 将收到的数据立即发送回去(回环)

void USART1_IRQHandler(void)

{

if (USART1->SR & USART_SR_RXNE) {

uint8_t data = USART1->DR;

// 回环:将收到的数据立即发送

while (!(USART1->SR & USART_SR_TXE));

USART1->DR = data;

}

}

标志清除方式汇总

这个故事的启示,外设标志位是硬件给软件的“信号”,不清理,硬件就认为你还没忙完。收到信号(中断),回应信号(读DR清标志)。不回应,硬件一直喊,系统卡死。写在最后,写USART接收中断,记住三件事:读DR清RXNE,读SR再读DR清ORE,不清楚清除方式查手册。不读DR,中断不停。不清ORE,接收卡死。


(本文灵感源于于振南《新概念ARM32单片机》教程第4.9节。)

觉得有用?点赞、转发,让更多人避开“不读DR”的坑。