一、UART 通讯简介
1.1 UART 通讯简介
UART 是 Universal Asynchronous Receiver / Transmitter 的缩写,中文为通用异步收发器。
发送端把并行数据 (如 CPU 内部的 8 位数据) 转成串行信号,接收端把串行信号重新变成并行字节,双方没有共享时钟线,靠起始位和波特率同步时序。
UART 协议在数据链路层和物理层并没有规定有关总线通讯的协议,如果要实现总线通讯,也就是在一条总线上挂载三个及以上的设备,其通讯方式只能在应用层完成,以一主机多从机形式实现。
UART 协议仅规范 OSI 模型下的数据链路层。其物理层模型并没有规范,我们可以使用 TLL 电平、RS-232、RS-485 和 RS-422 电气协定进行通讯。
1.2 特性
1.2.1 优点
- 只需要两条线:TX (发送) 和 RX (接收) ,可选 GND。无需时钟线。
- 几乎所有 MCU 都自带 UART 外设,驱动简单,配置方便。
- 不需要共享时钟,主从设备的时钟只需波特率匹配。
- 有起始位、停止位、可选校验位,能检测单比特错误。
- TX 和 RX 独立,可以同时发送和接收数据。
1.2.2 缺点
- UART 本质是点对点通信,不能天然支持总线结构 (不像 CAN、I²C 那样) 。
- 没有时钟的异步通信需要双方波特率精确匹配,否则易出现位错。
- 常见波特率如 9600、115200 bps;相比 SPI/I²C/CAN 等高速总线要慢。
- UART 只是一种字节流接口,没有帧结构或地址机制,需要上层协议实现。
二、数据链路层
2.1 什么是数据链路层
物理层定义了 0 和 1 的信号形式。数据链路层则提供可靠的数据传输,进行帧的封装、错误检测、流量控制。
- 帧封装:把目标数据封装成一帧 (Frame),加上帧头、帧尾,使接收方能识别帧的起止。
- 物理寻址:每个链路设备都有一个地址,用于在同一总线中识别发送方和接收方。
- 差错检测与纠正:CRC、奇偶校验等方式检测 (有时纠正) 比特错误。
- 流量控制:控制发送速度,防止发送方过快导致接收方缓冲区溢出。
- 重传控制:通过确认(ACK)机制与超时重传,提高传输可靠性。
对于 UART 协议中的数据链路层提供了:帧封装 (空闲状态、起始位、数据位、停止位)、错误检测 (CRC 校验)、流量控制 (硬件或软件流控)。
2.2 帧数据波形
如果我们使用 停止位 1 位、数据位 8 位,无校验位的格式,其一帧结构如下:

2.3 空闲状态、起始位、数据位、校验位、停止位
2.3.1 空闲状态
串口在没有数据时处于高电平。
2.3.2 起始位
串口在空闲时一直处于高电平,如果在空闲状态波形被拉低一格,则是一个起始位,就是上图的 (1) 格。
2.3.3 数据位
其中 (2)~(9) 为数据位,我们可以看到上图的数据位中的数据是 1101 0010,也就是 0xD2。
2.3.4 停止位
在数据位结束之后,会被拉到一格,这也就是停止位了,意味着数据位结束。之后就回到了空闲状态,也就是高电平。对应上图的 (10)。
2.3.5 校验位
上图中没有校验位,他的位置介于上图的数据位 (9) 和停止位 (10) 之间,其定义为:
- 如果数据里1的个数是偶数 → 校验位 = 1
- 如果数据里1的个数是奇数 → 校验位 = 0
2.5 流控
2.5.1 硬件流控
硬件流控解决收发速度过快的问题。它的基本含义非常简单,当接收端接收到的数据处理不过来时,就向发送端发送不再接收的信号,发送端接收到这个信号之后就会停止发送,直到收到可以继续发送的信号再继续发送。因此流控本身是可以控制数据传输的进度,进而防止数据丢失。
硬件流控需要两根额外的信号线:
| 信号线 | 全称 | 方向 | 作用 |
| RTS | Request To Send | 输出 (本机→对方) | 本机准备好接收数据 |
| CTS | Clear To Send | 输入 (对方→本机) | 对方允许本机发送数据 |

