1. UART基础回顾:协议帧格式与关键参数详解
UART(Universal Asynchronous Receiver/Transmitter,通用异步收发器)是嵌入式系统中最基础、最广泛使用的串行通信协议之一。它采用异步方式传输数据,即收发双方不需要共享时钟信号,而是通过预先约定的波特率和帧格式来同步数据采样点。理解UART的帧结构、波特率计算以及校验机制,是后续FIFO管理与中断触发条件调试的基石。
核心要点:UART通信的可靠性完全依赖于收发双方对帧格式和波特率的精确匹配。任何参数偏差都会导致数据错位、校验失败或帧错误。
1.1 UART协议帧格式
一个标准的UART数据帧由以下部分组成:
- 起始位(Start Bit): 固定为逻辑低电平(0),标志一帧数据的开始。
- 数据位(Data Bits): 通常为5~9位,常见配置为8位(1字节)。数据位从最低有效位(LSB)开始传输。
- 校验位(Parity Bit): 可选字段,用于简单的错误检测。分为奇校验、偶校验或无校验。
- 停止位(Stop Bit): 固定为逻辑高电平(1),标志一帧数据的结束。常见长度为1位、1.5位或2位。
驱动开发提示:在配置UART控制器时,数据位、校验位和停止位的组合通常被称为“字长配置”。例如“8N1”表示8位数据、无校验、1位停止位,这是最常用的配置。
1.2 波特率详解
波特率(Baud Rate) 表示每秒传输的符号数。在UART中,一个符号对应一个比特位,因此波特率等于比特率(bps)。波特率决定了每一位的持续时间:位时间 = 1 / 波特率。
| 波特率 (bps) | 位时间 (μs) | 8N1 帧传输时间 (μs) | 典型应用场景 |
|---|---|---|---|
| 9600 | 104.17 | 约 1041.7 | 调试控制台、GPS模块 |
| 115200 | 8.68 | 约 86.8 | 蓝牙模块、传感器数据流 |
| 921600 | 1.09 | 约 10.9 | 高速数据采集、固件升级 |
| 3000000 | 0.33 | 约 3.3 | 高速UART桥接芯片 |
波特率误差容限:UART接收端通常要求波特率误差在 ±2% 以内。如果系统时钟分频无法精确匹配目标波特率,应优先选择误差最小的分频值。过大的波特率误差会导致采样点偏移,引发帧错误或数据错位。
1.3 起始位、数据位、停止位与校验位详解
起始位
起始位是UART帧的同步信号。在总线空闲(高电平)状态下,发送端将总线拉低一个位时间,接收端检测到这个下降沿后启动内部采样时钟,开始接收后续数据位。起始位的下降沿是接收端进行位同步的唯一参考点。
数据位
数据位承载实际传输的信息。常见配置为8位,但部分协议(如LIN总线)使用9位数据模式。数据位从LSB(最低有效位)开始传输,接收端按顺序采样并重组为字节。
| 数据位长度 | 传输字节数 | 典型用途 |
|---|---|---|
| 5位 | 半字节 | 早期电传打字机 |
| 7位 | ASCII字符 | AT指令集、短信PDU模式 |
| 8位 | 1字节 | 通用数据、二进制协议 |
| 9位 | 1字节 + 地址/标志 | 多机通信、9位协议 |
停止位
停止位标志一帧数据的结束,固定为高电平。接收端在停止位期间检测总线状态,如果停止位不是高电平,则产生帧错误(Frame Error)。停止位长度可以是1位、1.5位或2位,较长的停止位为接收端提供更多处理时间,适用于低速或高噪声环境。
校验位
校验位提供简单的错误检测能力。发送端根据数据位中1的个数计算校验位,接收端重新计算并比对。
- 无校验(None): 不发送校验位,帧长度最短。
- 奇校验(Odd): 数据位 + 校验位中1的总数为奇数。
- 偶校验(Even): 数据位 + 校验位中1的总数为偶数。
- 固定校验(Mark/Space): 校验位固定为1(Mark)或0(Space),较少使用。
驱动开发建议:在调试阶段,建议先使用“8N1”配置(8位数据、无校验、1位停止位),排除校验位引入的额外复杂性。待基本收发稳定后,再根据协议要求启用校验位。
1.4 UART通信中的常见错误标志
UART控制器硬件通常提供以下错误检测标志,驱动开发中需要正确处理这些中断状态:
| 错误类型 | 触发条件 | 驱动处理建议 |
|---|---|---|
| 帧错误 (FE) | 停止位采样为低电平 | 检查波特率匹配、总线噪声、收发器电平 |
| 校验错误 (PE) | 接收端计算的校验位与接收到的校验位不一致 | 确认收发双方的校验模式一致,检查数据完整性 |
| 溢出错误 (OE) | 接收FIFO已满,新数据覆盖旧数据 | 优化FIFO阈值设置,提高中断响应速度 |
| 间断检测 (BI) | 接收线保持低电平超过一个完整帧时间 | 通常用于唤醒或复位信号,需在协议层处理 |
驱动开发关键:在中断服务函数中,必须首先读取UART状态寄存器,检查错误标志位。如果存在错误,应先清除错误标志,再读取数据寄存器,避免错误状态持续影响后续数据接收。