1. Modbus协议基础:起源、协议栈、串口与TCP、物理层与电气特性

各位工程师朋友,咱们今天聊聊Modbus。说实话,这协议年纪比我还大——1979年由Modicon公司推出,专为PLC通信设计。但你别看它老,工业现场里七八成的设备都靠它活着。我入行那会儿,第一个项目就是调试Modbus RTU网络,当时被接地问题折腾了三天,从那以后我对物理层就特别上心。

1.1 Modbus的起源:为什么它活到了现在?

Modbus诞生时,工业自动化还处于“各厂商自说自话”的年代。Modicon做了件聪明事:把协议规范完全公开。这招太狠了——任何厂家都能免费实现,于是它成了事实标准。我个人习惯把Modbus比作工业界的“通用语言”,虽然语法简单,但大家都听得懂。

你想想看,一个1979年的协议,到现在还在用,为什么?

  • 极简设计:帧结构就几个字节,单片机都能跑
  • 无状态通信:主站问,从站答,逻辑清晰
  • 硬件无关性:串口、TCP、甚至光纤都能跑

核心要点:Modbus的成功不在于技术多先进,而在于“够用且开放”。我在项目中遇到过客户非要上Profinet,结果现场传感器全是Modbus,最后还得加网关——何必呢?

1.2 协议栈结构:从物理层到应用层

Modbus的协议栈很薄,就三层。我画了张图,你一看就明白:

应用层 功能码 + 数据(如读线圈01、读寄存器03) 数据链路层 地址 + 功能码 + 数据 + CRC/LRC校验 物理层 RS-232 / RS-485 / TCP/IP 电气特性 PDU ADU 介质

说白了,Modbus的报文就两部分:PDU(协议数据单元)ADU(应用数据单元)。PDU是功能码+数据,ADU是在PDU外面套了个“信封”——串口加地址和校验,TCP加MBAP头。

我的经验:调试时如果报文解析不对,先看ADU层。串口模式下,地址字节错了整个帧就废了。我曾经花了两小时查一个从站不响应的问题,最后发现是从站地址拨码开关设成了0——Modbus规定地址1-247才有效。

1.3 串口 vs TCP:到底该选哪个?

很多新手会问:RTU、ASCII、TCP,我该用哪个?我直接给你对比表:

特性 Modbus RTU Modbus ASCII Modbus TCP
编码方式 二进制 ASCII字符 二进制
校验方式 CRC-16 LRC 无(依赖TCP)
传输效率 低(约2倍长度)
最大从站数 247 247 理论无限制
典型距离 1200米(RS-485) 1200米(RS-485) 100米(以太网)
适用场景 工业现场、抗干扰 老旧设备、调试 上位机、跨网段

我个人习惯:现场总线用RTU,上位机通信用TCP。RTU效率高,一个报文能读多个寄存器;ASCII现在基本淘汰了,除非你接的是上世纪的老古董。TCP的好处是不用管校验和地址,但延迟比串口大——实时控制慎用。

避坑指南:我曾经在一条RS-485总线上挂了32个从站,结果通信时断时续。排查后发现是终端电阻没加——RS-485要求在总线两端各加一个120Ω电阻。记住:没有终端电阻,信号反射会吃掉你的数据。

1.4 物理层与电气特性:别让硬件坑了你

物理层是Modbus最容易出问题的地方。我见过太多“软件调通了,一接硬件就崩”的案例。咱们重点说RS-485,因为它是工业现场的主力。

RS-485关键参数

  • 差分信号:A线(+)、B线(-),电压差>200mV为逻辑1
  • 共模电压:-7V ~ +12V,超出会烧芯片
  • 最大节点数:标准32个,加中继可扩展
  • 线缆要求:双绞屏蔽线,特性阻抗120Ω

嗯,这里要注意:屏蔽层单端接地。我见过有人两端都接地,结果形成地环路,通信直接瘫痪。正确的做法是:屏蔽层在控制器一端接地,另一端悬空。

RS-232 vs RS-485

RS-232是点对点,距离15米以内,适合调试。RS-485是多站总线,距离1200米,适合现场。你想想看,一个工厂几百米,用RS-232根本跑不了。

实战建议:设计多从站网络时,注意以下几点:

  1. 总线长度超过300米,用带隔离的收发器
  2. 每个从站地址唯一,不能重复
  3. 波特率不要盲目求高——9600bps比115200bps稳定得多
  4. 预留20%的带宽余量,别把总线跑满

1.5 一个典型的Modbus RTU报文实例

光说不练假把式,咱们看个实际报文。假设主站要读从站地址1的3个保持寄存器,起始地址0:

请求帧(主站→从站):
01 03 00 00 00 03 05 CB

字节解析:
01    → 从站地址
03    → 功能码(读保持寄存器)
00 00 → 起始地址(高字节在前)
00 03 → 寄存器数量(3个)
05 CB → CRC-16校验

响应帧(从站→主站):
01 03 06 00 01 00 02 00 03 4A 3B

字节解析:
01    → 从站地址
03    → 功能码
06    → 数据字节数(3个寄存器×2字节)
00 01 → 寄存器0的值 = 1
00 02 → 寄存器1的值 = 2
00 03 → 寄存器2的值 = 3
4A 3B → CRC-16校验

你看,就这么简单。但简单不等于容易——CRC算错、地址不对、字节顺序搞反,都是常见坑。我建议你调试时先用Modbus Poll这样的工具抓包,确认报文没问题再写代码。

小技巧:CRC-16的计算网上有现成代码,别自己手写。我当年就是自己写了个CRC函数,结果多项式搞反了,折腾一整天。直接用查表法,又快又准。

1.6 总结:Modbus基础的核心要点

好了,咱们把这一章的核心捋一捋:

  • Modbus是主从架构,一主多从,从站不能主动发数据
  • 协议栈分三层:应用层(功能码)、数据链路层(地址+校验)、物理层(电气特性)
  • 串口选RTU,TCP用于上位机,别混用
  • RS-485要加终端电阻、屏蔽层单端接地、地址不能重复

说实话,Modbus基础就这么点东西。但越是简单的东西,越容易在细节上翻车。下一章咱们会深入功能码和报文结构,到时候你会看到更多实战案例。


专注资料整理