1. UART基础概念与历史沿革
UART(Universal Asynchronous Receiver/Transmitter)是一种用于异步串行通信的硬件设备,它负责将并行数据转换为串行格式进行传输,同时也能将接收到的串行数据转换回并行格式。这种技术自计算机诞生初期就存在,最早可追溯到20世纪60年代DEC公司为PDP系列计算机设计的线路单元板。
在早期计算机系统中,UART通常作为独立芯片存在,比如著名的8250、16450系列。随着集成电路技术的发展,现代微控制器大多将UART作为内置外设集成在芯片内部。一个典型的例子是STM32系列MCU,它们通常包含多个USART(Universal Synchronous/Asynchronous Receiver/Transmitter)模块,既支持异步模式也支持同步模式。
关键点:UART通信是异步的,这意味着通信双方不需要共享时钟信号,而是依靠预先约定的波特率来实现同步。这种特性使得UART非常适合距离较短、布线简单的设备间通信。
2. UART工作原理深度解析
2.1 数据帧结构
UART通信的基本单位是"帧",每帧包含以下几个部分:
- 起始位(Start Bit):逻辑低电平,持续1个位时间,标志一帧数据的开始
- 数据位(Data Bits):5-9位有效数据,通常使用8位
- 校验位(Parity Bit,可选):用于简单的错误检测
- 停止位(Stop Bit):逻辑高电平,持续1-2个位时间,标志一帧数据的结束
典型的8N1配置(8位数据,无校验,1位停止位)的帧效率为80%,因为每10位中只有8位是有效数据。
2.2 发送与接收机制
发送端UART的工作流程:
- 从数据总线获取并行数据
- 添加起始位、校验位(如果启用)和停止位
- 按照设定的波特率将数据逐位移出到TX线上
接收端UART的工作流程:
- 检测起始位的下降沿
- 按照设定的波特率对RX线进行采样(通常在位周期的中点)
- 移入数据位,检查校验位(如果启用)
- 确认停止位
- 将有效数据提供给数据总线
2.3 波特率与时钟
UART通信的双方必须使用相同的波特率(每秒传输的位数)。常见的波特率有9600、19200、38400、115200等。由于是异步通信,UART通常使用16倍或8倍过采样来提高接收的可靠性。
波特率计算公式:
code复制波特率 = 主时钟频率 / (16 × 波特率分频值)
例如,使用16MHz时钟实现115200波特率:
code复制分频值 = 16,000,000 / (16 × 115200) ≈ 8.68 → 取整为9
实际波特率 = 16,000,000 / (16 × 9) ≈ 111,111 bps
可见,整数分频会引入误差,因此现代UART通常使用分数波特率发生器来减小误差。
3. UART硬件实现与配置
3.1 典型UART芯片
-
传统独立UART芯片:
- 16550:经典UART,带16字节FIFO
- 16C550:CMOS版本,功耗更低
- FT232R:USB转UART桥接芯片,广泛使用
-
现代微控制器内置UART:
- STM32 USART:支持多种模式
- ESP32 UART:支持高速通信
- S32K3 UART:汽车级MCU中的UART模块
3.2 寄存器配置
典型的UART寄存器包括:
- 波特率寄存器(DLL/DLH)
- 线路控制寄存器(LCR)
- FIFO控制寄存器(FCR)
- 中断使能寄存器(IER)
- 线路状态寄存器(LSR)
配置示例(设置115200波特率,8N1):
c复制// 设置波特率分频器
UART->DLL = 9; // 分频值低字节
UART->DLH = 0; // 分频值高字节
UART->LCR = 0x80; // 允许设置波特率
// 设置数据格式
UART->LCR = 0x03; // 8位数据,无校验,1位停止位
// 启用FIFO
UART->FCR = 0x01;
3.3 电平标准
UART通常使用以下电平标准:
- TTL电平:0V表示逻辑0,3.3V/5V表示逻辑1
- RS-232:±3V至±15V,负电压表示逻辑1
- RS-485:差分信号,支持长距离传输
注意:直接连接不同电平标准的UART会损坏设备,必须使用电平转换芯片如MAX232、SP3232等。
4. UART应用实践
4.1 设备连接与调试
UART常用于:
- 微控制器与PC通信
- 设备固件更新
- 系统调试输出
- 模块间通信(GPS、蓝牙、WiFi模块等)
典型连接方式:
code复制MCU.TX → RX of other device
MCU.RX ← TX of other device
GND ↔ GND
4.2 多设备连接
UART本质上是点对点通信协议,但可以通过以下方式实现多设备通信:
- 软件协议:为每个设备分配唯一地址
- 硬件切换:使用多路复用器选择通信对象
- RS-485总线:支持多达32个设备在同一总线上
4.3 常见问题排查
-
无通信:
- 检查TX/RX是否交叉连接
- 确认波特率设置一致
- 检查电平标准是否匹配
-
数据错误:
- 降低波特率测试
- 检查时钟精度(误差应<3%)
- 缩短线缆长度或使用屏蔽线
-
通信不稳定:
- 添加适当的终端电阻
- 确保共地良好
- 考虑使用差分信号(RS-485)
5. UART高级应用与优化
5.1 DMA应用
现代UART通常支持DMA,可大幅降低CPU开销。配置示例(STM32):
c复制// 配置UART DMA
hdma_usart_tx.Instance = DMA1_Channel4;
hdma_usart_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_usart_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart_tx.Init.Mode = DMA_NORMAL;
hdma_usart_tx.Init.Priority = DMA_PRIORITY_LOW;
HAL_DMA_Init(&hdma_usart_tx);
// 关联DMA到UART
__HAL_LINKDMA(&huart1, hdmatx, hdma_usart_tx);
// 启动DMA传输
HAL_UART_Transmit_DMA(&huart1, txBuffer, sizeof(txBuffer));
5.2 流量控制
硬件流控(RTS/CTS):
- RTS(Request To Send):发送方准备就绪
- CTS(Clear To Send):接收方准备就绪
软件流控(XON/XOFF):
- XON(0x11):恢复传输
- XOFF(0x13):暂停传输
5.3 错误处理
UART常见错误标志:
- 帧错误(FE):未检测到有效的停止位
- 噪声错误(NE):检测到线路噪声
- 溢出错误(OE):接收FIFO溢出
- 校验错误(PE):接收数据校验失败
处理策略:
c复制if(__HAL_UART_GET_FLAG(&huart1, UART_FLAG_PE)) {
__HAL_UART_CLEAR_FLAG(&huart1, UART_CLEAR_PEF);
// 处理校验错误
}
6. UART与其他串行协议对比
| 特性 | UART | SPI | I2C | USB |
|---|---|---|---|---|
| 通信方式 | 异步 | 同步 | 同步 | 异步/同步 |
| 线数 | 2+地线 | 3+片选 | 2 | 2(差分) |
| 最大速率 | 3-5Mbps | 50Mbps+ | 3.4Mbps | 480Mbps+ |
| 寻址方式 | 无 | 片选 | 7/10位地址 | 设备地址 |
| 硬件复杂度 | 低 | 中等 | 低 | 高 |
| 典型应用 | 调试接口 | 高速外设 | 传感器 | 外设连接 |
在实际项目中,UART因其简单可靠的特点,仍然是调试接口和低速设备通信的首选方案。对于需要更高速度或更复杂拓扑的场景,可以考虑SPI、I2C或USB等协议。
