4. 串行通信基础
串行通信是工业控制与嵌入式系统中最基础、最广泛使用的通信方式。无论是调试单片机程序时使用的UART转USB,还是工厂现场长达千米的RS-485总线网络,其底层都遵循着串行数据传输的基本规律。本章将系统梳理串行通信的核心要素:从物理层的电气标准(RS-232/RS-485),到数据链路层的帧格式与校验机制,再到工程设计中必须掌握的波特率误差预算与接地策略。理解这些基础,是后续学习CAN、Modbus乃至工业以太网的前提。
上图展示了串行通信的三层视角:UART负责数据帧的组装与解析,物理层标准定义了电气信号如何在线缆上传输,而应用层协议则规定了字节流的业务含义。在实际工程中,这三者必须协同工作,任何一层的设计失误都会导致通信失败。
4.1 UART帧格式与波特率机制
4.1.1 核心原理:帧结构与时序
UART(Universal Asynchronous Receiver/Transmitter)是一种异步串行通信协议,所谓“异步”意味着收发双方不需要共享时钟信号,而是通过约定相同的波特率(Baud Rate)来保证位时序的同步。每一帧数据由以下部分组成:
- 起始位(Start Bit):1位逻辑0,表示一帧数据的开始,用于触发接收端的采样时钟同步。
- 数据位(Data Bits):通常为5~8位,常见配置为8位,低位先发送(LSB First)。
- 校验位(Parity Bit):可选,用于简单的错误检测。偶校验(Even)保证数据位+校验位中“1”的个数为偶数;奇校验(Odd)则保证为奇数。
- 停止位(Stop Bit):1位或2位逻辑1,表示一帧结束,为下一帧的起始位提供间隔。
典型的帧配置为“8-N-1”,即8个数据位、无校验、1个停止位。此时一帧共10位(1起始+8数据+1停止)。波特率表示每秒传输的码元(符号)数,单位是bps(bit per second)。例如9600bps意味着每比特持续约104.17μs。
4.1.2 判断方法:如何确定正确的帧格式
在调试串口通信时,如果出现乱码或数据错位,应按照以下步骤排查:
- 确认波特率:使用示波器测量TX引脚的波形,测量一个位的时间宽度,计算实际波特率。
- 确认帧格式:观察波形中起始位(下降沿)后的数据位个数,以及停止位的高电平持续时间。
- 检查校验设置:如果使能了校验位,但对端未使能,会导致数据字节错位。
- 验证逻辑电平:RS-232电平是负逻辑(-12V表示1,+12V表示0),而TTL电平是正逻辑(3.3V表示1,0V表示0)。
4.1.3 实战场景:MCU与PC串口调试
假设我们使用STM32F103的USART1与PC通过USB转TTL模块通信。硬件连接为:MCU的PA9(TX)接模块的RXD,PA10(RX)接模块的TXD,GND共地。初始化代码如下:
// 配置USART1为115200-8-N-1
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 115200;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART1, &USART_InitStructure);
USART_Cmd(USART1, ENABLE);
如果PC端串口助手设置为115200-8-N-1,但收到的数据为乱码,首先检查USB转TTL模块的驱动是否安装正确,其次用示波器测量MCU的TX引脚,确认波特率是否准确。若波形显示位宽为8.68μs(理论值8.68μs),则波特率正确;若位宽偏差超过0.2μs,则需检查晶振频率。
4.2 RS-232与RS-485物理层设计
4.2.1 核心原理:电气标准对比
RS-232和RS-485是两种最常用的串行物理层标准,它们的核心差异在于信号传输方式和驱动能力。RS-232采用单端传输,使用一根信号线相对于地线的电压差来表示逻辑状态,电压范围在±3V~±15V之间,逻辑1为-3V~-15V,逻辑0为+3V~+15V。这种方式的优点是简单,但抗干扰能力差,传输距离一般不超过15米。
RS-485采用差分传输,使用两根线(A和B)之间的电压差来表示逻辑状态。当A-B电压差在+2V~+6V时表示逻辑1,在-2V~-6V时表示逻辑0。差分信号具有共模抑制能力,因此传输距离可达1200米,且支持多点通信(最多32个节点,使用高阻抗接收器时可扩展到128个)。
| 参数 | RS-232 | RS-485 |
|---|---|---|
| 传输方式 | 单端(不平衡) | 差分(平衡) |
| 逻辑电平 | ±3V~±15V | A-B:±2V~±6V |
| 最大速率 | 115.2kbps(典型) | 10Mbps(短距离) |
| 最大距离 | 15m | 1200m(低速) |
| 节点数 | 点对点(1发1收) | 最多32~128节点 |
| 抗干扰能力 | 弱 | 强(共模抑制) |
| 典型应用 | PC串口、调试口 | 工业现场总线、Modbus |
4.2.2 操作流程:RS-485网络设计要点
设计一个RS-485总线网络时,需要遵循以下工程规范:
- 终端电阻匹配:在总线两端(最远节点)各并联一个120Ω电阻,用于吸收信号反射。如果网络节点少于2个且距离较短,可以省略。
- 偏置电阻:在总线空闲时,A-B电压差可能处于不确定区域(-200mV~+200mV),导致接收器误判。通常在A端上拉至5V(或3.3V),B端下拉至GND,提供约200mV的确定性偏置。
- 接地策略:RS-485虽然使用差分信号,但收发器的共模电压范围有限(通常为-7V~+12V)。如果各节点的地电位差过大,会超出共模范围。建议使用屏蔽双绞线,屏蔽层单点接地。
- 浪涌保护:在户外或工业环境中,应在A/B线上对地并联TVS管(如SMBJ6.0CA),并串联自恢复保险丝。
4.2.3 案例拆解:工厂环境下的RS-485总线故障排查
某自动化产线使用RS-485总线连接12台变频器,主站为PLC,通信协议为Modbus RTU,波特率9600bps。现场反馈通信时好时坏,尤其在变频器启动时通信中断。工程师现场排查过程如下:
- 初始现象:通信成功率约70%,变频器启动瞬间通信完全中断,停止后恢复。
- 关键测量:使用示波器测量A-B差分电压,发现变频器启动时总线噪声峰峰值达到4V,且波形出现明显振铃。
- 分析判断:变频器启动时产生强电磁干扰,通过电源线耦合到RS-485总线。同时,总线末端未安装终端电阻,导致信号反射加剧。
- 实际操作:①在总线两端各并联120Ω终端电阻;②将屏蔽层在PLC侧单点接地;③在每台变频器的RS-485接口处增加磁环(铁氧体扼流圈);④将总线远离变频器动力线(间距大于30cm)。
- 结果对比:整改后通信成功率提升至99.9%,变频器启动时不再中断。
- 复盘经验:RS-485的“抗干扰”是相对的,差分信号只能抑制共模干扰,对差模干扰(如振铃)仍需通过终端匹配和布线规范解决。
4.3 校验机制与错误处理
4.3.1 核心原理:奇偶校验与CRC
UART的奇偶校验只能检测奇数个比特错误,对于偶数个比特错误无能为力。在工业控制中,更可靠的做法是使用CRC(循环冗余校验)。CRC将数据帧视为一个多项式,通过模2除法计算余数作为校验码。常见的CRC-16(如Modbus使用的CRC-16/MODBUS)可以检测所有单比特错误、双比特错误以及所有奇数个错误,漏检率极低。
在UART层面,除了奇偶校验,接收端还会检测以下错误:
- 帧错误(FE):停止位不是高电平,说明帧边界错位。
- 溢出错误(OE):接收FIFO已满,新数据覆盖旧数据。
- 奇偶错误(PE):校验位与数据位不匹配。
4.3.2 判断方法:错误处理策略
在嵌入式软件中,UART中断服务程序应检查错误标志,并采取相应策略:
void USART1_IRQHandler(void) {
if (USART_GetITStatus(USART1, USART_IT_RXNE)) {
uint8_t data = USART_ReceiveData(USART1);
// 处理数据
}
if (USART_GetITStatus(USART1, USART_IT_FE)) {
// 帧错误:清除标志,丢弃数据
USART_ClearITPendingBit(USART1, USART_IT_FE);
}
if (USART_GetITStatus(USART1, USART_IT_ORE)) {
// 溢出错误:清除标志,重新初始化接收
USART_ClearITPendingBit(USART1, USART_IT_ORE);
}
}
对于Modbus RTU等协议,帧错误或CRC错误会导致整个报文被丢弃,主站会等待超时后重发。因此,从站程序必须实现超时管理,避免因半帧数据卡死通信。
4.3.3 实战场景:自定义协议中的校验设计
假设我们需要设计一个简单的传感器数据采集协议,帧格式为:帧头(0xAA)+ 地址(1字节)+ 数据长度(1字节)+ 数据(N字节)+ CRC16(2字节)。CRC16的计算范围从地址到数据结束。使用查表法实现CRC-16/MODBUS:
uint16_t crc16_modbus(uint8_t *buffer, uint16_t length) {
uint16_t crc = 0xFFFF;
for (uint16_t i = 0; i < length; i++) {
crc ^= buffer[i];
for (uint8_t j = 0; j < 8; j++) {
if (crc & 0x0001) {
crc = (crc >> 1) ^ 0xA001;
} else {
crc >>= 1;
}
}
}
return crc;
}
接收端计算CRC并与接收到的CRC字段比较,如果不一致则丢弃该帧。这种设计可以检测出传输过程中的任何比特翻转,适用于电磁环境复杂的工业现场。
4.4 物理层设计中的接地与隔离
4.4.1 核心原理:地环路与共模电压
当两个设备通过RS-232或RS-485连接时,如果它们分别使用不同的电源系统,地线之间可能存在电位差。这个电位差会导致地环路电流,轻则引起通信误码,重则烧毁接口芯片。解决方法是使用隔离器(如ADI的ADM2483或TI的ISO3082)将信号地与逻辑地隔离,隔离电压通常为2500Vrms。
对于RS-232,由于电平较高(±12V),地环路问题相对不敏感,但长距离传输时仍需注意。对于RS-485,共模电压范围是-7V~+12V,如果超出此范围,接收器可能损坏。
4.4.2 操作流程:隔离RS-485设计
一个典型的隔离RS-485节点包括:
- MCU的UART TX/RX信号经过数字隔离器(如ISO7721)隔离。
- 隔离后的信号连接到RS-485收发器(如ISO3082,内部集成隔离电源)。
- 隔离电源使用DC-DC模块(如B0505S)提供5V隔离电源。
- 总线侧A/B线连接TVS管和终端电阻。
这种设计可以彻底消除地环路,同时防止浪涌通过总线进入MCU系统。
4.4.3 案例拆解:跨建筑通信的接地问题
某污水处理厂的两个控制柜相距200米,使用RS-485连接。控制柜A的PLC与控制柜B的触摸屏通信,频繁出现数据错误。测量发现A柜与B柜的地电位差高达8V(A柜接地电阻较大)。解决方案:在B柜侧增加隔离型RS-485中继器(如PTC-232),将总线隔离为两段。改造后通信恢复正常,且后续雷击时未再损坏设备。
4.5 常见误区与工程复盘
| 误区 | 后果 | 正确做法 |
|---|---|---|
| RS-485总线不接终端电阻 | 信号反射,长线时误码 | 两端各并联120Ω电阻 |
| RS-232使用长线(>20m) | 信号衰减,数据错误 | 改用RS-485或加中继器 |
| 忽略地电位差 | 共模电压超限,烧毁芯片 | 使用隔离器或共地 |
| 波特率设置不一致 | 完全无法通信 | 统一配置并验证 |
| 只靠奇偶校验 | 多比特错误漏检 | 增加CRC16/32 |
| A/B线接反 | 逻辑反转,通信失败 | 用万用表测电压确认极性 |
在实际项目中,串行通信的故障往往不是单一原因,而是多个因素叠加。例如,波特率误差加上终端电阻缺失,可能导致偶发性通信中断。因此,建议在系统调试阶段使用示波器或逻辑分析仪记录总线波形,建立通信质量的基线数据。对于批量生产的设备,应在出厂前进行完整的通信压力测试(如持续24小时循环收发),确保物理层设计的可靠性。
最后需要强调的是,串行通信虽然“古老”,但它在工业控制中的地位不可替代。RS-485至今仍是Modbus、Profibus等主流现场总线的基础。掌握本章内容,意味着你能够独立设计、调试和排查基于串行通信的嵌入式系统,为后续学习更复杂的工业以太网协议打下坚实基础。