前一路信号控制 B 设备的发送,后一路信号控制 A 设备的发送。
对B设备的发送 (A 设备接收) 来说,如果 A 设备接收缓冲快满的时发出 RTS 信号 (RTS 拉高,RTS 无效,告知对方停止发送),通知B设备停止发送,B 设备通过 CTS 检测到该信号,停止发送;
一段时间后 A 设备接收缓冲有了空余,发出RTS 信号 (RTS 拉低,RTS 有效,请求发送),指示B设备开始发送数据。A 设备发 (B 设备接收) 类似。
除了 RTS 和 CTS 之外还有 DTR 和 DSR 两个信号用于上电触发,这也是流控的一部分:
| 信号线 | 全称 | 方向 | 作用 |
| DTR | Data Terminal Ready | 输出 (本机→对方) | 设备上电就绪 |
| DSR | Data Set Ready | 输入 (对方→本机) | 对方设备就绪 |
2.5.2 软件流控
由于电缆线的限制,我们在普通的控制通讯中一般不用硬件流控制,而用软件流控制。一般通过XON/XOFF 来实现软件流控制。
常用方法是:当接收端的输入缓冲区内数据量超过设定的高位时,就向数据发送端发出 XOFF 字符 (十进制的 19 或 Control-S),发送端收到 XOFF 字符后就立即停止发送数据;
当接收端的输入缓冲区内数据量低于设定的低位时,就向数据发送端发出 XON 字符 (十进制的 17或 Control-Q),发送端收到 XON 字符后就立即开始发送数据。一般可以从设备配套源程序中找到发送的是什么字符。
应该注意,若传输的是二进制数据,标志字符也有可能在数据流中出现而引起误操作,这是软件流控制的缺陷,而硬件流控制不会有这个问题。
三、物理层
3.1 什么是物理层
物理层是 OSI 模型的第一层 (最底层),它负责 在物理媒介上发送和接收原始比特流,也就是把 0 和 1 转换成实际可传输的信号。它完全和数据内容无关,只关注 信号如何在介质上传播。
物理层的主要定义有:
- 电气特性:电压幅度、逻辑电平、信号极性 (高电平 / 低电平表示 0 / 1)
- 传输速率:比特率 (bps) 或以太网的 (Mbps) 等
- 物理拓扑:点对点 (串口) 、总线 (CAN)、星型 (以太网) 等
- 传输模式 :单工、半双工、全双工
3.2 传输速率——波特率
波特率 (Baud Rate) 是指每秒传输的符号 (Symbol) 数。
在 UART 中,一个符号 = 1 位 (bit),所以波特率 = 每秒传输的比特数 (bps)。
波特率 = 9600 表示每秒传输 9600 位 (包括起始位、数据位、校验位、停止位)。注意:波特率 ≠ 实际有效数据速率,因为一帧除了数据位,还有控制位。
例如:8N1 格式 (8 数据位、无校验、1 停止位),则每帧每帧有 10 位 (1+8+1)。
如果波特率为 9600 bps,则:
字节/秒
即每秒能传输约 960 字节 (≈1KB/s)。
3.1 TLL 电平
3.1.1 简介
TTL = Transistor–Transistor Logic (晶体管-晶体管逻辑)。它是一种数字逻辑电路的电平标准,规定了高电平和低电平。
常见使用于 USB-TTL 模块、MCU 串口、蓝牙串口模块等,大部分 STM32/Arduino 等都使用 TTL/CMOS 电平标准。
3.1.2 连线
共有四根引线:
| 引脚 | 名称 | 方向(相对主机) | 功能 |
| TXD | Transmit Data | 主机输出 → 设备输入 | 数据发送 |
| RXD | Receive Data | 主机输入 ← 设备输出 | 数据接收 |
| GND | Ground | 共地 | 通讯参考电平 |
| VCC | 电源 | 输出/输入 | 给设备供电 (3.3V/5V) |
接线定义如下:

