好的阿杰 👍
下面我给你整理一份 Modbus 通信协议详解,涵盖背景、结构、常见功能码、通信方式、应用案例和注意事项,方便系统理解。
🔹 Modbus 通信协议详解
1. Modbus 简介
- 提出者:Modicon 公司(现为 Schneider 施耐德)1979 年发布,用于 PLC 与设备之间的通信。
- 协议层级:工作在 OSI 模型第七层(应用层)。
- 开放性:开源、无版权限制,已成为工业自动化中最常用的通信协议之一。
- 应用场景:PLC、DCS、智能仪表、传感器、变频器、远程 I/O、数据采集设备。
2. Modbus 协议类型
根据物理层/链路层不同,主要有三种:
- Modbus RTU
- 基于 RS-485/RS-232,总线型拓扑。
- 数据紧凑,传输效率高。
- 常见波特率:9600、19200、38400 bps。
- Modbus ASCII
- 同样基于串口通信(RS-232/485)。
- 数据帧以 ASCII 字符表示(可读性好,但效率低)。
- Modbus TCP/IP
- 基于以太网(TCP 502 端口)。
- 直接嵌入 TCP 报文,无需 CRC 校验(由 TCP 保证)。
- 适合远程监控和工业物联网 (IIoT)。
3. 数据模型
Modbus 采用寄存器-变量的抽象方式:
寄存器类型 | 访问方式 | 地址范围 | 数据长度 | 功能码 |
---|---|---|---|---|
线圈 Coils | 读/写 | 00001–09999 | 1 bit | 01/05/15 |
离散输入 Inputs | 只读 | 10001–19999 | 1 bit | 02 |
保持寄存器 Holding Regs | 读/写 | 40001–49999 | 16 bit | 03/06/16 |
输入寄存器 Input Regs | 只读 | 30001–39999 | 16 bit | 04 |
💡 地址编号与功能码有紧密对应关系。比如 40001 实际内部地址为 0,协议传输时常用 偏移地址。
4. 通信帧结构
4.1 RTU 帧结构
| 从站地址 | 功能码 | 数据区 | CRC16 校验 |
- 从站地址:1 字节(1–247,0 为广播)。
- 功能码:1 字节(如 03 代表读保持寄存器)。
- 数据区:N 字节(起始地址、寄存器数量、实际数据)。
- CRC16:2 字节,校验错误会丢弃该帧。
4.2 ASCII 帧结构
: 起始符 → 地址 → 功能码 → 数据区 → LRC 校验 → 回车换行
4.3 TCP/IP 帧结构
| 事务处理标识符 | 协议标识符 | 长度 | 单元标识符 | 功能码 | 数据区 |
- 无 CRC 校验,交由 TCP 处理。
5. 常见功能码
功能码 (Hex) | 含义 |
---|---|
01 | 读线圈状态 |
02 | 读离散输入状态 |
03 | 读保持寄存器 |
04 | 读输入寄存器 |
05 | 写单个线圈 |
06 | 写单个保持寄存器 |
0F (15) | 写多个线圈 |
10 (16) | 写多个保持寄存器 |
6. 通信流程
- 主站发起请求(Query):包含从站地址、功能码、数据区、校验。
- 从站响应(Response):返回数据或执行结果。
- 异常响应:若出错(非法功能码、寄存器不存在、写保护),从站返回 功能码 + 0x80 和错误码。
7. 应用举例
7.1 读取温度传感器(保持寄存器)
- 主站:
01 03 00 10 00 01 CRC
- 设备地址 01,功能码 03,起始寄存器 0x0010,数量 1。
- 从站响应:
01 03 02 00 1E CRC
- 返回寄存器值 0x001E (十进制 30℃)。
7.2 控制开关(写单个线圈)
- 主站:
02 05 00 00 FF 00 CRC
- 控制地址 0x0000 的线圈 ON。
- 从站响应:
02 05 00 00 FF 00 CRC
- 返回相同数据表示成功。
8. 优缺点
优点:
- 协议简单、开放、实现容易。
- 被广泛支持,跨厂商设备兼容性好。
- 适合小规模、实时性要求不高的应用。
缺点:
- 地址空间有限(16 bit)。
- 安全性不足(无加密、认证机制)。
- 实时性和带宽较低(尤其是 RTU)。
9. 工业实践注意事项
- RS-485 总线布线需采用 屏蔽双绞线,终端加 120Ω 电阻。
- 多机通信时注意 从站地址唯一。
- 避免大批量寄存器一次读取,防止超时。
- TCP 版本应结合 VPN/防火墙使用,防止被非法访问。
✅ 总结:
Modbus 协议因其 简单、开放、通用,成为工业自动化里事实上的标准。掌握 RTU/TCP 帧结构、寄存器模型和常用功能码,就能快速开发上位机程序或嵌入式采集设备。
好的阿杰 👍
那我来给你写一份 Modbus RTU 通信抓包实战示例,带 完整的请求帧、响应帧,逐字节解析每一部分的含义。
🔹 Modbus RTU 抓包实战示例
场景
- 主站地址:01
- 目标操作:读取保持寄存器(Holding Register)
- 起始寄存器地址:0x0010 (16)
- 寄存器数量:2 个
- 功能码:03 (Read Holding Registers)
1. 主站请求帧
01 03 00 10 00 02 C5 CD
逐字节解析
字节 | 内容 | 含义 |
---|---|---|
01 | 从站地址 | 目标设备地址 = 1 |
03 | 功能码 | 读保持寄存器 |
00 10 | 起始地址 | 从寄存器 0x0010 开始 |
00 02 | 数量 | 读取 2 个寄存器 |
C5 CD | CRC16 校验 | 检错用(低字节在前) |
👉 含义:“从站 1,请返回保持寄存器 0x0010 开始的 2 个值”
2. 从站响应帧
假设寄存器值为:
- 0x0010 = 0x1234
- 0x0011 = 0x5678
返回帧:
01 03 04 12 34 56 78 79 84
逐字节解析
字节 | 内容 | 含义 |
---|---|---|
01 | 从站地址 | 响应设备地址 = 1 |
03 | 功能码 | 读保持寄存器 |
04 | 字节数 | 后续数据长度 = 4 字节 |
12 34 | 第 1 个寄存器值 | 0x1234 |
56 78 | 第 2 个寄存器值 | 0x5678 |
79 84 | CRC16 校验 | 检错用 |
👉 含义:“寄存器 0x0010 的值是 0x1234,寄存器 0x0011 的值是 0x5678”
3. 错误/异常响应示例
如果主站请求寄存器数量非法(例如超过设备支持范围),从站可能返回异常帧:
01 83 02 C0 F1
逐字节解析
字节 | 内容 | 含义 |
---|---|---|
01 | 从站地址 | 响应设备地址 = 1 |
83 | 功能码 + 0x80 | 表示功能码 03 出错 |
02 | 异常码 | 02 = 非法数据地址 |
C0 F1 | CRC16 校验 | 检错用 |
👉 含义:“请求的寄存器地址不存在或不可用”
4. CRC16 校验说明
Modbus RTU 使用 CRC16-IBM 算法:
- 多项式:
0xA001
- 结果低字节在前,高字节在后
- 例:
C5 CD
→ 实际 CRC 值为0xCDC5
5. 抓包工具
实际调试时可以用以下工具查看 Modbus 帧:
- 串口调试助手(支持十六进制显示)
- Modbus Poll(上位机软件)
- Wireshark(可解析 Modbus RTU/TCP 协议)
✅ 小结:
通过请求帧和响应帧的 逐字节解析,我们能清楚理解 Modbus RTU 的交互过程。
- 主站发起请求 → 地址、功能码、寄存器范围。
- 从站返回响应 → 数据长度、寄存器值。
- 出错时返回 异常帧(功能码+0x80,异常码)。
好的阿杰 👍
接着我们来写一份 Modbus TCP 抓包实战示例,同样给你完整的请求帧、响应帧,并逐字节解析。
🔹 Modbus TCP 抓包实战示例
1. 基本特点
- 物理层/链路层:基于以太网,走 TCP 协议(默认端口 502)。
- 帧结构:相比 RTU,没有 CRC 校验,因为 TCP 已保证可靠性。
- 数据帧组成:
| MBAP Header (7字节) | PDU (功能码+数据) |
2. MBAP 头结构(7 字节)
字段 | 长度 | 说明 |
---|---|---|
Transaction ID | 2B | 事务标识符,上位机自己生成,用于请求-响应对应 |
Protocol ID | 2B | 协议标识,Modbus 固定为 0x0000 |
Length | 2B | 后续字节长度(Unit ID + PDU 长度) |
Unit ID | 1B | 单元标识符(等同于 RTU 从站地址) |
3. 示例场景
- 事务 ID:
0x0001
- 协议 ID:
0x0000
- 单元 ID:
0x11
(即设备地址 17) - 功能:读保持寄存器(功能码 03)
- 起始寄存器地址:0x006B (107)
- 寄存器数量:3
4. 主站请求帧
00 01 00 00 00 06 11 03 00 6B 00 03
逐字节解析
字节 | 含义 |
---|---|
00 01 | Transaction ID = 1(用于匹配响应) |
00 00 | Protocol ID = 0(表示 Modbus 协议) |
00 06 | 长度 = 6(后面 Unit ID + PDU 的字节数) |
11 | Unit ID = 17(目标设备地址) |
03 | 功能码 = 03(读保持寄存器) |
00 6B | 起始寄存器地址 = 107 |
00 03 | 寄存器数量 = 3 |
👉 含义:“从设备 17 读取从 107 开始的 3 个保持寄存器”
5. 从站响应帧
假设寄存器值为:
- 107 = 0x02 2B
- 108 = 0x00 00
- 109 = 0x00 64
响应帧:
00 01 00 00 00 09 11 03 06 02 2B 00 00 00 64
逐字节解析
字节 | 含义 |
---|---|
00 01 | Transaction ID = 1(与请求对应) |
00 00 | Protocol ID = 0 |
00 09 | 长度 = 9(后续 9 字节:Unit ID + PDU) |
11 | Unit ID = 17 |
03 | 功能码 = 03 |
06 | 字节数 = 6(3 个寄存器 × 2 字节) |
02 2B | 第 1 个寄存器值 (555) |
00 00 | 第 2 个寄存器值 (0) |
00 64 | 第 3 个寄存器值 (100) |
👉 含义:“寄存器107=555,108=0,109=100”
6. 异常响应示例
如果请求的寄存器超出范围,从站返回:
00 01 00 00 00 03 11 83 02
逐字节解析
字节 | 含义 |
---|---|
00 01 | Transaction ID = 1 |
00 00 | Protocol ID = 0 |
00 03 | 长度 = 3 |
11 | Unit ID = 17 |
83 | 功能码 + 0x80,表示 03 出错 |
02 | 异常码 = 02(非法数据地址) |
7. 抓包工具
- Wireshark:支持解析 Modbus TCP,非常直观。
- Modbus TCP 测试软件:如 Modbus Poll、QModMaster。
✅ 小结:
- Modbus RTU:有 CRC 校验,串口通信。
- Modbus TCP:无 CRC,增加 MBAP 头(事务 ID、长度、Unit ID)。
- 请求/响应帧格式非常相似,掌握一种,另一种也能快速上手。
好的阿杰 👍
下面我帮你整理一个 Modbus RTU vs Modbus TCP 对比表格,涵盖 帧结构、传输介质、适用场景、优缺点,让你快速对比两者。
🔹 Modbus RTU vs Modbus TCP 对比
特性 | Modbus RTU | Modbus TCP |
---|---|---|
物理层 | 串口 (RS-232 / RS-485) | 以太网 (TCP/IP,默认端口 502) |
帧结构 | 地址 + 功能码 + 数据 + CRC16 | MBAP头 (7B) + 功能码 + 数据 |
校验方式 | CRC16(低字节在前,高字节在后) | TCP 本身保证可靠性,无 CRC |
地址范围 | 从站地址 1–247(0 为广播) | Unit ID (1B),理论支持多个设备,通常与网关关联 |
传输速率 | 常见波特率:9.6k、19.2k、38.4k bps | 10/100/1000 Mbps,以太网速度远快于 RTU |
拓扑结构 | 总线型(多点 RS-485),主从架构 | 星型/树型(交换机/路由器),支持复杂网络 |
通信距离 | RS-485 最长约 1200 米 | 以太网典型 100 米(可通过交换机/光纤扩展到 km 级) |
实时性 | 较好,延迟低,但速率有限 | 网络延迟可能略高,但带宽大,整体吞吐量高 |
部署难度 | 简单,成本低(常见于现场设备) | 需要网络配置(IP 地址、交换机/路由器) |
适用场景 | 工厂车间、近距离、点对点/小规模设备采集 | 远程监控、SCADA 系统、工业物联网 (IIoT) |
优点 | – 协议简单,硬件需求低 – 抗干扰性强(RS-485 差分) – 成本低 | – 基于以太网,易扩展 – 高带宽,支持远程访问 – 无需 CRC,效率高 |
缺点 | – 速率低,地址有限 – 距离长需中继 – 设备扩展性差 | – 需要 IP 网络配置 – 对网络环境依赖大 – 安全性问题(需 VPN/防火墙保护) |
🔸 总结
- Modbus RTU 更适合 本地/近距离、成本敏感 的场合,比如:PLC ↔ 变频器 ↔ 温度传感器。
- Modbus TCP 更适合 远程监控、跨区域、IIoT 系统,比如:工厂数据上传云端,SCADA 集中监控。
发表回复