1. Modbus通讯基础:协议概述、RS-232/RS-485/RS-422区别、Modbus RTU与ASCII模式对比

各位同行,咱们今天聊聊Modbus通讯的基础。说实话,这玩意儿在工业现场太常见了,但很多人一开始就栽在基础概念上。我见过不少项目,通讯不稳定,查来查去,最后发现是协议模式选错了,或者物理接口搞混了。咱们先把地基打牢。

1.1 Modbus协议概述

Modbus,说白了就是一个“主-从”通讯协议。一个主站(通常是PLC、DCS或者工控机)问,多个从站(传感器、变频器、仪表)答。主站发指令,从站响应,就这么简单。

它为什么能活这么久?我琢磨着,就因为它够简单、够开放。你想想看,一个协议,公开透明,谁都能用,不用交钱,硬件成本也低。这在工业现场,简直就是“万金油”。

Modbus定义了三种数据访问方式:

  • 位访问:读写单个线圈(输出)或离散输入(输入)。比如控制一个继电器,或者读一个按钮状态。
  • 字访问:读写保持寄存器(可读可写)或输入寄存器(只读)。比如读一个温度值,或者写一个设定参数。
  • 诊断与特殊功能:比如读取从站设备信息、复位等。这些用得不多,但关键时刻能救命。
我的经验: 刚开始做项目时,我总喜欢把所有数据都塞到保持寄存器里。后来发现,有些只读数据(比如设备序列号)放在输入寄存器里更合理,还能避免误写。嗯,这里要注意,功能码别搞混了。

1.2 RS-232 / RS-485 / RS-422 区别

这三个物理层接口,是Modbus通讯的“腿”。腿不好,跑不快,还容易摔跤。我一个个说。

特性 RS-232 RS-485 RS-422
传输方式 单端(不平衡) 差分(平衡) 差分(平衡)
最大距离 约15米(50英尺) 约1200米(4000英尺) 约1200米
最大节点数 1对1(点对点) 最多32个(标准),可扩展 1发10收(典型)
信号线 TX, RX, GND(至少3线) A, B, GND(2线半双工) T+, T-, R+, R-, GND(4线全双工)
抗干扰能力
典型应用 短距离、低速、一对一 长距离、多节点、工业现场 长距离、全双工、高速

RS-232:老古董了。我最早接触PLC时就用它。距离短,速度慢,还容易受干扰。现在基本只用在调试口或者近距离设备连接上。你想想看,一根线拖15米,信号就衰减得不行了。

RS-485:这才是工业现场的主力。差分信号传输,抗干扰能力强。我做过一个项目,现场电机变频器一大堆,用RS-485走Modbus,愣是没出过通讯错误。记住,它通常是半双工的,就是说,同一时刻只能发或者收,不能同时进行。

RS-422:全双工,可以同时收发。但节点数有限,一般就1个主站对几个从站。我在一些老式的DCS系统里见过它,现在新项目里用得少了。不过,如果你需要高速、长距离、全双工,它还是个不错的选择。

避坑指南: 我曾经在一个项目里,把RS-485的A/B线接反了。结果通讯时断时续,查了半天。后来发现,A线接B线,B线接A线,信号就反了。记住,A线(通常标为D+或Data+)接A线,B线(D-或Data-)接B线。别搞混!

1.3 Modbus RTU 与 ASCII 模式对比

这两个是Modbus的两种报文格式。说白了,就是数据在线上怎么“说话”。

特性 Modbus RTU Modbus ASCII
数据表示 二进制(8位) ASCII字符(16进制)
报文长度 短(效率高) 长(约为RTU的2倍)
传输效率
错误校验 CRC(循环冗余校验) LRC(纵向冗余校验)
帧间隔 严格(3.5个字符时间) 宽松(1秒超时)
典型应用 绝大多数工业现场 调试、低速、噪声环境

Modbus RTU:这是主流。数据以二进制形式发送,效率高,速度快。我99%的项目都用它。但有个坑:它对帧间隔要求很严格。两个报文之间必须间隔至少3.5个字符时间。如果间隔太短,从站会认为是一个报文,导致解析错误。

Modbus ASCII:每个字节用两个ASCII字符表示。比如,0x1A就变成'1'和'A'两个字符。报文长度翻倍,效率低。但它有个好处:对时间间隔不敏感。在一些噪声大、时钟不准的环境里,ASCII模式反而更稳定。我曾在一些老旧的仪表上用过它,因为那些仪表的CPU太慢,处理不了RTU的严格时序。

我的建议: 除非你有特殊原因(比如设备只支持ASCII,或者现场噪声大到RTU无法工作),否则一律用RTU模式。效率高,兼容性好。ASCII模式,说白了,就是RTU的“备胎”。

最后,说个代码示例。这是Modbus RTU读取保持寄存器的报文格式:

// 主站请求(读取从站地址1,起始地址0,读取2个寄存器)
// 从站地址: 0x01
// 功能码: 0x03 (读取保持寄存器)
// 起始地址高字节: 0x00
// 起始地址低字节: 0x00
// 寄存器数量高字节: 0x00
// 寄存器数量低字节: 0x02
// CRC校验低字节: 0xC4
// CRC校验高字节: 0x0B

// 完整报文(16进制):
01 03 00 00 00 02 C4 0B

// 从站正常响应(返回4个字节数据:0x00 0x0A, 0x00 0x14)
// 从站地址: 0x01
// 功能码: 0x03
// 数据字节数: 0x04
// 数据1高字节: 0x00
// 数据1低字节: 0x0A (即10)
// 数据2高字节: 0x00
// 数据2低字节: 0x14 (即20)
// CRC校验低字节: 0xF8
// CRC校验高字节: 0x4D

// 完整响应报文:
01 03 04 00 0A 00 14 F8 4D

你看,RTU报文就这么简洁。ASCII模式下,同样的请求,报文会长得多,而且每个字节都要转成ASCII字符。效率差距一目了然。

好了,这一章就到这里。下一章咱们聊聊线缆选型,这可是个大学问。选错了线,通讯就等着哭吧。