4、UART核心寄存器详解(上):USART_SR(状态寄存器)、USART_DR(数据寄存器)

UART通信的底层控制,本质上是MCU通过寄存器读写来驱动硬件收发。在STM32等主流MCU中,USART模块的核心寄存器主要包括状态寄存器(USART_SR)和数据寄存器(USART_DR)。理解这两个寄存器的每一位含义,是编写稳定、高效UART驱动的基础。

4.1 USART_SR:状态寄存器(Status Register)

USART_SR是驱动开发中最常查询的寄存器,它实时反映UART外设的当前工作状态,包括数据是否就绪、发送是否完成、是否发生溢出或帧错误等。该寄存器为32位,但实际有效位集中在低8位。

位号 名称 类型 描述
Bit 9 CTS 只读 CTS标志(硬件流控制时使用)
Bit 8 LBD 只读 LIN断开检测标志
Bit 7 TXE 只读 发送数据寄存器空:1表示DR已空,可写入新数据
Bit 6 TC 只读 发送完成:1表示帧发送完成(包括停止位)
Bit 5 RXNE 只读 接收数据寄存器非空:1表示DR已收到新数据,可读取
Bit 4 IDLE 只读 空闲线路检测
Bit 3 ORE 只读 溢出错误:1表示数据未及时读取,新数据覆盖旧数据
Bit 2 NF 只读 噪声标志(检测到噪声)
Bit 1 FE 只读 帧错误:1表示停止位无效(波特率不匹配或线路干扰)
Bit 0 PE 只读 奇偶校验错误

驱动开发关键位速记:

  • TXE:发送缓冲区空 → 可以写DR
  • TC:发送完成 → 帧已发完(关闭使能或切换模式前必须检查)
  • RXNE:接收数据就绪 → 可以读DR
  • ORE:溢出错误 → 驱动必须处理,否则会丢失后续数据

4.1.1 中断使能与SR的联动

在中断模式下,USART_SR的某些位与中断使能寄存器(USART_CR1/CR2/CR3)配合工作。例如:

  • 使能RXNEIE(接收中断使能)后,当SR的RXNE位变为1时,硬件自动触发中断。
  • 使能TCIE(发送完成中断使能)后,当SR的TC位变为1时触发中断。

驱动开发中,中断服务函数(ISR)的第一步通常是读取SR,判断是哪个事件触发了中断,然后执行对应的读写操作。

避坑提示:读取SR后,某些标志位(如TC、RXNE)不会自动清零。通常采用“先读SR,再读/写DR”的序列来硬件清除标志。如果使用软件清零,需查阅参考手册确认具体操作。

4.2 USART_DR:数据寄存器(Data Register)

USART_DR是UART数据收发的直接通道。它是一个32位寄存器,但实际有效数据只占用低8位(或9位,取决于数据位配置)。

位号 名称 类型 描述
Bit 31:9 保留 — 保留位,写入0
Bit 8:0 DR[8:0] 读/写 数据值:发送时写入,接收时读取

4.2.1 发送数据流程(轮询模式示例)

// 发送一个字节(轮询模式)
void UART_SendByte(uint8_t data) {
    // 等待TXE置1,表示DR空
    while (!(USART1->SR & USART_SR_TXE));
    // 写入数据到DR
    USART1->DR = data;
    // 可选:等待TC置1,确保帧完全发送完成
    while (!(USART1->SR & USART_SR_TC));
}

4.2.2 接收数据流程(轮询模式示例)

// 接收一个字节(轮询模式)
uint8_t UART_ReceiveByte(void) {
    // 等待RXNE置1,表示DR有数据
    while (!(USART1->SR & USART_SR_RXNE));
    // 读取DR获取数据
    return (uint8_t)(USART1->DR & 0xFF);
}

关键注意:

  • 读DR前必须先读SR:这是硬件清除RXNE标志的标准序列。如果顺序颠倒,可能导致标志位无法正确清除,引发中断风暴或数据重复读取。
  • 写DR前必须等待TXE:如果DR未空就写入新数据,会覆盖上一个未发送的数据,造成发送错误。
  • 9位数据模式:当配置为9位数据位时,DR[8:0]全部有效,读取/写入时需使用uint16_t类型。

4.3 SR与DR的协同工作流程

下图展示了UART收发过程中,SR与DR的交互关系,以及中断触发的时机。

USART_SR 与 USART_DR 协同工作流程 CPU 写 DR TXE=0(DR满) 硬件移位发送 TXE=1(DR空) 触发TXE中断 硬件接收移位 RXNE=1(DR满) 触发RXNE中断 CPU 读 DR 读DR后RXNE自动清零

4.4 中断模式下的寄存器操作要点

  • ISR入口先读SR:通过读取SR判断中断来源(RXNE、TC、IDLE、ORE等),避免误处理。
  • 清除标志位:RXNE和TC标志通过“读SR后操作DR”自动清除;ORE标志需先读SR再读DR才能清除。
  • 错误处理:当检测到ORE、FE、NF或PE时,建议在ISR中记录错误计数,并重新初始化接收逻辑,防止数据错位。
  • 中断优先级:UART中断优先级不宜设置过高,避免阻塞其他实时任务;但接收中断(RXNE)应略高于发送中断(TC),防止接收溢出。

实战口诀:

“先读SR再读DR,接收不丢;先等TXE再写DR,发送不乱;ORE必须清,否则数据停。”