3.1.3 拓扑结构
通常TLL 通讯的 UART 就是一对一的,所以没有拓扑结构。
3.1.4 电气规范
TLL 所规定的电平范围如下:
| 状态 | 输入电压范围 | 输出电压范围 | 说明 |
| 逻辑 0 (低电平) | 0V ~ 0.8V | 0V ~ 0.4V | 低电平最大 0.8V,输入低于此值被认为是逻辑 0 |
| 逻辑 1 (高电平) | 2.0V ~ 5.0V | 2.4V ~ 5.0V | 高电平最小 2.4V,输入高于 2V 认为是逻辑 1 |
| 不确定区 | 0.8V ~ 2.0V | —— | 信号在此区间逻辑状态不确定 |
3.2 RS-485
3.2.1 简介
RS-485 是一种差分串行通信标准,不是协议。它只规定电气层 (电压 / 布线 / 抗干扰能力),不规定数据格式。常用于工业、楼宇、仪表等多节点可靠通讯。其收发共用一对差分线。
3.2.2 连线
详细定义如下:
| 引脚 | 名称 | 方向(相对主机) | 功能说明 |
|---|---|---|---|
| A / D+ | RS-485 A(正线) | 双向 | 差分线 + (有些厂商叫 D+ / Data+) |
| B / D- | RS-485 B(负线) | 双向 | 差分线 - (有些厂商叫 D- / Data-) |
| GND | Signal Ground | 共地 | 通讯参考地(强烈建议接) |
MCU 不能直接驱动 RS-485 波形,所以需要一个 485 转换芯片:

3.2.3 拓扑结构
RS-485 支持 最多 32 个节点(新版芯片可到 128 或 256 节点)。
下图是 485 总线的拓扑结构:

比较特殊的同步 485 拓扑结构,收发使用不同的线,比较少见。

3.2.4 电气规范
RS-485 所规定的电平范围如下:
| 状态 | 差分电压 | 电压关系 |
| 逻辑 1 (低电平) | A 高于 B | |
| 逻辑 0 (高电平) | B 高于 A |
3.2 RS-232
3.2.1 简介
RS-232 是一种串行通信的电气标准(不是协议)。单端、一对一、短距离的传统串口标准,常见于电脑和工控机。
3.2.2 连线
RS-232 有一个标准插头。

