串行通信与并行通信:从物理本质到工程选型
串口通信(UART)是嵌入式系统中最基础、最广泛使用的通信方式之一。要真正理解UART的工作原理,首先需要厘清通信领域的几个基本概念:串行与并行、同步与异步、单工/半双工/全双工。这些概念不仅是理论分类,更直接决定了硬件设计中的引脚数量、协议复杂度、传输速率上限以及驱动开发的逻辑模型。本章将从物理层信号传输的本质出发,逐一剖析这些概念,并结合实际工程场景说明其应用与取舍。
2.1 串行通信与并行通信:物理本质与工程取舍
核心原理
串行通信(Serial Communication)是指数据在一根数据线(或一对差分线)上按位(bit)依次传输的方式。发送端将并行数据转换为串行比特流,接收端再将比特流还原为并行数据。并行通信(Parallel Communication)则使用多根数据线同时传输多个比特,例如8位并行总线一次传输一个字节。
从信息论角度看,串行通信以时间换空间,并行通信以空间换时间。但工程实现中,并行通信并非简单地在更多线上复制串行逻辑——它还需要额外的同步时钟线、数据有效信号(如STB)、以及严格的布线等长要求。随着速率提升,并行总线的信号偏移(Skew)和串扰(Crosstalk)问题急剧恶化,这也是为什么现代高速接口(USB、PCIe、SATA)全部转向串行差分结构。
对比分析
| 维度 | 串行通信 | 并行通信 |
|---|---|---|
| 数据线数量 | 1根(或1对差分线) | 8/16/32根数据线+控制线 |
| 传输速率 | 单线速率高(可达Gbps级) | 总线速率受限于Skew(通常<500Mbps) |
| 抗干扰能力 | 强(差分串行更优) | 弱(多线间串扰严重) |
| 布线成本 | 低(节省PCB面积和连接器引脚) | 高(需等长布线、屏蔽) |
| 同步方式 | 异步(UART)或同步(SPI) | 通常需要独立时钟线 |
| 典型应用 | UART、SPI、I2C、USB、PCIe | 旧式打印机并口、SRAM接口、LCD并口 |
| 驱动开发复杂度 | 较低(协议简单) | 较高(时序约束严格) |
案例拆解:为什么MCU内部总线用并行,外部接口用串行?
以STM32F407为例,其内部AHB总线为32位并行,CPU与SRAM、Flash之间通过并行总线通信,单次访问可读写4字节,效率极高。但芯片对外提供的通信接口(UART、SPI、USB)几乎全部是串行。原因在于:芯片引脚数量有限(LQFP100封装仅100脚),若采用32位并行对外通信,仅数据线就占用32个引脚,加上地址线、控制线,引脚数将不可接受。而串行接口仅需2-4根线即可实现可靠通信,代价是传输速率略低,但通过提高单线时钟频率(如UART可达数Mbps,USB 3.0可达5Gbps)完全可以弥补。
从驱动开发角度看,MCU内部并行总线由硬件自动管理,驱动工程师无需干预;而外部串行接口则需要软件配置寄存器、管理波特率、处理中断和DMA。这正是本课程后续章节的重点内容。
2.2 同步通信与异步通信:时钟的博弈
核心原理
同步通信(Synchronous)要求发送端和接收端共享同一个时钟信号。发送端在时钟的上升沿(或下降沿)输出数据,接收端在相同的时钟沿采样数据。典型代表:SPI(SCLK线)、I2C(SCL线)。同步通信的时序关系简单,因为收发双方始终对齐,但代价是需要额外的时钟线,且时钟频率受限于传输距离和线间延迟。
异步通信(Asynchronous)不共享时钟线,收发双方各自使用独立的时钟源(通常是本地晶振分频得到的波特率时钟)。发送端在数据帧起始时先发送一个起始位(低电平),接收端检测到起始位后,按照约定的波特率(每秒传输的比特数)在每一位的中心点采样。UART就是最典型的异步通信协议。
判断方法:如何区分同步与异步?
- 看是否有独立的时钟线:有SCLK/SCL线则为同步;只有数据线(TX/RX)则为异步。
- 看协议帧格式:异步协议必有起始位和停止位(如UART帧:1起始位+5~8数据位+1校验位+1~2停止位);同步协议通常以字节为单位连续传输,无起始/停止位。
- 看波特率容错要求:异步通信要求收发双方波特率误差不超过±2%(通常±1%以内),否则采样点会偏移;同步通信无此限制。
实战场景:UART波特率误差计算
假设系统主频为16MHz,需要产生115200bps的波特率。使用标准UART波特率寄存器分频:
// 以STM32为例,USARTDIV = 16MHz / (115200 * 16) = 8.68
// 实际写入寄存器值为8,实际波特率 = 16MHz / (16 * 8) = 125000bps
// 误差 = (125000 - 115200) / 115200 = 8.5% → 超出容限,通信必然失败!
// 解决方案:改用8MHz晶振或使用分数波特率发生器(如STM32的USARTDIV支持小数部分)
这个案例说明,异步通信的波特率精度是驱动开发中必须验证的第一项参数。实际调试时,应使用示波器测量TX引脚的位宽,确认与理论值偏差在±2%以内。
2.3 单工、半双工与全双工:数据流向的三种模式
核心原理
这三种模式描述的是通信双方在数据流向上的能力:
- 单工(Simplex):数据只能沿一个方向传输。例如UART仅连接TXD到对方RXD,无反向通道。典型应用:传感器数据上报、LED状态指示。
- 半双工(Half-Duplex):双方都能发送和接收,但同一时刻只能有一个方向的数据传输。典型应用:RS-485总线(共享一对差分线,通过方向控制引脚切换收发状态)。
- 全双工(Full-Duplex):双方可同时发送和接收。UART标准模式即为全双工(独立TX和RX线),但需注意:若使用单根线(如RS-485),则退化为半双工。
工程判断:如何确定当前UART的工作模式?
| 判断依据 | 单工 | 半双工 | 全双工 |
|---|---|---|---|
| 物理连接 | 仅1根数据线(单向) | 1根数据线(双向分时) | 2根数据线(TX/RX独立) |
| 硬件资源 | 仅发送或仅接收 | 收发共用,需方向控制GPIO | 收发独立,可同时工作 |
| 驱动实现 | 只写或只读 | 需切换方向(如RS-485的DE/RE引脚) | 可同时读写,需处理并发 |
| 典型场景 | 红外遥控发射 | RS-485总线、LIN总线 | PC串口调试、蓝牙UART |
案例拆解:RS-485半双工通信的驱动陷阱
某工业控制项目使用RS-485总线连接1个主机和8个从机,波特率9600bps。从机采用UART+MAX3485芯片实现半双工通信。初始现象:主机发送查询指令后,从机无响应。分析过程:
- 用示波器测量从机RO引脚(UART RX),发现主机指令波形正常到达。
- 测量从机DI引脚(UART TX),发现从机有数据输出,但总线电平无变化。
- 检查MAX3485的DE/RE控制引脚,发现驱动代码中未将DE置高,导致发送数据未驱动到总线。
根因:半双工模式下,驱动必须在发送前将DE置高(使能发送),发送完成后立即将DE置低(恢复接收)。若使用中断发送,需在TXE(发送寄存器空)中断中切换方向,而非在TC(发送完成)中断中切换——因为TC中断时移位寄存器可能仍在输出最后一位。
修复方案:
// 伪代码示例
void UART_SendRS485(uint8_t* data, uint16_t len) {
DE_GPIO_HIGH(); // 使能发送
HAL_UART_Transmit(&huart, data, len, 100);
while (__HAL_UART_GET_FLAG(&huart, UART_FLAG_TC) == RESET); // 等待完全发送
DE_GPIO_LOW(); // 恢复接收
}
结果对比:修复后通信正常,误码率从100%降至0%。复盘经验:半双工通信的驱动核心是方向切换时序,必须在最后一个停止位完全移出后,才能关闭发送使能,否则会截断帧尾。
1. 正确配置波特率(误差<2%);
2. 管理数据帧格式(起始位/数据位/校验位/停止位);
3. 根据物理层选择单工/半双工/全双工模式,并实现相应的方向控制或并发处理逻辑。
后续章节将深入UART帧结构、寄存器配置和中断/DMA驱动设计。