从零搭建厂务数据采集:Modbus TCP与RTU通信调试 - 第2节

2.1 Modbus协议发展历史

Modbus协议由Modicon公司(现施耐德电气旗下)于1979年发明,最初用于可编程逻辑控制器(PLC)之间的通信。作为工业自动化领域最早开放的通信协议之一,Modbus经历了从串行总线到以太网的演进,至今仍是厂务数据采集系统中最广泛使用的协议。

2.1.1 关键发展里程碑

年份 事件 意义
1979 Modicon发布Modbus串行协议 首个公开、免授权的工业通信协议
1990s Modbus RTU/ASCII成为事实标准 RS-232/RS-485物理层广泛部署
1999 Modbus TCP/IP规范发布 基于以太网,端口502,与互联网技术融合
2004 Modbus组织移交至Modbus-IDA 标准化维护,推动互操作性认证
2007 Modbus成为国家标准GB/T 19582 中国工业自动化领域强制推荐标准
课程提示: 理解Modbus的历史有助于判断现场设备的通信能力。1990年代前的设备通常只支持Modbus RTU,2000年后的新设备普遍同时支持RTU和TCP。

2.2 物理层与协议栈

Modbus协议栈采用分层设计,物理层决定了信号的传输介质和电气特性,数据链路层定义了帧格式和差错校验,应用层则规定了功能码和数据模型。不同物理层对应不同的通信变体。

2.2.1 物理层对比

特性 Modbus RTU Modbus ASCII Modbus TCP
物理介质 RS-232 / RS-485 RS-232 / RS-485 以太网(RJ45)
最大距离 RS-232: 15m / RS-485: 1200m 同RTU 100m(交换机级联可扩展)
传输速率 9600~115200 bps 同RTU(但效率低) 10/100/1000 Mbps
节点数量 RS-485: 最多32节点(可中继扩展) 同RTU 理论上无限制(IP地址空间)
帧格式 二进制(8位数据位) ASCII字符(16进制可读) TCP/IP报文封装
校验方式 CRC-16(循环冗余校验) LRC(纵向冗余校验) TCP/IP协议栈校验
工程避坑: 在厂务数据采集项目中,Modbus RTU(RS-485)是最常见的物理层。注意RS-485总线必须使用双绞屏蔽线,并在两端加120Ω终端电阻,否则长距离通信会出现数据丢包或乱码。

2.2.2 协议栈分层模型

Modbus TCP/IP协议栈遵循OSI模型简化分层,Modbus RTU则直接映射到物理层和数据链路层。

协议栈对比:
  • Modbus TCP: 应用层(Modbus)→ 传输层(TCP)→ 网络层(IP)→ 链路层(以太网)
  • Modbus RTU: 应用层(Modbus)→ 数据链路层(RTU帧)→ 物理层(RS-485)
Modbus协议栈分层对比 Modbus TCP/IP 应用层:Modbus 应用协议 传输层:TCP(端口502) 网络层:IP 链路层:以太网(IEEE 802.3) 物理层:RJ45 / 双绞线 Modbus RTU 应用层:Modbus 应用协议 数据链路层:RTU帧 + CRC-16 物理层:RS-485 / RS-232 应用层相同 说明:Modbus TCP 复用 TCP/IP 协议栈的传输层校验,无需额外 CRC;Modbus RTU 在数据链路层自行实现 CRC-16 校验

2.3 主从架构与通信模型

Modbus采用严格的主从(Master/Slave)通信架构,在Modbus TCP中称为客户端/服务器(Client/Server)。整个网络中只有一个主站(Master/Client),其余均为从站(Slave/Server)。主站发起所有通信请求,从站只能响应,不能主动发送数据。

2.3.1 主从架构核心规则

  • 单主站原则: 同一时刻只能有一个主站设备,避免总线冲突。
  • 轮询机制: 主站依次向每个从站发送请求帧,从站回复响应帧。
  • 从站地址: 每个从站拥有唯一地址(1~247),地址0为广播地址。
  • 超时处理: 主站发送请求后启动定时器,若超时未收到响应则重试或报错。

2.3.2 通信模型对比

特性 Modbus RTU(串行) Modbus TCP(以太网)
主站角色 Master(通常为PLC、上位机) Client(通常为SCADA、边缘网关)
从站角色 Slave(传感器、执行器、仪表) Server(支持TCP的智能设备)
通信方式 半双工(RS-485)或全双工(RS-232) 全双工(以太网)
连接方式 总线型(所有设备挂接在同一对双绞线上) 星型(通过交换机连接)
地址标识 从站地址(1字节,1~247) IP地址 + 端口号(默认502)
并发能力 单线程轮询,一次只能与一个从站通信 多线程并发,可同时与多个服务器通信