其接线定义如下:
详细定义如下:
| 引脚号 | 信号名称 | 方向(相对 DTE/主机) | 功能说明 |
| 1 | DCD (Data Carrier Detect) | 输入 | 调制解调器载波检测 |
| 2 | RXD (Receive Data) | 输入 | 接收数据 |
| 3 | TXD (Transmit Data) | 输出 | 发送数据 |
| 4 | DTR (Data Terminal Ready) | 输出 | 终端就绪信号 |
| 5 | GND (Signal Ground) | — | 公共地 |
| 6 | DSR (Data Set Ready) | 输入 | 调制解调器就绪信号 |
| 7 | RTS (Request To Send) | 输出 | 请求发送控制 |
| 8 | CTS (Clear To Send) | 输入 | 清除发送控制 |
| 9 | RI (Ring Indicator) | 输入 | 来电指示(电话/调制解调器) |
大多数 MCU / 工业设备只用 3 根核心线:
| 引脚 | 信号 | 方向 | 功能 |
|---|---|---|---|
| 2 | RXD | 输入 | 接收数据 |
| 3 | TXD | 输出 | 发送数据 |
| 5 | GND | — | 公共地 |
3.2.3 电气规范
RS-232 所规定的电平范围如下:
| 状态 | 电压范围 (V) | 逻辑 | 说明 |
| 逻辑 1 (低电平) | –3V ~ –15V | 逻辑 1 | 线路空闲时一般为 Mark (负电压) |
| 逻辑 0 (高电平) | +3V ~ +15V | 逻辑 0 | RS-232 的逻辑 0 是正电压 |
| 不确定区 | –3V ~ +3V | 未定义 | 接收端可能误判,不允许长期停留 |
3.3 RS-422
3.3.1 简介
RS-422 是一种差分串行通信电气标准,介于 RS-232 与 RS-485 之间。RS-422 是一种全双工差分串口,抗干扰强、距离远,比 RS-232 强,比 RS-485 简单。
3.3.1 连线
共有五根引线:
| 引脚 | 名称 | 方向(相对主机) | 功能 |
| TX+ | Transmit Data + | 主机输出 → 设备接收 | 差分正端,发送数据 |
| TX– | Transmit Data – | 主机输出 → 设备接收 | 差分负端,发送数据 |
| RX+ | Receive Data + | 主机接收 ← 设备发送 | 差分正端,接收数据 |
| RX– | Receive Data – | 主机接收 ← 设备发送 | 差分负端,接收数据 |
| GND | Ground | 共地 | 通讯参考电平 |
MCU 不具有直接发送 RS-422 的能力,需要一个收发芯片:

