在嵌入式系统、工业控制、智能硬件等领域,数据通信是核心功能之一,而UART(通用异步收发传输器) 作为最基础、最常用的串行通信协议,凭借结构简单、成本低、易实现的优势,至今仍在各类设备中广泛应用。从 MCU 与传感器的短距离数据交互,到 PC 与外设的调试通信,再到工业场景中的多设备组网,UART 始终扮演着 “数据桥梁” 的角色。
一、UART 核心概念:厘清基础定义与关键特性
要理解 UART,首先需明确其在通信体系中的定位 —— 它是一种异步串行通信协议,无需时钟信号同步,仅通过两根信号线(发送线 TX、接收线 RX)即可实现全双工数据传输。在展开细节前,需先厘清几个易混淆的核心概念,避免后续理解偏差。
1.1 UART 与 USART 的区别
很多人会将 UART 与 USART(通用同步异步收发传输器)混淆,二者的核心差异在于是否支持同步通信:
- UART:仅支持异步通信,传输过程中无需时钟信号,依赖 “波特率”(数据传输速率)实现发送端与接收端的时序同步;
- USART:兼容异步(UART 模式)和同步模式,同步模式下需额外一根时钟线(SCLK),发送端通过时钟信号控制接收端的采样时序,适合对传输速率和稳定性要求更高的场景(如高速数据传输)。
在实际应用中,多数 MCU(如 STM32、51 单片机)的 “UART 外设” 本质是 USART,但默认工作在异步模式,因此日常场景中 “UART” 的称呼更为通用。
1.2 异步通信与全双工的核心含义
UART 的两大关键特性 ——异步通信和全双工,决定了其传输方式和适用场景:
- 异步通信:无需时钟信号,发送端和接收端通过预设的 “波特率” 和 “帧结构” 保持时序一致。为避免数据错位,UART 会在每个数据帧的开头和结尾添加 “起始位” 和 “停止位”,用于标记数据的开始和结束(后续 “帧结构” 部分会详细拆解);
- 全双工:通过两根独立的信号线(TX 发送、RX 接收)实现 “同时收发”。例如,MCU 的 TX 连接传感器的 RX,MCU 的 RX 连接传感器的 TX,二者可在同一时间向对方发送数据,无需等待对方响应,传输效率高于半双工(如 RS-485 的半双工模式需分时收发)。
1.3 与其他串行通信协议的定位差异
在串行通信体系中,UART 并非唯一选择,需与 I2C、SPI、RS-485 等协议区分,明确其适用边界:
| 协议 | 通信方式 | 信号线数量 | 核心优势 | 适用场景 |
|---|---|---|---|---|
| UART | 异步全双工 | 2(TX/RX) | 结构简单、易实现 | 短距离点对点通信(如调试、传感器) |
| I2C | 同步半双工 | 2(SDA/SCL) | 多主多从、布线少 | 芯片间短距离通信(如 OLED、EEPROM) |
| SPI | 同步全双工 | 4(SCK/MOSI/MISO/CS) | 速率高、抗干扰强 | 高速外设(如 SD 卡、LCD) |
| RS-485 | 异步半双工 | 2(A/B) | 长距离、多节点、抗干扰强 | 工业组网(如 PLC、变频器) |
需注意:RS-485 并非独立于 UART 的协议,而是一种 “电平标准 + 总线结构”,其底层仍基于 UART 的帧结构,仅通过差分信号转换实现长距离传输(后续 “硬件接口” 部分会详细说明)。
二、UART 工作原理:从信号传输到帧结构解析
UART 的核心功能是 “将并行数据转换为串行数据发送,再将接收的串行数据转换为并行数据”,整个过程依赖时序同步和帧结构定义实现可靠传输。要掌握其原理,需从 “信号电平”“波特率同步”“帧结构拆解” 三个核心环节入手。
2.1 信号电平:TTL 与 RS-232 的差异
UART 的信号电平并非固定,需根据传输距离和场景选择,最常见的两种电平标准是TTL 电平和RS-232 电平,二者的差异直接影响传输距离和抗干扰能力:
-
TTL 电平(Transistor-Transistor Logic):
- 逻辑 1(高电平):3.3V 或 5V(取决于 MCU 供电电压,如 3.3V MCU 的 TTL 高电平为 3.3V,5V MCU 为 5V);
- 逻辑 0(低电平):0V;
- 传输距离:短距离(通常≤10 米),因电平幅值小,易受噪声干扰;
- 适用场景:板内或近距离设备通信(如 MCU 与板载传感器、蓝牙模块)。
-
RS-232 电平(EIA RS-232):
- 逻辑 1(MARK):-3V~-15V;
- 逻辑 0(SPACE):+3V~+15V;
- 传输距离:中短距离(通常≤15 米),差分电平(正负电压)抗干扰能力优于 TTL;
- 适用场景:PC 与外设通信(如早期 Modem、串口调试),需通过电平转换芯片(如 MAX232)将 MCU 的 TTL 电平转换为 RS-232 电平。
2.2 波特率:时序同步的核心
异步通信无时钟信号,发送端与接收端的时序同步依赖波特率(Baud Rate) —— 即 “单位时间内传输的码元数”,在 UART 中通常等同于 “每秒传输的二进制位数(bps,Bits Per Second)”。
2.2.1 常见波特率与选择原则
UART 支持多种标准波特率,需确保发送端与接收端的波特率完全一致,否则会导致数据错乱。常见波特率及适用场景如下:
- 9600 bps:最通用,适用于低速数据传输(如温湿度传感器、简单指令交互),抗干扰能力强;
- 19200 bps / 38400 bps:中速场景,平衡速率与稳定性;
- 115200 bps:高速场景(如 GPS 模块、日志输出),是调试常用波特率;
- 256000 bps / 1Mbps:超高速场景(需硬件支持),仅适用于短距离(如板内通信),易受干扰。
2.2.2 波特率误差的影响
实际应用中,波特率由 MCU 的系统时钟分频生成,可能存在微小误差(如理论 9600 bps,实际 9580 bps)。通常要求误差≤2%,否则会导致接收端采样错误:
- 误差来源:系统时钟精度(如外部晶振误差)、分频系数计算偏差;
- 后果:若误差过大,接收端可能将 “逻辑 1” 误判为 “逻辑 0”,导致数据错误或丢失;
- 解决方式:选择高精度晶振(如 25MHz±10ppm),或通过 MCU 的波特率发生器寄存器(如 STM32 的 USART_BRR)精确配置分频系数。
2.3 帧结构:数据传输的 “格式规范”
UART 通过 “帧(Frame)” 作为数据传输的基本单位,每个帧包含 “起始位、数据位、校验位、停止位” 四部分,格式可通过软件配置,确保发送端与接收端一致。标准帧结构如下(以 “1 个起始位 + 8 个数据位 + 1 个偶校验位 + 1 个停止位” 为例):
2.3.1 各字段的功能与配置
-
起始位(Start Bit):
- 固定为 1 位,逻辑 0(低电平);
- 作用:标记数据帧的开始,触发接收端同步 —— 接收端检测到 “空闲电平(逻辑 1)→ 低电平” 的跳变时,开始准备采样后续数据。
-
数据位(Data Bits):
- 可配置为 5~9 位,最常用 8 位(1 字节);
- 传输顺序:低位在前(LSB First),即先传输数据的最低位,再传输高位(如数据 0x55=01010101,传输顺序为 1→0→1→0→1→0→1→0);
- 作用:承载实际传输的数据(如传感器数值、控制指令)。
-
校验位(Parity Bit):
- 可配置为 “无校验(None)、奇校验(Odd)、偶校验(Even)、强制 1(Mark)、强制 0(Space)”,最常用 “无校验” 或 “偶校验”;
- 作用:检测传输过程中的单比特错误(无法纠正错误,仅能提示);
- 计算规则:
- 偶校验:数据位中 “1” 的个数为偶数,校验位补 0;若为奇数,校验位补 1;
- 奇校验:数据位中 “1” 的个数为奇数,校验位补 0;若为偶数,校验位补 1。
-
停止位(Stop Bit):
- 可配置为 1 位、1.5 位或 2 位,最常用 1 位;
- 固定为逻辑 1(高电平);
- 作用:标记数据帧的结束,给接收端留出 “恢复时间”,避免与下一个帧的起始位混淆。
2.3.2 帧传输时序示例
以 “波特率 9600 bps、8 数据位、1 偶校验位、1 停止位” 为例,传输数据 0x55(二进制 01010101)的时序如下:
- 空闲状态:TX 线为高电平(逻辑 1);
- 起始位:TX 线变为低电平(逻辑 0),持续 1/9600 ≈ 104μs;
- 数据位:依次传输 0x55 的 8 位数据(低位在前),每位移位持续 104μs;
- 校验位:0x55 的 8 位数据中 “1” 的个数为 4(偶数),故校验位为 0,持续 104μs;
- 停止位:TX 线变为高电平(逻辑 1),持续 104μs;
- 回到空闲状态,等待下一个帧传输。
三、UART 硬件组成:从控制器到接口电路
UART 的硬件实现需包含 “UART 控制器”“电平转换电路”“接口连接器” 三部分,不同场景的硬件设计差异主要体现在电平转换和连接方式上。
3.1 UART 控制器:数据处理的核心
UART 控制器通常集成在 MCU 内部(如 STM32 的 USART 外设、51 单片机的 UART 模块),负责 “并行数据与串行数据的转换”“帧结构生成与解析”“波特率控制” 等核心功能。其内部结构可拆解为以下子模块:
3.1.1 发送器(Transmitter)
- 接收 MCU 内核发送的并行数据(如从 CPU 寄存器或内存读取的数据);
- 根据配置的帧结构(数据位、校验位、停止位),生成串行数据帧;
- 通过 TX 引脚将串行数据发送出去;
- 包含 “发送缓冲区(TX Buffer)”:若 MCU 内核发送数据过快,数据可暂存于缓冲区,避免丢失(多数 MCU 的发送缓冲区为 1 字节,需通过中断或 DMA 避免溢出)。
3.1.2 接收器(Receiver)
- 通过 RX 引脚接收外部的串行数据;
- 解析串行数据帧,提取数据位,校验传输错误(如校验位不匹配则标记错误);
- 将解析后的并行数据送入 MCU 内核(如写入 CPU 寄存器或内存);
- 包含 “接收缓冲区(RX Buffer)”:若 MCU 内核读取数据过慢,数据可暂存于缓冲区(1 字节或多字节,如 STM32 的 USART 支持多字节 DMA 接收),避免新数据覆盖旧数据。
3.1.3 波特率发生器(Baud Rate Generator)
- 由 MCU 的系统时钟(如 HSI、HSE 晶振时钟)分频得到,生成与目标波特率匹配的时钟信号;
- 核心是 “分频器”:通过配置寄存器(如 STM32 的 USART_BRR)设置分频系数,计算公式为:分频系数 = 系统时钟频率 / (波特率 × 16)(异步模式下通常为 16 倍采样);
- 示例:若 STM32 的系统时钟为 72MHz,目标波特率为 115200 bps,则分频系数 = 72000000/(115200×16)=39.0625,对应 USART_BRR 寄存器值为 0x271(十六进制)。
3.1.4 控制与状态模块
- 控制模块:接收 MCU 内核的配置指令(如波特率、帧结构、中断使能);
- 状态模块:提供传输状态标志(如发送缓冲区空 TXE、发送完成 TC、接收缓冲区非空 RXNE、校验错误 PE),MCU 可通过查询标志位或触发中断实现数据收发。
3.2 电平转换电路:适配不同电平标准
如前文所述,UART 的信号电平分为 TTL 和 RS-232,若发送端与接收端电平标准不同,需通过 “电平转换芯片” 实现兼容。以下是两种典型场景的电路设计:
3.2.1 TTL→RS-232:MAX232 芯片应用
当 MCU(TTL 电平)需与 PC(RS-232 电平,如 DB9 串口)通信时,需使用 MAX232 芯片(双路 RS-232 发送 / 接收芯片),电路原理如下:
- 供电:MAX232 需 5V 供电(部分型号支持 3.3V,如 MAX3232);
- 电容:需外接 4 个 1μF 的电解电容(用于电荷泵,将 5V 转换为 ±15V 的 RS-232 电平);
- 引脚连接:
- MCU 的 TX(TTL)→ MAX232 的 T1IN(发送输入);
- MAX232 的 T1OUT(RS-232 发送)→ PC DB9 的 RX(引脚 2);
- PC DB9 的 TX(引脚 3)→ MAX232 的 R1IN(RS-232 接收);
- MAX232 的 R1OUT(TTL 接收)→ MCU 的 RX;
- PC DB9 的 GND(引脚 5)→ MCU 的 GND(共地是通信可靠的前提)。
3.2.2 TTL→RS-485:MAX485 芯片应用
RS-485 是一种差分传输的电平标准,支持多节点(最多 32 个)、长距离(≤1200 米)通信,底层基于 UART 帧结构,需通过 MAX485 芯片(半双工 RS-485 收发器)实现 TTL 与 RS-485 的转换:
- 供电:3.3V 或 5V(与 MCU 匹配);
- 控制引脚:MAX485 的 DE(驱动使能)和 RE(接收使能)需短接,由 MCU 的 IO 口控制(高电平为发送模式,低电平为接收模式);
- 引脚连接:
- MCU 的 TX → MAX485 的 DI(数据输入);
- MAX485 的 RO(数据输出)→ MCU 的 RX;
- MAX485 的 A(差分正)→ 总线 A 线;
- MAX485 的 B(差分负)→ 总线 B 线;
- 总线两端需接 120Ω 终端电阻(匹配阻抗,减少信号反射);
- 所有节点共地(避免共模干扰)。
3.3 接口连接器:设备连接的物理载体
UART 的物理接口根据场景不同分为多种类型,常见的有:
- 排针 / 排座:板载设备常用(如 MCU 开发板的 UART 调试接口,2Pin 或 4Pin,包含 TX、RX、VCC、GND);
- DB9 接口:PC 传统串口接口(9 针 D 型连接器),引脚定义如下:
DB9 引脚 功能 说明 1 DCD(载波检测) 仅 Modem 等设备使用 2 RXD(接收数据) 接外部设备的 TX 3 TXD(发送数据) 接外部设备的 RX 4 DTR(数据终端就绪) 仅 Modem 等设备使用 5 GND(地) 共地引脚(必须连接) 6 DSR(数据设备就绪) 仅 Modem 等设备使用 7 RTS(请求发送) 流控制引脚(可选) 8 CTS(清除发送) 流控制引脚(可选) 9 RI(振铃指示) 仅 Modem 等设备使用 注:UART 通信仅需连接 2(RX)、3(TX)、5(GND)三根引脚,其他引脚为流控制或 Modem 专用,多数场景无需连接。 - Micro USB/Type-C:现代设备常用(如 USB 转 TTL 模块),通过 USB 芯片(如 CH340、PL2303)将 USB 信号转换为 UART 信号,外部仅需连接 TX、RX、GND(VCC 可选,用于给外设供电)。
四、UART 软件实现:从驱动开发到协议封装
UART 的软件实现需分 “底层驱动” 和 “应用层协议” 两层:底层驱动负责控制硬件(如初始化、数据收发),应用层协议负责解决 “数据识别” 问题(如避免粘包、丢包)。以下以 STM32 为例,详解软件实现流程。
4.1 底层驱动开发:基于 HAL 库的实现
STM32 的 HAL 库(Hardware Abstraction Layer)提供了 UART 的标准化 API,无需直接操作寄存器,降低开发难度。驱动开发主要包含 “初始化配置”“数据发送”“数据接收” 三部分。
4.1.1 UART 初始化配置
初始化的核心是配置 “时钟、波特率、帧结构、中断 / DMA”,步骤如下:
-
使能时钟:
- 使能 UART 外设时钟(如 USART1 挂载在 APB2 总线上,需调用
__HAL_RCC_USART1_CLK_ENABLE()); - 使能 TX/RX 引脚对应的 GPIO 时钟(如 USART1 的 TX 为 PA9,RX 为 PA10,需调用
__HAL_RCC_GPIOA_CLK_ENABLE())。
- 使能 UART 外设时钟(如 USART1 挂载在 APB2 总线上,需调用
-
配置 GPIO 引脚:
- TX 引脚:配置为 “复用推挽输出”(GPIO_Mode_AF_PP),速度为高速(GPIO_Speed_High);
- RX 引脚:配置为 “浮空输入”(GPIO_Mode_IN_FLOATING)或 “上拉输入”(GPIO_Mode_IPU,避免悬空噪声);
- 示例(USART1 PA9/TX、PA10/RX):
c
运行
GPIO_InitTypeDef GPIO_InitStruct = {0}; // TX引脚配置 GPIO_InitStruct.Pin = GPIO_PIN_9; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); // RX引脚配置 GPIO_InitStruct.Pin = GPIO_PIN_10; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
-
配置 UART 参数:
- 波特率:如 115200 bps;
- 数据位:8 位(UART_WordLength_8b);
- 停止位:1 位(UART_StopBits_1);
- 校验位:无校验(UART_Parity_None);
- 模式:收发模式(UART_Mode_Tx | UART_Mode_Rx);
- 示例:
c
运行
UART_HandleTypeDef huart1; huart1.Instance = USART1; huart1.Init.BaudRate = 115200; huart1.Init.WordLength = UART_WORDLENGTH_8B; huart1.Init.StopBits = UART_STOPBITS_1; huart1.Init.Parity = UART_PARITY_NONE; huart1.Init.Mode = UART_MODE_TX_RX; huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; // 无硬件流控制 huart1.Init.OverSampling = UART_OVERSAMPLING_16; // 16倍采样 if (HAL_UART_Init(&huart1) != HAL_OK) { Error_Handler(); // 初始化失败处理 }
-
使能中断(可选):
- 若采用 “中断方式” 收发数据,需使能对应的中断(如接收非空中断 RXNE、发送完成中断 TC),并配置 NVIC(嵌套向量中断控制器);
- 示例(使能 USART1 接收中断):
c
运行
HAL_NVIC_EnableIRQ(USART1_IRQn); // 使能USART1中断 HAL_NVIC_SetPriority(USART1_IRQn, 0, 0); // 设置中断优先级 __HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE); // 使能接收非空中断
4.1.2 数据发送:查询、中断、DMA 三种方式
UART 数据发送有三种实现方式,需根据传输量和实时性需求选择:
-
查询方式(轮询):
- 原理:通过查询 “发送缓冲区空(TXE)” 标志位,等待缓冲区为空后发送数据;
- 优点:代码简单,无需中断配置;
- 缺点:占用 CPU 资源,发送过程中 CPU 无法执行其他任务;
- 适用场景:少量数据发送(如单字节指令);
- HAL 库 API:
HAL_UART_Transmit(&huart1, tx_buf, tx_len, timeout);(tx_buf:发送数据缓冲区,tx_len:数据长度,timeout:超时时间,单位 ms)。
-
中断方式:
- 原理:发送缓冲区为空时触发 “TXE 中断”,在中断服务函数中发送下一个字节,直到所有数据发送完成;
- 优点:不占用 CPU,实时性高;
- 缺点:代码复杂,需处理中断服务函数;
- 适用场景:中量数据发送(如多字节传感器数据);
- 实现步骤:① 使能 TXE 中断(
__HAL_UART_ENABLE_IT(&huart1, UART_IT_TXE););② 在中断服务函数(如 USART1_IRQHandler)中判断中断类型,发送数据;③ 所有数据发送完成后,关闭 TXE 中断,使能 “发送完成中断(TC)”,通知应用层发送完成。
-
DMA 方式(直接内存访问):
- 原理:通过 DMA 控制器直接将内存中的数据传输到 UART 发送缓冲区,无需 CPU 干预;
- 优点:完全不占用 CPU,适合大量数据发送(如日志、文件);
- 缺点:需配置 DMA 通道,代码复杂度高;
- 适用场景:大量数据高速传输(如 GPS 模块连续输出定位数据);
- HAL 库 API:
HAL_UART_Transmit_DMA(&huart1, tx_buf, tx_len);(发送完成后会触发 DMA 中断,可在回调函数HAL_UART_TxCpltCallback()中处理后续逻辑)。
4.1.3 数据接收:同样支持三种方式
数据接收与发送逻辑类似,核心是及时读取接收缓冲区的数据,避免溢出:
-
查询方式:
- 原理:查询 “接收缓冲区非空(RXNE)” 标志位,有数据则读取;
- 缺点:CPU 需持续轮询,实时性差,易丢失数据(若数据到来时 CPU 未查询);
- HAL 库 API:
HAL_UART_Receive(&huart1, rx_buf, rx_len, timeout);。
-
中断方式:
- 原理:接收缓冲区有数据时触发 “RXNE 中断”,在中断服务函数中读取数据;
- 优点:实时性高,数据到来时立即处理;
- 注意:需设置接收缓冲区(如环形缓冲区),避免中断频繁触发导致数据覆盖;
- 示例(中断服务函数中读取数据):
c
运行
void USART1_IRQHandler(void) { uint8_t rx_data; if (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_RXNE) != RESET) // 接收非空 { rx_data = (uint8_t)(huart1.Instance->DR & 0x00FF); // 读取1字节数据 ring_buf_put(&rx_ring_buf, rx_data); // 存入环形缓冲区 __HAL_UART_CLEAR_FLAG(&huart1, UART_FLAG_RXNE); // 清除标志位 } }
-
DMA 方式:
- 原理:DMA 控制器直接将 UART 接收缓冲区的数据传输到内存,支持 “单次传输” 或 “循环传输”;
- 适用场景:大量连续数据接收(如蓝牙模块接收文件);
- HAL 库 API:
HAL_UART_Receive_DMA(&huart1, rx_buf, rx_len);(接收完成后触发 DMA 中断,回调函数HAL_UART_RxCpltCallback()中处理数据)。
4.2 应用层协议:解决数据识别问题
UART 本身是 “透明传输” 协议,仅负责发送二进制数据,不区分 “数据边界”—— 若连续发送多帧数据,接收端可能无法判断 “哪部分是第一帧,哪部分是第二帧”,即 “粘包问题”;若数据丢失,接收端也无法察觉。因此,需在应用层设计协议,实现 “帧识别” 和 “错误检测”。
4.2.1 常用应用层协议:帧头 + 帧尾 + 长度 + 校验
最通用的协议格式为:帧头1 + 帧头2 + 数据长度 + 数据内容 + 校验和 + 帧尾,各字段功能如下:
- 帧头(2 字节):固定值(如 0xAA、0x55),用于标记帧的开始,接收端通过检测帧头锁定数据起始位置;
- 数据长度(1 字节):表示 “数据内容” 的字节数,用于确定数据的结束位置,避免粘包;
- 数据内容(N 字节):实际传输的业务数据(如传感器数值、控制指令);
- 校验和(1 字节):对 “数据长度 + 数据内容” 的所有字节求和,取低 8 位,用于检测数据传输错误;
- 帧尾(1 字节):固定值(如 0xEE),用于标记帧的结束,辅助验证帧的完整性。
示例:传输 “温度 25℃(0x19)、湿度 60%(0x3C)” 的协议帧:
| 字段 | 数值 | 说明 |
|---|---|---|
| 帧头 1 | 0xAA | 固定帧头 |
| 帧头 2 | 0x55 | 固定帧头 |
| 数据长度 | 0x02 | 数据内容为 2 字节 |
| 数据内容 | 0x19 | 温度 25℃ |
| 0x3C | 湿度 60% | |
| 校验和 | 0x02+0x19+0x3C=0x57 | 求和后低 8 位 |
| 帧尾 | 0xEE | 固定帧尾 |
| 完整帧 | 0xAA 0x55 0x02 0x19 0x3C 0x57 0xEE | 共 7 字节 |
4.2.2 协议解析流程(接收端)
接收端需按照以下步骤解析数据,确保正确识别帧并检测错误:
- 帧头检测:持续读取数据,直到检测到连续的 “帧头 1 + 帧头 2”(如 0xAA followed by 0x55),若未检测到则丢弃当前数据;
- 读取数据长度:帧头后读取 1 字节数据长度(如 0x02),确定后续 “数据内容” 的字节数;
- 读取数据内容:根据数据长度读取 N 字节数据(如 2 字节:0x19、0x3C);
- 校验和验证:计算 “数据长度 + 数据内容” 的校验和,与接收的 “校验和” 字段对比,若不一致则丢弃该帧(视为传输错误);
- 帧尾检测:读取最后 1 字节,验证是否为帧尾(如 0xEE),若不是则丢弃该帧;
- 数据处理:校验通过后,提取 “数据内容” 并交给业务层处理(如显示温度、湿度)。
4.2.3 工业标准协议:Modbus RTU
在工业控制场景中,常用Modbus RTU 协议(基于 UART)实现多设备通信,其本质是标准化的应用层协议,格式如下:
- 从站地址(1 字节):标识总线上的设备(1~247,0 为广播地址);
- 功能码(1 字节):表示操作类型(如 0x03 为 “读取保持寄存器”,0x06 为 “写入单个寄存器”);
- 数据(N 字节):业务数据(如寄存器地址、数据值);
- CRC 校验(2 字节):对 “从站地址 + 功能码 + 数据” 进行 16 位循环冗余校验,抗干扰能力强于简单校验和;
Modbus RTU 的优势在于 “标准化”,不同厂商的设备(如 PLC、传感器、变频器)只要支持 Modbus RTU,即可通过 UART 总线直接通信,无需自定义协议。
五、UART 性能指标与影响因素
UART 的通信性能由 “传输速率、传输距离、误码率” 三个核心指标决定,而这些指标又受硬件设计、环境干扰、软件配置等因素影响。掌握性能指标的优化方法,是确保 UART 通信可靠的关键。
5.1 核心性能指标
5.1.1 传输速率(波特率)
- 定义:每秒传输的二进制位数(bps);
- 理论上限:受 UART 控制器硬件和电平标准限制;
- TTL 电平:通常≤1Mbps(部分高性能 MCU 支持更高速率,如 STM32H7 支持 10Mbps);
- RS-232 电平:通常≤115200 bps(速率过高时,正负电平切换延迟导致信号失真);
- RS-485 电平:通常≤10Mbps(短距离),长距离(1200 米)时需降至 9600 bps;
- 实际限制:速率越高,抗干扰能力越弱,传输距离越短 —— 例如,115200 bps 的 TTL 通信距离通常≤5 米,而 9600 bps 可达到 10 米。
5.1.2 传输距离
- 定义:发送端与接收端之间的最大距离;
- 主要影响因素:电平标准(见下表);| 电平标准 | 最大传输距离(理想环境) | 实际应用距离 | 原因 ||----------|--------------------------|--------------|-----------------------|| TTL | ≤10 米 | 3~5 米 | 电平幅值小,易受干扰 || RS-232 | ≤15 米 | 5~10 米 | 差分电平,但幅值有限 || RS-485 | ≤1200 米 | 500~1000 米 | 差分传输,抗干扰强 |
- 其他影响因素:线缆质量(屏蔽线比非屏蔽线抗干扰强)、环境噪声(工业环境需缩短距离)、终端电阻(RS-485 需接 120Ω 电阻,否则信号反射缩短距离)。
5.1.3 误码率(BER)
- 定义:传输错误的比特数与总传输比特数的比值(如 10⁻⁶表示每传输 100 万比特,平均有 1 比特错误);
- 理想值:≤10⁻⁶(工业场景要求更高,需≤10⁻⁹);
- 影响因素:
- 噪声干扰:电磁干扰(如电机、继电器)导致电平跳变;
- 波特率误差:发送端与接收端波特率偏差超过 2%;
- 线缆损耗:长距离传输导致信号衰减,高低电平边界模糊;
- 校验方式:无校验的误码率高于偶校验(偶校验可检测单比特错误)。
5.2 关键影响因素与优化方法
5.2.1 电磁干扰(EMI):最常见的性能杀手
- 干扰来源:工业环境中的电机、变频器、开关电源,或消费电子中的 WiFi、蓝牙模块;
- 干扰后果:信号电平跳变,导致数据错误或丢失;
- 优化方法:
- 使用屏蔽线:将 UART 线缆(尤其是 TX/RX)穿过金属屏蔽层,屏蔽层一端接地;
- 采用双绞线:将 TX 和 RX 绞合(每米绞合 3~5 次),利用差分信号抵消共模干扰;
- 远离干扰源:UART 线缆与动力线(如 220V 电源线)保持≥30cm 距离;
- 电源滤波:在 MCU 和 UART 外设的电源端并联 0.1μF 陶瓷电容,滤除高频噪声。
5.2.2 接地问题:共地噪声导致电平偏移
- 问题本质:发送端与接收端的地电位不同(如共地电阻为 1Ω,电流 100mA 时,地电位差为 0.1V),导致接收端检测的电平偏移 —— 例如,MCU 的 TTL 高电平为 3.3V,若接收端地电位比发送端高 0.5V,接收端实际检测到的高电平仅为 2.8V,可能误判为低电平;
- 优化方法:
- 单点接地:所有 UART 设备的 GND 连接到同一点(如电源地),避免地环路;
- 加粗地线:使用≥22AWG 的导线作为地线,降低接地电阻;
- 隔离供电:若设备距离远,使用隔离电源(如 DC-DC 隔离模块),避免地电位差。
5.2.3 波特率与帧结构配置:匹配与优化
- 常见问题:发送端与接收端的波特率、数据位、校验位、停止位不一致,导致数据无法解析;
- 优化方法:
- 统一配置:确保所有设备的 UART 参数完全一致(如 9600 bps、8 数据位、1 停止位、无校验);
- 选择合适波特率:短距离、高实时性场景选 115200 bps,长距离、强干扰场景选 9600 bps;
- 启用校验位:工业环境或长距离传输时,启用偶校验,减少单比特错误导致的数据丢失。
六、UART 应用场景与典型案例
UART 凭借 “简单、可靠、低成本” 的优势,在各类电子设备中均有应用,以下是几个典型场景及实现方案。
6.1 嵌入式调试:串口日志输出
在 MCU 开发过程中,调试是核心环节,UART 是最常用的调试工具之一 —— 通过 UART 将 “日志信息”(如变量值、程序运行状态)输出到 PC,开发者可通过串口助手(如 SecureCRT、SSCOM、Putty)查看日志,定位问题。
6.1.1 实现方案(以 STM32 为例)
- 硬件连接:MCU 的 UART_TX(如 PA9)→ USB 转 TTL 模块的 RX,USB 转 TTL 模块的 USB 口→PC;
- 软件配置:UART 初始化为 115200 bps、8 数据位、1 停止位、无校验;
- 日志函数:编写
printf重定向函数,将printf输出的内容通过 UART 发送:c
运行
#include "stdio.h" // 重定向fputc函数,使printf通过USART1输出 int fputc(int ch, FILE *f) { HAL_UART_Transmit(&huart1, (uint8_t*)&ch, 1, 100); // 发送1字节 return ch; } // 调试时使用printf输出日志 void debug_log(void) { uint8_t temp = 25; printf("当前温度:%d℃\r\n", temp); // 日志输出到PC } - PC 端操作:打开串口助手,选择对应的 COM 口(如 COM3),配置相同的 UART 参数,点击 “打开” 即可查看日志。
6.2 传感器数据采集:温湿度传感器 SHT30
SHT30 是一款高精度温湿度传感器,支持 I2C 和 UART 两种通信方式,若采用 UART 接口,可直接与 MCU 通信,实现温湿度数据采集。
6.2.1 实现方案
- 硬件连接:SHT30 的 TX→MCU 的 RX(PA10),SHT30 的 RX→MCU 的 TX(PA9),SHT30 的 VCC→MCU 的 3.3V,GND→GND;
- 软件配置:
- UART 初始化:9600 bps、8 数据位、1 停止位、无校验;
- 指令发送:MCU 向 SHT30 发送 “读取数据” 指令(0x2C 0x06);
- 数据接收:SHT30 响应指令,返回 6 字节数据(温度高 8 位、温度低 8 位、温度 CRC、湿度高 8 位、湿度低 8 位、湿度 CRC);
- 数据解析:根据 SHT30 数据手册,温度计算公式为:温度(℃)= -45 + 175 × (温度高 8 位 <<8 | 温度低 8 位) / (2¹⁶ - 1)湿度计算公式为:湿度(% RH)= 0 + 100 × (湿度高 8 位 <<8 | 湿度低 8 位) / (2¹⁶ - 1);
- 数据处理:将解析后的温湿度通过 UART 输出到 PC,或显示在 OLED 屏上。
6.3 无线通信模块:蓝牙 HC-05 与 MCU 交互
HC-05 是一款通用蓝牙模块,支持 UART 接口,可实现 “MCU 与手机 / PC 的无线通信”—— 例如,手机通过蓝牙发送 “开灯” 指令,MCU 接收指令后控制 LED 点亮。
6.3.1 实现方案
- 硬件连接:HC-05 的 TX→MCU 的 RX(PA10),HC-05 的 RX→MCU 的 TX(PA9),HC-05 的 VCC→5V(部分型号支持 3.3V),GND→GND;
- 模块配置:通过 AT 指令配置 HC-05(如设置蓝牙名称为 “MCU_BT”,波特率为 9600 bps,角色为从机);
- 软件实现:
- UART 初始化:9600 bps、8 数据位、1 停止位、无校验,启用接收中断;
- 指令解析:在接收中断服务函数中读取 HC-05 发送的数据,若接收到 “ON”(开灯指令),则控制 LED 引脚输出高电平;若接收到 “OFF”(关灯指令),则输出低电平;
- 数据反馈:MCU 向 HC-05 发送 “LED 已开启” 或 “LED 已关闭” 的反馈信息,手机端通过蓝牙 APP(如 Serial Bluetooth Terminal)查看反馈。
6.4 工业控制:RS-485 总线组网
在工业场景中,需实现 “多台设备的长距离通信”(如 PLC 与 10 台传感器的组网),此时可采用 “UART+RS-485” 的方案,利用 RS-485 的差分传输和总线结构,实现抗干扰、长距离的多节点通信。
6.4.1 实现方案
- 硬件组成:
- 主设备:PLC(如西门子 S7-200),通过 UART+MAX485 芯片转换为 RS-485 电平;
- 从设备:10 台温湿度传感器(如 SHT30),每台传感器均配备 MAX485 芯片;
- 总线连接:所有设备的 MAX485 芯片的 A 端连接在一起,B 端连接在一起,总线两端接 120Ω 终端电阻;
- 通信协议:采用 Modbus RTU 协议,PLC 为主站,传感器为从站(地址 1~10);
- 软件实现:
- 主站(PLC):发送 Modbus RTU 指令(如地址 1、功能码 0x03、寄存器地址 0x0000、读取长度 0x0002),请求从站 1 的温湿度数据;
- 从站(传感器):接收指令后,解析地址和功能码,若地址匹配则读取温湿度数据,封装为 Modbus RTU 响应帧发送给主站;
- 数据处理:PLC 接收所有从站的响应数据,进行显示、存储或控制逻辑判断(如温度超过阈值时触发报警)。
七、UART 常见问题与排查方法
在 UART 通信调试中,常遇到 “收不到数据”“数据错乱”“数据丢包” 等问题,需按 “硬件→软件→协议” 的顺序逐步排查,定位根因。
7.1 问题 1:收不到数据
7.1.1 可能原因与排查步骤
-
硬件连接错误:
- 排查 TX/RX 是否交叉:发送端的 TX 必须接接收端的 RX,若接反(TX→TX、RX→RX),则无法传输数据;解决:重新核对接线(如 MCU_TX→传感器_RX,MCU_RX→传感器_TX);
- 线缆松动或断裂:用万用表测量线缆通断,确保 TX、RX、GND 均导通;解决:更换线缆或重新焊接;
- 未共地:发送端与接收端 GND 未连接,导致电平参考不一致;解决:确保所有设备 GND 可靠连接。
-
电平标准不匹配:
- 例如,MCU(TTL 3.3V)直接连接 PC 的 DB9 串口(RS-232 ±15V),未加 MAX232 电平转换;解决:添加电平转换芯片,或使用 USB 转 TTL 模块(将 PC 的 USB 转换为 TTL 电平)。
-
UART 参数不匹配:
- 发送端与接收端的波特率、数据位、校验位、停止位不一致;解决:统一所有设备的 UART 参数(如均设置为 9600 bps、8N1:8 数据位、无校验、1 停止位),可通过 “逐一排查法” 验证(如固定其他参数,仅更换波特率测试)。
-
设备未上电或硬件故障:
- 外设(如传感器、蓝牙模块)未接 VCC,或模块本身损坏;解决:用万用表测量外设 VCC 电压,确保供电正常;若供电正常仍无响应,更换模块测试。
7.2 问题 2:数据错乱(如接收端显示乱码)
7.2.1 可能原因与排查步骤
-
波特率不匹配或误差过大:
- 最常见原因,例如发送端 9600 bps,接收端 115200 bps;或发送端波特率误差超过 2%(如系统时钟为 72MHz,理论 9600 bps 的分频系数为 480,实际配置为 470);解决:统一波特率,或重新计算分频系数(如 STM32 通过 USART_BRR 寄存器精确配置),确保误差≤2%。
-
电磁干扰:
- 线缆靠近电机、电源等干扰源,导致信号失真;解决:更换为屏蔽线或双绞线,远离干扰源,或在电源端添加滤波电容。
-
数据位或校验位配置错误:
- 例如发送端 8 数据位,接收端 7 数据位;或发送端偶校验,接收端奇校验;解决:核对所有设备的帧结构配置,确保完全一致。
-
采样时钟不稳定:
- MCU 使用内部 RC 时钟(如 HSI),精度低(±1%),导致波特率不稳定;解决:更换为外部晶振(如 HSE 25MHz),提高时钟精度。
7.3 问题 3:数据丢包(接收端少收部分数据)
7.3.1 可能原因与排查步骤
-
接收端缓冲区溢出:
- 采用 “查询方式” 接收时,CPU 未及时读取接收缓冲区数据,新数据覆盖旧数据;或中断服务函数中未及时处理数据,导致缓冲区满溢;解决:改用 “中断方式” 或 “DMA 方式” 接收,或在查询方式中缩短轮询间隔;若用中断,可添加环形缓冲区(如大小 64 字节),暂存多字节数据。
-
传输距离过长或速率过高:
- TTL 电平传输超过 10 米,或波特率过高(如 1Mbps)导致信号衰减;解决:缩短传输距离,降低波特率(如从 115200 bps 降至 9600 bps),或改用 RS-485 电平。
-
总线冲突(RS-485 场景):
- 多台从设备同时向主设备发送数据,导致总线数据碰撞;解决:采用 “主从通信” 机制(仅主设备可主动发送指令,从设备仅在接收指令后响应),避免同时发送。
-
校验错误导致数据丢弃:
- 应用层协议启用校验和 / CRC 校验,传输错误导致接收端丢弃数据;解决:优化硬件抗干扰设计(如屏蔽线、滤波),或在应用层添加 “重发机制”(接收端校验错误时,向发送端请求重发)。
八、UART 的发展与替代技术
随着通信技术的发展,UART 面临 USB、I2C、SPI、CAN、以太网等技术的竞争,但因其 “简单、低成本” 的核心优势,在中低速、短距离场景中仍不可替代。以下是 UART 与替代技术的对比及发展趋势:
8.1 主要替代技术及适用场景
| 技术 | 优势 | 劣势 | 替代 UART 的场景 |
|---|---|---|---|
| USB | 速率高(USB 2.0 达 480Mbps)、支持热插拔、总线供电 | 协议复杂(需 USB 控制器)、成本高 | PC 外设(如 USB 转串口、打印机) |
| I2C | 仅需 2 根线、多主多从、布线少 | 速率低(≤1Mbps)、抗干扰弱 | 板内芯片间通信(如 OLED、EEPROM) |
| SPI | 速率高(≤100Mbps)、抗干扰强 | 需 4 根线、仅支持主从模式 | 高速外设(如 SD 卡、LCD、ADC) |
| CAN | 差分传输、抗干扰强、支持多节点 | 协议复杂(需 CAN 控制器)、成本高 | 汽车电子、工业控制(长距离多节点) |
| 以太网 | 速率高(千兆以太网)、长距离(≥100 米) | 需以太网控制器和 TCP/IP 协议栈 | 物联网设备(如智能家居网关) |
8.2 UART 的不可替代性与发展趋势
8.2.1 不可替代的核心场景
- 简单传感器通信:如温湿度传感器、光照传感器,数据量小(1~4 字节),无需高速传输,UART 的低成本和易实现性是最优选择;
- 嵌入式调试:串口日志输出仍是最通用的调试方式,无需额外硬件(仅需 USB 转 TTL 模块,成本≤5 元);
- legacy 设备兼容:大量老旧工业设备(如 PLC、变频器)仅支持 UART/RS-485 通信,需保留 UART 接口实现兼容。
8.2.2 发展趋势
- 集成化:MCU 集成更多 UART 外设(如 STM32H7 支持 8 个 USART),满足多设备同时通信需求;
- 高速化:部分高性能 MCU 支持更高波特率(如 10Mbps TTL UART),拓展高速短距离应用场景;
- 与无线技术结合:UART 与蓝牙(如 HC-05)、WiFi(如 ESP8266)、LoRa(如 SX1278)模块结合,实现 “有线转无线” 通信,拓展物联网应用;
- 低功耗优化:低功耗 MCU(如 STM32L4)的 UART 支持 “低功耗模式”,在休眠状态下仍可接收数据,适合电池供电设备(如无线传感器节点)。
九、总结
UART 作为一种经典的异步串行通信协议,历经数十年发展,仍在嵌入式系统、工业控制、智能硬件等领域发挥着不可替代的作用。其核心优势在于结构简单、成本低、易实现—— 仅需两根信号线即可实现全双工通信,无需复杂的时钟同步或协议栈;同时,通过与 RS-232、RS-485 等电平标准结合,可满足短距离、中长距离、抗干扰等不同场景的需求。
掌握 UART 的技术细节,需从 “硬件 + 软件 + 协议” 三个维度切入:硬件上理解控制器结构、电平转换电路和接口设计;软件上掌握驱动开发(初始化、收发方式)和应用层协议封装(解决粘包、丢包);实践中能排查常见问题(收不到数据、数据错乱、丢包),并根据场景选择最优的硬件配置和软件方案。
尽管 USB、CAN、以太网等技术在高速、长距离场景中逐渐替代 UART,但在简单传感器通信、嵌入式调试、legacy 设备兼容等场景中,UART 仍将长期保持其核心地位。对于电子工程师和嵌入式开发者而言,UART 是必须掌握的基础通信技术,也是深入理解其他复杂通信协议的重要基石。


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



