1. UART基础回顾

1.1 UART通信协议原理

UART(Universal Asynchronous Receiver/Transmitter,通用异步收发器)是一种采用异步串行通信方式的物理层协议。通信双方无需共享时钟信号,而是通过预先约定的波特率和帧格式完成数据收发。

核心特点:全双工、异步、点对点、无时钟线、依赖起始位同步。

UART通信的基本链路包含三根信号线:

  • TXD(Transmit Data):发送数据线
  • RXD(Receive Data):接收数据线
  • GND(Ground):共地参考
UART 点对点通信链路 设备 A (TXD / RXD) 设备 B (TXD / RXD) TXD → RXD RXD ← TXD GND(共地)

1.2 UART帧格式详解

UART数据以帧为单位传输,每一帧由以下字段按顺序组成:

字段 位宽 电平状态 说明
起始位 1 bit 逻辑 0(低电平) 标志帧开始,接收端通过下降沿同步
数据位 5 ~ 9 bits LSB 优先 实际有效数据,常用 8 bits
校验位 0 / 1 bit 奇/偶/无 可选,用于检错
停止位 1 / 1.5 / 2 bits 逻辑 1(高电平) 帧结束标志,保证帧间间隔
常见配置:8N1 = 8 数据位 + 无校验 + 1 停止位,是嵌入式 Linux 中最常用的 UART 帧格式。
UART 帧格式时序图(8N1) 空闲 高电平 起始 0 D0 D1 D2 D3 D4 D5 D6 D7 停止 1 空闲 下降沿同步 高电平结束 1 帧 = 10 bits(8N1)

1.3 波特率计算

波特率(Baud Rate)表示每秒传输的符号数。在 UART 中,1 个符号 = 1 bit,因此波特率等于比特率(bps)。

1.3.1 波特率与时钟分频

UART 外设通常由系统时钟(如 50 MHz、100 MHz)驱动,通过分频器产生目标波特率时钟。通用计算公式如下:

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

其中:
- 时钟频率:UART 模块输入时钟(Hz)
- 16:过采样因子(多数 UART IP 使用 16 倍过采样)
- 分频系数:可编程整数或小数分频值
示例:若 UART 时钟 = 50 MHz,目标波特率 = 115200,则分频系数 = 50,000,000 / (16 × 115200) ≈ 27.13。实际取整后,真实波特率会有微小偏差,需确保误差 < 2%。

1.3.2 常用波特率对照表

波特率(bps) 位时间(μs) 1 字节传输时间(8N1) 典型应用场景
9600 104.17 1.04 ms 调试终端、低速率传感器
19200 52.08 0.52 ms 工业控制、GPS 模块
38400 26.04 0.26 ms 蓝牙模块、串口屏
115200 8.68 86.8 μs Linux 内核调试串口(最常用)
230400 4.34 43.4 μs 高速数据采集
921600 1.09 10.9 μs 高速透传、FPGA 通信
波特率误差警告:Linux 内核中 UART 驱动通过 uart_get_baud_rate() 函数计算实际分频值。若分频取整后误差超过 ±2%,可能导致接收端采样点偏移,产生误码。驱动开发中务必通过 clk_round_rate() 确认实际时钟精度。
UART 波特率分频原理 系统时钟 50 MHz 分频器 ÷ (16 × 分频系数) 波特率时钟 115200 Hz 分频系数 = 50 MHz / (16 × 115200) ≈ 27.13 → 取整 27

1.4 本章小结

  • UART 是异步串行通信协议,依赖起始位下降沿同步,无需时钟线。
  • 标准帧格式包含:起始位(1) + 数据位(5~9) + 校验位(0/1) + 停止位(1/2),8N1 是 Linux 串口默认配置。
  • 波特率由系统时钟经 16 倍过采样分频 产生,驱动开发中必须校验分频误差 < 2%。
  • Linux 内核通过 uart_get_baud_rate() 和 uart_update_timeout() 管理波特率与超时参数,后续章节将深入 FIFO 与中断交互。