2.3.3 通信流程示例

以下是一个典型的Modbus RTU读取保持寄存器的通信流程:

  1. 主站发送请求帧: 从站地址 + 功能码 + 起始地址 + 寄存器数量 + CRC校验
  2. 从站接收并解析: 校验地址匹配 → 校验CRC → 执行功能码操作
  3. 从站返回响应帧: 从站地址 + 功能码 + 数据字节数 + 数据 + CRC校验
  4. 主站校验响应: 校验CRC → 提取数据 → 更新数据库或界面
Python伪代码示例: 主站发送读取请求
import struct

# 构建Modbus RTU读取保持寄存器请求帧
slave_addr = 0x01          # 从站地址1
function_code = 0x03       # 读取保持寄存器
start_addr = 0x0064        # 起始地址100
quantity = 0x0002          # 读取2个寄存器

# 组装报文(不含CRC)
frame = struct.pack('>BBHH', slave_addr, function_code, start_addr, quantity)

# 计算CRC-16并追加
crc = calculate_crc16(frame)
frame += struct.pack('<H', crc)

# 通过串口发送
serial_port.write(frame)
Modbus主从通信模型(轮询流程) 主站(Master) PLC / 上位机 / 网关 从站1(地址01) 温度传感器 从站2(地址02) 压力变送器 从站3(地址03) 流量计 从站N(地址...) 其他设备 ① 请求帧(功能码+地址+数据) ② 响应帧(数据+CRC校验) 轮询下一站 轮询下一站 轮询下一站 主从通信关键规则 1. 主站发起所有通信,从站不能主动发送数据 2. 每个从站地址唯一,主站通过地址区分设备 3. 轮询周期 = 所有从站请求/响应时间之和 + 帧间隔

2.3.4 数据模型与地址空间

Modbus协议定义了四种基本数据对象类型,每种类型对应不同的功能码和地址范围。理解数据模型是正确配置采集点的前提。

数据对象 访问类型 数据大小 地址范围(PLC习惯) 常用功能码
线圈(Coil) 读写 1位(0/1) 00001~09999 01(读)、05(写单)、15(写多)
离散输入(Discrete Input) 只读 1位(0/1) 10001~19999 02(读)
输入寄存器(Input Register) 只读 16位(0~65535) 30001~39999 04(读)
保持寄存器(Holding Register) 读写 16位(0~65535) 40001~49999 03(读)、06(写单)、16(写多)
工程经验: 在厂务数据采集中,90%以上的数据点来自保持寄存器(Holding Register),例如温度、压力、流量、液位等模拟量。线圈(Coil)常用于控制阀门开关、电机启停等数字量输出。

2.3.5 功能码速查表

功能码 名称 操作对象 典型用途
01 (0x01) 读取线圈 线圈 读取DO状态
02 (0x02) 读取离散输入 离散输入 读取DI状态
03 (0x03) 读取保持寄存器 保持寄存器 读取AI/参数
04 (0x04) 读取输入寄存器 输入寄存器 读取AI
05 (0x05) 写单个线圈 线圈 控制DO
06 (0x06) 写单个寄存器 保持寄存器 设定参数
15 (0x0F) 写多个线圈 线圈 批量控制DO
16 (0x10) 写多个寄存器 保持寄存器 批量设定参数
常见误区: 初学者容易混淆“输入寄存器”和“保持寄存器”。输入寄存器只能读取(如传感器实时值),保持寄存器可读可写(如设定值、累计量)。在Modbus TCP中,地址偏移量(如40001)仅用于PLC习惯标识,实际报文中的地址从0开始。

2.4 本章小结

  • Modbus协议自1979年诞生,经历了从串行到以太网的演进,是厂务数据采集的基石。
  • 物理层选择直接影响通信距离、速率和抗干扰能力:RS-485适合长距离多节点,以太网适合高速大容量。
  • 主从架构是Modbus的核心通信模型,主站轮询、从站响应,地址唯一性至关重要。
  • 四种数据对象(线圈、离散输入、输入寄存器、保持寄存器)覆盖了数字量和模拟量的读写需求。
  • 功能码是操作指令,03/04读寄存器、06/16写寄存器是厂务采集最常用的功能码。