4. UART 寄存器详解:数据寄存器 DR、状态寄存器 SR、控制寄存器 CR1/CR2/CR3、波特率寄存器 BRR
UART 外设的寄存器是驱动开发者与硬件交互的唯一接口。在中断模式下,实时响应与高吞吐量的实现,依赖于对每个寄存器位域的精确理解与配置。本章将深入剖析 STM32 系列(以 USART2 为例)的五大核心寄存器组:数据寄存器(DR)、状态寄存器(SR)、控制寄存器(CR1/CR2/CR3)以及波特率寄存器(BRR)。
寄存器访问提示: 所有 UART 寄存器均为 32 位宽,但实际有效位域因型号而异。在编写驱动时,务必参考对应芯片的参考手册(Reference Manual),避免使用保留位(Reserved)导致不可预期的行为。
4.1 数据寄存器(DR)—— 收发数据的核心通道
数据寄存器(Data Register, DR)是 CPU 与 UART 移位寄存器之间的数据缓冲。它实际上由两个物理寄存器组成:发送数据寄存器(TDR)和接收数据寄存器(RDR),但共享同一个地址。读取 DR 返回接收到的数据,写入 DR 则装载待发送的数据。
| 位域 | 名称 | 描述 |
|---|---|---|
| [31:9] | 保留 | 必须保持复位值(0x000) |
| [8:0] | DR[8:0] | 数据值。当字长配置为 9 位时,DR[8] 有效;8 位模式下仅 DR[7:0] 有效。 |
中断模式下的 DR 操作要点:
- 发送: 在 TXE(发送数据寄存器空)中断触发后,向 DR 写入下一个待发送字节。写入动作会自动清除 TXE 标志。
- 接收: 在 RXNE(接收数据寄存器非空)中断触发后,必须及时读取 DR 以获取数据,否则后续接收数据将导致溢出错误(ORE)。
- 溢出处理: 若 RXNE 标志未被清除前又有新数据到达,硬件会置位 ORE 标志并可能丢失旧数据。中断服务函数中应先检查 ORE,再读取 DR。
4.2 状态寄存器(SR)—— 中断与错误标志的实时窗口
状态寄存器(Status Register, SR)反映了 UART 模块的实时运行状态。中断使能位决定哪些状态标志能够触发中断请求,而中断服务函数则通过查询 SR 来判断事件类型。
| 位 | 标志 | 含义 | 中断使能位 | 清除方式 |
|---|---|---|---|---|
| 7 | TXE | 发送数据寄存器空 | CR1.TXEIE | 写 DR 自动清除 |
| 6 | TC | 发送完成 | CR1.TCIE | 写 DR 或读 SR+写 DR |
| 5 | RXNE | 接收数据寄存器非空 | CR1.RXNEIE | 读 DR 自动清除 |
| 4 | IDLE | 总线空闲 | CR1.IDLEIE | 读 SR+读 DR |
| 3 | ORE | 溢出错误 | CR1.RXNEIE | 读 SR+读 DR |
| 2 | NF | 噪声标志 | 无 | 读 SR+读 DR |
| 1 | FE | 帧错误 | 无 | 读 SR+读 DR |
| 0 | PE | 奇偶校验错误 | CR1.PEIE | 读 SR+读 DR |
常见陷阱: 许多初学者在中断服务函数中只读取 DR 而不检查 ORE/NF/FE 标志。在高速通信或干扰环境下,这会导致数据错位而不自知。建议在 RXNE 中断处理中始终先读取 SR,检查错误标志,再读取 DR。
4.3 控制寄存器 CR1/CR2/CR3 —— 模式与功能的配置中心
三个控制寄存器(Control Register 1/2/3)共同决定了 UART 的工作模式、数据格式、流控方式以及中断使能。下面以表格形式列出每个寄存器的关键位域。
4.3.1 CR1 寄存器
| 位 | 名称 | 功能描述 |
|---|---|---|
| 13 | UE | UART 使能。必须置 1 后其他配置才生效。 |
| 12 | M | 字长选择:0=8 位,1=9 位。 |
| 11 | WAKE | 唤醒方式:0=空闲总线,1=地址匹配。 |
| 10 | PCE | 奇偶校验使能。 |
| 9 | PS | 奇偶校验选择:0=偶校验,1=奇校验。 |
| 8 | PEIE | 奇偶校验错误中断使能。 |
| 7 | TXEIE | 发送缓冲区空中断使能。 |
| 6 | TCIE | 发送完成中断使能。 |
| 5 | RXNEIE | 接收缓冲区非空中断使能。 |
| 4 | IDLEIE | 空闲总线中断使能。 |
| 3 | TE | 发送器使能。 |
| 2 | RE | 接收器使能。 |
| 0 | SBK | 发送间隔帧(Break)。 |
4.3.2 CR2 寄存器
| 位 | 名称 | 功能描述 |
|---|---|---|
| 14 | LINEN | LIN 模式使能。 |
| 13:12 | STOP[1:0] | 停止位长度:00=1 位,01=0.5 位,10=2 位,11=1.5 位。 |
| 11 | CLKEN | 时钟输出使能(同步模式)。 |
| 10 | CPOL | 时钟极性。 |
| 9 | CPHA | 时钟相位。 |
| 6 | LBDIE | LIN 间隔帧检测中断使能。 |
| 5 | LBDL | LIN 间隔帧检测长度。 |
4.3.3 CR3 寄存器
| 位 | 名称 | 功能描述 |
|---|---|---|
| 10 | CTSIE | CTS 状态变化中断使能。 |
| 9 | CTSE | CTS 硬件流控使能。 |
| 8 | RTSE | RTS 硬件流控使能。 |
| 7 | DMAT | 发送 DMA 使能。 |
| 6 | DMAR | 接收 DMA 使能。 |
| 5 | SCEN | 智能卡模式使能。 |
| 4 | NACK | 智能卡 NACK 使能。 |
| 3 | HDSEL | 半双工选择。 |
| 1 | IRLP | 红外低功耗模式。 |
| 0 | IREN | 红外模式使能。 |
中断模式典型配置序列:
// 1. 使能 USART2 时钟
RCC->APB1ENR |= RCC_APB1ENR_USART2EN;
// 2. 配置 GPIO 为复用功能(略)
// 3. 配置波特率
USART2->BRR = 0x1A0; // 假设 16MHz 时钟,115200 bps
// 4. 配置 CR1:8 位数据、1 位停止、使能发送/接收、使能 RXNE 中断
USART2->CR1 = (0 << 12) // M=0: 8 位
| (0 << 10) // PCE=0: 无校验
| (1 << 3) // TE=1: 发送使能
| (1 << 2) // RE=1: 接收使能
| (1 << 5); // RXNEIE=1: 接收中断使能
// 5. 使能 UART
USART2->CR1 |= (1 << 13); // UE=1
// 6. 使能 NVIC 中断(以 STM32F4 为例)
NVIC_EnableIRQ(USART2_IRQn);
4.4 波特率寄存器(BRR)—— 通信速率的精确设定
波特率寄存器(Baud Rate Register, BRR)决定了 UART 的串行通信速率。其值由系统时钟频率(f_CK)和目标波特率共同计算得出。STM32 的 BRR 采用 16 位整数部分 + 4 位小数部分的定点格式。
| 位域 | 名称 | 描述 |
|---|---|---|
| [15:4] | DIV_Mantissa[11:0] | 整数部分(12 位) |
| [3:0] | DIV_Fraction[3:0] | 小数部分(4 位) |
计算公式:
BRR 值 = f_CK / (16 × 目标波特率)
整数部分 = floor(BRR 值)
小数部分 = round((BRR 值 - 整数部分) × 16)
// 示例:f_CK = 16 MHz,目标波特率 = 115200
BRR 值 = 16000000 / (16 × 115200) = 8.6806
整数部分 = 8
小数部分 = round(0.6806 × 16) = round(10.889) = 11 (0xB)
BRR 寄存器值 = (8 << 4) | 0xB = 0x8B
波特率误差容忍度: 实际波特率与目标波特率之间的误差应控制在 ±2% 以内,否则可能导致通信丢帧。在中断模式下,如果波特率误差过大,RXNE 中断可能频繁触发但数据错误,严重影响实时性。建议使用表格预先计算常用波特率对应的 BRR 值。
4.5 寄存器配置速查表
下表汇总了中断模式 UART 驱动开发中最常用的寄存器配置组合,方便快速查阅。
| 配置项 | 相关寄存器 | 典型值 | 说明 |
|---|---|---|---|
| 波特率 115200 | BRR | 0x8B (16MHz) | 需根据实际时钟计算 |
| 8N1 模式 | CR1, CR2 | CR1.M=0, CR2.STOP=00 | 8 位数据,无校验,1 位停止 |
| 使能接收中断 | CR1 | RXNEIE=1 | 接收数据到达时触发中断 |
| 使能发送中断 | CR1 | TXEIE=1 | 发送缓冲区空时触发中断 |
| 硬件流控 | CR3 | CTSE=1, RTSE=1 | 需配合 CTS/RTS 引脚 |
| DMA 传输 | CR3 | DMAT=1, DMAR=1 | 与中断模式互斥,用于高吞吐 |
寄存器配置顺序: 在修改 CR1 的 UE 位之前,必须先完成所有其他配置(波特率、数据格式、中断使能等)。UE 置 1 后,UART 立即开始工作,此时再修改某些位可能导致不可预测的行为。推荐顺序:时钟 → GPIO → BRR → CR2 → CR3 → CR1(含 UE)。