2. UART硬件架构:深入理解控制器内部结构

UART(Universal Asynchronous Receiver/Transmitter,通用异步收发器)是嵌入式系统中历史最悠久、应用最广泛的串行通信接口之一。要编写高效的UART驱动,首先必须透彻理解其硬件架构。本章将深入剖析UART控制器的内部结构,包括发送器、接收器、波特率发生器以及FIFO缓冲区等核心模块。

2.1 UART控制器整体架构

一个典型的UART控制器内部由多个功能模块组成,它们协同工作以实现串行数据的异步收发。下图展示了UART控制器的核心架构。

UART控制器内部架构图 UART控制器内部架构 系统总线接口 控制寄存器组 波特率发生器 发送器 (TX) 移位寄存器 + 控制 接收器 (RX) 移位寄存器 + 控制 TX FIFO 发送数据缓冲区 RX FIFO 接收数据缓冲区 中断控制器 中断产生与屏蔽 TXD 引脚 RXD 引脚 时钟源输入 (如 16× 波特率时钟)

从上图可以看出,UART控制器通过系统总线接口与CPU连接,内部包含控制寄存器组、波特率发生器、发送器、接收器、FIFO缓冲区以及中断控制器等模块。下面我们将逐一深入分析每个模块的工作原理。

2.2 发送器(TX)

发送器负责将并行数据转换为串行数据,并按照UART协议帧格式逐位发送到TXD引脚上。其核心组件是发送移位寄存器。

2.2.1 发送器工作原理

  1. 数据加载:CPU将待发送的数据写入发送数据寄存器(THR),数据被送入TX FIFO或直接送入发送移位寄存器。
  2. 并行转串行:发送移位寄存器在波特率时钟驱动下,将并行数据逐位移出。
  3. 帧格式封装:在数据位前后自动添加起始位(0)、可选的奇偶校验位和停止位(1)。
  4. 位发送:每个位在TXD引脚上保持一个波特率时钟周期。
UART发送帧格式 UART发送帧格式(8N1:8数据位,无校验,1停止位) 起始位 0 D0 D1 D2 D3 D4 D5 D6 D7 停止位 1 时间方向 → LSB先发送 MSB后发送
关键点:UART协议规定数据以LSB(最低有效位)优先的方式发送。这意味着数据字节的位0最先出现在TXD引脚上,位7最后出现。驱动开发中,发送中断通常在发送移位寄存器为空时触发,通知CPU可以写入下一个数据。

2.3 接收器(RX)

接收器与发送器相反,它从RXD引脚接收串行数据,将其转换为并行数据,并去除起始位、校验位和停止位,最终将有效数据存入接收数据寄存器(RBR)或RX FIFO中。

2.3.1 接收器工作原理

  1. 起始位检测:接收器持续采样RXD引脚,检测到高电平到低电平的跳变(起始位)后开始接收。
  2. 位采样:在每个数据位的中间时刻(通常使用16倍波特率时钟进行过采样)采样RXD电平,确保数据稳定。
  3. 串行转并行:接收移位寄存器将接收到的串行位流组装成并行数据。
  4. 帧校验:检查停止位是否为1,以及奇偶校验位是否正确(如果启用)。
  5. 数据存储:有效数据被送入RX FIFO或接收数据寄存器,等待CPU读取。
UART接收采样过程 UART接收采样过程(16×过采样) 采样时钟 一个数据位(16个采样时钟周期) 采样点(第8个时钟) 过采样技术: 在每个位中间采样 提高抗干扰能力
常见问题:接收器可能遇到帧错误(停止位不是1)、奇偶校验错误或溢出错误(前一个数据未被读取,新数据已到达)。驱动开发中必须检查错误标志位,并进行相应的错误处理。

2.4 波特率发生器

波特率发生器是UART的“心跳”,它根据输入的系统时钟产生精确的波特率时钟,控制数据位的发送/接收速率。

2.4.1 波特率计算公式

大多数UART控制器使用以下公式计算波特率:

