通讯协议-UART
UART(Universal Asynchronous Receiver/Transmitter,通用异步收发器)是一种常见的点对点串行通信方式。UART 规定了数据如何按位发送和接收,但不规定连接器、电压等级或上层数据帧格式。
接口组成
| 信号 | 方向(以本机为准) | 作用 |
|---|---|---|
| TX | 输出 | 发送串行数据 |
| RX | 输入 | 接收串行数据 |
| GND | - | 通信双方的参考地 |
| RTS/CTS | 可选 | 硬件流控,防止接收方来不及处理数据 |
最小全双工连接需要 TX、RX 和 GND。连接时,一端的 TX 应接另一端的 RX,两端必须共地。
MCU UART 通常使用 3.3 V 或 5 V TTL/CMOS 电平。RS-232、RS-485 与 UART 的电气特性不同,不能直接连接,必须使用对应的电平转换或收发器。
工作原理
UART 不传输独立时钟,通信双方依靠预先约定的波特率确定每一位的采样时间。线路空闲时通常为高电平,每个字符由起始位、数据位、可选校验位和停止位组成。
空闲 起始位 数据位(示例:8 位) 校验位 停止位 空闲
1 | 0 | D0 D1 D2 D3 D4 D5 D6 D7 | P | 1 | 1
UART 数据通常先发送最低有效位(LSB)。接收器检测到起始位的下降沿后,按波特率在每一位的中间位置采样。
帧格式
常见写法为“数据位-校验-停止位”,例如 8N1:
| 配置 | 含义 |
|---|---|
| 8 | 8 个数据位 |
| N | 无校验位(None) |
| 1 | 1 个停止位 |
常见校验方式:
| 类型 | 规则 | 能力 |
|---|---|---|
| 无校验(None) | 不发送校验位 | 无法通过 UART 字符帧检测数据位错误 |
| 偶校验(Even) | 数据位与校验位中 1 的总数为偶数 | 可检测奇数个位翻转 |
| 奇校验(Odd) | 数据位与校验位中 1 的总数为奇数 | 可检测奇数个位翻转 |
校验位只能提供有限的错误检测能力。需要更可靠的通信时,应在上层协议中增加长度、序号、校验和或 CRC。
波特率与吞吐量
波特率表示每秒传输的符号数。对普通二进制 UART,每个符号承载 1 bit,因此波特率通常可近似理解为 bit/s。
以 115200 8N1 为例,每个字节实际占用:
1 个起始位 + 8 个数据位 + 1 个停止位 = 10 bit
理论有效载荷速率约为:
115200 / 10 = 11520 byte/s
实际吞吐量还会受到报文头、校验、处理延迟和流控影响。
常见波特率包括 9600、19200、38400、57600、115200 和 1M。是否能稳定使用某一波特率,取决于双方时钟误差、UART 外设分频能力、线路质量和收发器能力。
关键参数
通信双方必须使用一致的参数:
| 参数 | 说明 |
|---|---|
| 波特率 | 每秒传输的符号数量 |
| 数据位 | 常见为 7、8 或 9 位 |
| 校验位 | 无、奇校验或偶校验 |
| 停止位 | 常见为 1 位或 2 位 |
| 电平与极性 | TTL/CMOS、RS-232、RS-485 等 |
| 流控方式 | 无流控、RTS/CTS 或软件流控 |
收发方式
| 方式 | 特点 | 适用场景 |
|---|---|---|
| 轮询 | 实现简单,但会占用 CPU | 低速、数据量小 |
| 中断 | 收到或发完数据时触发处理 | 常规命令与不定长报文 |
| DMA | 批量搬运数据,降低 CPU 负载 | 高波特率、连续数据流 |
接收不定长数据时,常结合环形缓冲区、接收超时或 UART 空闲线中断来判断一段数据结束。不要仅假设一次接收调用一定对应一帧完整报文。
上层协议设计建议
UART 只提供字节流,不提供报文边界。自定义协议通常需要明确以下内容:
| 项目 | 建议 |
|---|---|
| 帧头 | 选择固定标识,用于从字节流中重新同步 |
| 长度 | 明确长度字段是否包含帧头、校验等字段 |
| 命令或类型 | 区分请求、响应和事件 |
| 数据字节序 | 明确多字节整数使用大端还是小端 |
| 完整性校验 | 按可靠性需求选择校验和或 CRC |
| 超时与重试 | 定义请求超时、重试次数与重复帧处理方式 |
| 流量控制 | 数据可能突发时使用硬件流控或应用层确认 |
常见问题与排查
| 现象 | 常见原因 | 排查方法 |
|---|---|---|
| 完全无数据 | TX/RX 未交叉、未共地、外设未启用 | 测量 TX 空闲电平,检查接线与引脚复用 |
| 输出乱码 | 波特率或帧格式不一致 | 用逻辑分析仪解码并核对 8N1 等参数 |
| 偶发错误 | 时钟误差、线长、干扰或地电位差 | 降低波特率,检查边沿、电源和接地 |
| 丢字节 | 接收缓冲区过小、处理不及时 | 检查溢出标志,使用中断、DMA 或流控 |
| 首字节错误 | 接收端启动过晚或发送前无等待 | 确认双方初始化顺序和握手流程 |
| 能发送不能接收 | RX 引脚复用、方向或电平错误 | 直接观察 RX 引脚波形并检查配置 |
调试步骤
- 确认双方电压等级兼容,并连接公共地。
- 确认
TX与RX交叉连接。 - 核对波特率、数据位、校验位和停止位。
- 用示波器确认空闲电平、位宽和信号幅度。
- 用逻辑分析仪按已知参数解码,确认发送字节是否正确。
- 检查 UART 的溢出、帧错误、校验错误和噪声错误标志。
- 最后再检查上层协议的帧头、长度、字节序和校验算法。
适用场景
UART 适合调试日志、模块配置、MCU 间低成本点对点通信,以及通过收发器实现的 RS-232/RS-485 通信。它连接简单、软硬件支持广泛,但缺少原生寻址、时钟和报文边界,不适合直接连接大量节点。