3.2.3 电气属性
RS-422 所规定的电平范围如下:
| 状态 | 差分电压 | 逻辑 | 说明 |
| 逻辑 1 | ≥ +0.2 V | 正端电压高于负端 | 表示逻辑 1 |
| 逻辑 0 | ≤ –0.2 V | 正端电压低于负端 | 表示逻辑 0 |
| 不确定区 | –0.2 V ~ +0.2 V | 未定义 | 接收端可能误判,不允许长期停留 |
3.4 物理层定义总结
| 项目 | TTL | RS-232 | RS-422 | RS-485 |
| 信号类型 | 单端 (对地) | 单端 (对地) | 差分 | 差分 |
| 逻辑定义 | 高=1,低=0 (正逻辑) | 高=0,低=1 (反逻辑) | A>B→1 (正逻辑) | A>B→1 (正逻辑) |
| 典型电平范围 | 0 V~5 V (或 3.3 V) | ±3 V~±15 V | ±2 V (差分) | ±1.5 V (差分) |
| 信号线数 | TX、RX、GND | 9 根或和 TLL 一样 | 4 线 (A±、B±) | 2 线 (A±、B±) |
| 通信方向 | 单向 | 全双工 | 单向 (1发多收) | 可多主多从 (半/全双工) |
| 最大节点数 | 1 发 1 收 | 1 发 1 收 | 1 发 10 收 | ≤32 节点 (典型) |
| 典型距离 | ≤1 m | ≤15 m | ≤1200 m | ≤1200 m |
| 抗干扰能力 | 弱 | 一般 | 强 | 很强 |
| 是否需接地 | 必须共地 | 必须共地 | 建议共地 (参考地) | 建议共地 (参考地) |
| 终端电阻 | 无 | 无 | 需要 (≈120 Ω) | 需要 (≈120 Ω) |
四、应用层
4.1 什么是应用层
OSI 模型中的应用层 (Application Layer) 是第七层,也是最靠近用户的一层。它直接为用户应用程序提供网络服务,是网络通信的最上层接口。
应用层的主要作用是:
- 为用户或软件提供网络访问接口
- 定义应用程序之间如何通信
- 规定数据格式、消息结构、命令集等
其中UART 通讯的协议通常规定 帧头、地址 (如果是一对多通讯)、长度、字段、命令字、校验方式、 DATA校验、数据的小端 / 大端等。
4.1 一对一通讯
4.1.1 示例的通讯协议
距离一个通讯协议,我们规定协议如下:
协议版本:1.0
串口参数:115200 8N1帧头:AA 55
长度:LEN = CMD + DATA 字节数
命令:见命令表
校验:Modbus CRC16 (低字节先传)
其中帧格式如下:
| HEAD1 | HEAD2 | LEN | CMD | DATA | CRC_L | CRC_H |
|---|---|---|---|---|---|---|
| 0xAA | 0x55 | 数据长度 | 命令字 | 数据区 | CRC16 低字节 | CRC16 高字节 |
规定命令字如下:
| 0x01 | 0x02 | 0x03 | 0x10 | 0x11 | 0x12 | 0x13 | 0x20 | 0x21 | 0x22 | 0x23 |
|---|---|---|---|---|---|---|---|---|---|---|
| 读寄存器 | 写单寄存器 | 写多寄存器 | 设置目标转速 | 设置 ID 电流 | 设置 IQ 电流 | 设置角度偏移 | 读取状态 | 读取速度反馈 | 读取电流反馈 | 读取母线电压 |
4.1.2 报文举例
设置电机速度为 1500 rpm (CMD=0x10)
AA 55 03 10 05 DC B8 4E // CRC16示例
设置 IQ = 2000 (CMD = 0x12)
AA 55 03 12 D0 07 92 0B
设置角度偏移 = -300 (CMD = 0x13)
AA 55 03 13 D4 FE 85 E0
读取速度反馈(CMD = 0x21)
AA 55 01 21 6C 60 //主控发送
AA 55 03 21 B0 04 3C B4 //电机回传 1200prm = 0x04B0(B0 04)
4.2 一对多通讯
刚才我们的协议是一对一的,下面我们设计一个一主机多从机案例。其从机不能主动发送消息,主机发送后从机应答。
协议版本:1.1
串口参数:115200 8N1帧头:AA 55
长度:LEN = CMD + DATA 字节数
命令:见命令表
校验:Modbus CRC16 (低字节先传)-------------------------------------------多从机扩展内容-----------------------------------
拓扑:RS-485 半双工 (主机轮询,从机仅在收到主机命令且地址匹配时应答)
单播:ADDR = 从机地址 (例如 0x05)
广播:ADDR = 0xFF,所有从机执行但不回复 (避免总线上多从机同时应答冲突)
主机地址通常不用,但可保留 (ADDR=0x00 表示 Maste)
其中帧格式如下:
| 字段名 | HEAD1 | HEAD2 | ADDR | LEN | CMD | DATA | CRC_L | CRC_H |
|---|---|---|---|---|---|---|---|---|
| 含义 | 帧头 0xAA | 帧头 0x55 | 从机地址 | 数据长度 | 命令字 | 数据区 | CRC16 低字节 | CRC16 高字节 |
规定命令字如下:
| 0x01 | 0x02 | 0x03 | 0x10 | 0x11 | 0x12 | 0x13 | 0x20 | 0x21 | 0x22 | 0x23 |
|---|---|---|---|---|---|---|---|---|---|---|
| 读寄存器 | 写单寄存器 | 写多寄存器 | 设置目标转速 | 设置 ID 电流 | 设置 IQ 电流 | 设置角度偏移 | 读取状态 | 读取速度反馈 | 读取电流反馈 | 读取母线电压 |
4.2.1 报文举例
主 -> 从机 0x05:设置转速 = 1500 rpm (CMD=0x10):
AA 55 05 03 10 DC 05 48 4D
主 -> 从机 0x05:读取速度 (CMD=0x21)
从机 0x05 -> 主:回复速度 = 1200 rpm (200 = 0x04B0 小端 B0 04):
AA 55 05 01 21 FC 5D //主 -> 从机
AA 55 05 03 21 B0 04 F5 42 //从机 0x05 -> 主
广播 -> 所有从机 (ADDR=0xFF):设置转速 = 1500 rpm(从机执行但不回复):
AA 55 FF 03 10 DC 05 90 59

961

被折叠的 条评论
为什么被折叠?