波特率 = 时钟频率 / (16 × 分频系数)

其中:
- 时钟频率:UART模块的输入时钟(如系统时钟或专用时钟)
- 16:过采样因子(大多数UART使用16倍过采样)
- 分频系数:可编程的分频器值(通常为16位寄存器)

2.4.2 常见波特率与分频系数对照表

目标波特率 (bps) 时钟频率 16 MHz 时钟频率 24 MHz 时钟频率 50 MHz
9600 104 (0.16% 误差) 156 (0.16% 误差) 325 (0.16% 误差)
19200 52 (0.16% 误差) 78 (0.16% 误差) 162 (0.16% 误差)
115200 8 (2.12% 误差) 13 (0.16% 误差) 27 (0.08% 误差)
921600 1 (8.51% 误差) 1 (38.7% 误差) 3 (1.36% 误差)
工程实践:波特率误差应控制在±2%以内,否则可能导致通信失败。当误差较大时,可以考虑使用小数分频(Fractional Baud Rate Generator)或选择更合适的系统时钟频率。许多现代MCU的UART支持小数波特率发生器,可以精确匹配标准波特率。

2.5 FIFO缓冲区

FIFO(First In First Out,先进先出)缓冲区是UART控制器内部的小型硬件队列,用于缓解CPU与UART之间的速度不匹配问题。

2.5.1 FIFO的作用

  • 减少中断频率:CPU可以在FIFO达到触发阈值时才响应中断,而不是每个字节都中断一次。
  • 防止数据丢失:在CPU响应中断前,FIFO可以暂存多个接收到的数据字节。
  • 提高传输效率:发送FIFO允许CPU一次性写入多个字节,UART自动逐位发送。

2.5.2 FIFO深度与触发阈值

FIFO类型 典型深度 常见触发阈值 适用场景
无FIFO 1字节 不适用 低端MCU,简单应用
16字节FIFO 16字节 1/4/8/14字节 通用嵌入式系统
64字节FIFO 64字节 1/8/16/32/56字节 高速通信,多任务系统
128字节FIFO 128字节 1/16/32/64/112字节 DMA传输,高吞吐量

2.5.3 FIFO操作流程

FIFO操作流程 FIFO操作流程(接收方向) ① 数据到达RXD引脚 接收器完成帧接收 ② 数据存入RX FIFO FIFO写指针递增 ③ 检查FIFO状态 是否达到触发阈值? ④ 未达阈值:继续接收 等待更多数据到达 ④ 达到阈值:触发中断 通知CPU读取数据

2.6 关键寄存器总结

UART驱动开发中需要操作的核心寄存器如下表所示:

寄存器名称 缩写 方向 功能描述
接收数据寄存器 RBR 只读 读取接收到的数据(从RX FIFO顶部)
发送数据寄存器 THR 只写 写入待发送的数据(写入TX FIFO尾部)
波特率除数寄存器 DLL/DLH 读写 设置波特率分频系数(低字节/高字节)
线路控制寄存器 LCR 读写 配置数据位、停止位、校验位、波特率访问锁
线路状态寄存器 LSR 只读 指示发送/接收状态、错误标志
FIFO控制寄存器 FCR 只写 使能/清空FIFO、设置触发阈值
中断使能寄存器 IER 读写 使能/屏蔽各类中断源
中断标识寄存器 IIR 只读 标识当前中断类型(优先级编码)
驱动开发要点:
  • 初始化顺序:配置LCR(帧格式)→ 设置DLL/DLH(波特率)→ 配置FCR(FIFO)→ 配置IER(中断)→ 使能UART。
  • 发送流程:检查LSR的THR空标志 → 写入THR → 等待发送完成(或使用中断)。
  • 接收流程:检查LSR的DR(数据就绪)标志 → 读取RBR → 检查LSR错误位。
  • 中断处理:读取IIR判断中断类型 → 执行对应处理 → 清除中断源。

2.7 本章小结

UART控制器的硬件架构是驱动开发的基础。理解发送器与接收器的移位寄存器