






















Modbus 是一种串行通信协议,因为它通过串行线路在设备之间传输数据。Modbus 最初由 Modicon 公司(现为施耐德电气的一部分)开发,主要用于可编程逻辑控制器(PLC)之间的通信。其基本工作原理是通过串行电缆连接两个设备的串行端口,数据以一系列的位(1和 0)进行传输,每个位通过电压变化来表示。
Modbus 在工业工控等各个领域都有广泛的应用。Modbus 协议应用在物联网控制器,可以用来监听控制传感器、电机、电表、变频器等设备;同时也可以将这些感知层设备的数据处理完成并上传至工控机或者云端平台进行展示。
ModbusTCP:基于以太网传输,使用 TCP/IP 协议。它允许在局域网或互联网上进行通信,具有高速、远距离传输的优点。
Modbus RTU:(Remote Terminal Unit,远程终端单元)基于串行通信,如 RS-232、RS-422 或 RS-485。它通常用于较短距离、较低速度的通信场景。
Modbus ASCII: 使用 ASCII 字符集传递消息,方便阅读和调试。Modbus ASCII 相比于 Modbus RTU,协议帧中添加了起始和结束,更换了校验算法。
测试工具:
Modbus Poll
Modbus Slave
Modbus RTU:Modbus Poll(主),Modbus Slave(从)
ModbusTCP:Modbus Poll(从),Modbus Slave(主)
Modbus Slave功能码:
| 存储区 | 操作 | 代号1 | 代号2 | 代号3 | 绝对地址 | 相对地址 |
| 0x01 | 位操作,只读 | 只读布尔 | 输入布尔 | 输入状态 | 10001~19999 | 0~9998 |
| 0x03 | 字节操作,只读 | 只读数字 | 输入寄存器 | 30001~39999 | 0~9998 | |
| 0x00 | 位操作,可读写 | 可读写布尔 | 输出布尔 | 线圈状态 | 00001~09999 | 0~9998 |
| 0x04 | 字节操作,可读写 | 可读写数字 | 输出寄存器 | 保存寄存器 | 40001~49999 | 0~9998 |
这里编号对应着Modbus Slave-->Setup-->Slave Definition内的Function
Modbus Poll功能码:
Modbus Slave功能码有4个;0:可读写,1:可读,3:可读,4:可读写;Modbus Poll功能码功能码有8个,对应Modbus Slave功能码,只不过把可读写拆分开来,写分为单个和多个。
Modbus Poll功能码:读:1输入线圈,0输出线圈,3输入寄存器,4输出寄存器
写:单个输出线圈,多个输出线圈,单个输出寄存器,多个输出寄存器;
| 功能码 | (功能) | 中文说明 |
|---|---|---|
| 1 | Read Coils | 读线圈:读取离散输出线圈的状态(单比特,读/写对象) |
| 2 | Read Discrete Inputs | 读离散输入:读取离散输入的状态(单比特,只读对象) |
| 3 | Read Holding Registers | 读保持寄存器:读取保持寄存器(16位寄存器,读/写对象,常用于模拟量或内部变量) |
| 4 | Read Input Registers | 读输入寄存器:读取输入寄存器(16位,只读,通常用于模拟量输入) |
| 5 | Write Single Coil | 写单个线圈:写入单个线圈(设置或复位一个离散输出位) |
| 6 | Write Single Register | 写单个寄存器:写入单个保持寄存器的值(16位) |
| 15 / 0x0F | Write Multiple Coils | 写多个线圈:同时写入多个离散输出线圈的状态 |
| 16 / 0x10 | Write Multiple Registers | 写多个寄存器:同时写入多个保持寄存器的值 |
| 20 / 0x14 | Read File Record | 读文件记录:用于读取文件记录(较少用,扩展功能) |
| 21 / 0x15 | Write File Record | 写文件记录:写文件记录(扩展功能) |
| 22 / 0x16 | Mask Write Register | 掩码写寄存器:对寄存器应用掩码进行部分位修改 |
| 23 / 0x17 | Read/Write Multiple Registers | 读/写多个寄存器:在一个请求中同时读和写保持寄存器 |
| 43 / 0x2B | Read Device Identification | 读取设备标识:读取设备识别信息(扩展,通常用于设备信息查询) |
Modbus 报文常见异常码
|
0x01 |
非法的功能码 |
|
0x02 |
非法的数据地址 |
|
0x03 |
非法的数据值 |
|
0x04 |
从设备/服务器故障 |
|
0x05 |
确认,从设备/服务器需要一个耗时操作 |
|
0x06 |
从设备/服务器繁忙 |
|
0x0A |
网关故障 |
|
0x0B |
网关目标设备未能响应 |
ModbusRTU 报文由四部分组成:从站地址、功能码、数据、校验。
| 请求 |
从站地址 |
功能码 |
起始地址 |
读取长度 |
校验 |
|||
| 01 | 01 | 00 | 00 | 00 | 0A |
BC |
0D |
|
| 响应 | 从站地址 | 功能码 | 字节数 |
输出状态 |
输出状态 |
校验 |
||
| 01 | 01 | 02 | 05 | 02 |
3B |
6D | ||
|
请求 响应 |
从站地址 |
功能码 |
写入地址 |
写入值 |
校验 |
|||
| 01 | 05 | 00 | 00 | FF | 00 | BC | 3A | |
| 请求 | 从站地址 | 功能码 |
写入地址 |
写入数量 |
字节 数 |
写入值 |
校验 |
||||
| 01 | 0F | 00 | 00 | 00 | 0A | 02 | AD | 03 | D9 | A9 | |
| 响应 | 从站地址 | 功能码 | 写入地址 | 写入数量 | 校验 | |||
| 01 | 0F | 00 | 00 | 00 | 0A | D5 | CC | |
|
请求 |
从站地址 |
功能码 |
起始地址 |
读取长度 |
校验 |
|||
|
01 |
03 |
00(H) |
00(L) |
00 | 0A |
C5 |
CD |
|
| 响应 |
从站地址 |
功能码 |
字节数 |
寄存器值(1) |
寄存器值(2) |
寄存器值(10) | 校验 | ||||
| 01 | 03 | 14 | 00 | 7B | 00 | 00 | 00 | 00 | 56 | 4F | |
|
请求 响应 |
从站地址 | 功能码 |
起始地址 |
写入值 | 校验 | |||
| 01 | 06 | 00 | 00 | FA | EA | 48 | 25 | |
|
请 求 |
从站地址 | 功能码 |
写入地址 |
写入数量 |
字节数 |
写入值 |
校验 |
||||||
| 01 | 10 | 00 | 02 | 00 | 02 | 04 | 41 | 00 | 00 | 00 | 66 | 4A | |
| 响应 | 从站地址 | 功能码 | 写入地址 | 写入数量 | 校验 | |||
| 01 | 10 | 00 | 00 | 00 | 02 | E0 | 08 | |
ModbusTCP协议报文由MBAP(Modbus Application Protocol Header)、PDU(ProtocolData Unit)两大部分。MBAP 包含了 ModbusTcp 的一些基本信息,PDU 则包含了具体数据。
MBAP 由如下 4 个部分组成:
(1) Transaction Identifier(事务标识符):占用两个字节,用于标识一次完整的
通讯事务。
(2) Protocal Identifier(协议标识符):占用两个字节,固定为 0x0000。
(3) Length(长度字段):占用两个字节。表示后续字节长度。
(4) Unit Identifier(单元标识符):占用一个字节,用于标识从站位置区域。
PDU 由如下 2 个部分组成:
(1) Function Code(功能码):占用一个字节,用于标识功能的类型。
(2) Data(数据):根据具体的功能码而定,用于传输具体的数据。
|
请求 |
事务标识符 |
协议标识符 |
长度 |
单元标识符 |
功能码 |
起始地址 |
读取长度 |
|||||
|
01 |
AA |
00 |
00 |
00 |
06 |
01 |
01 |
00 |
00 |
00 |
0A |
|
|
响应 |
事务标识符 |
协议标识符 |
长度 |
单元标识符 |
功能码 |
数据长度 |
数据 |
||||
|
01 |
AA |
00 |
00 |
00 |
05 |
01 |
01 |
02 |
4B |
00 |
|
写单线圈:0x05
|
请求响应 |
事务标识符 |
协议标识符 |
长度 |
单元标识符 |
功能码 |
起始地址 |
写入值 |
|||||
|
0B |
5B |
00 |
00 |
00 |
06 |
01 |
05 |
00 |
00 |
FF/00 |
00 |
|
写多线圈:0x0F
|
请求 |
事务标识符 |
协议标识符 |
长度 |
单元标识符 |
功能码 |
起始地址 |
写入数量 |
字节数 |
写入值 |
||||||
|
0D |
05 |
00 |
00 |
00 |
09 |
01 |
0F |
00 |
00 |
00 |
0A |
02 |
AD |
03 |
|
|
响应 |
事务标识符 |
协议标识符 |
长度 |
单元标识符 |
功能码 |
起始地址 |
写入数量 |
|||||
|
0D |
05 |
00 |
00 |
00 |
06 |
01 |
0F |
00 |
00 |
00 |
0A |
|
读寄存器 0x03、0x04
|
请求 |
事务标识符 |
协议标识符 |
长度 |
单元标识符 |
功能码 |
起始地址 |
读取长度 |
|||||
|
08 |
ED |
00 |
00 |
00 |
06 |
01 |
03 |
00 |
00 |
00 |
03 |
|
|
响应 |
事务标识符 |
协议标识符 |
长度 |
单元标识符 |
功能码 |
数据长度 |
数据 |
||||||
|
08 |
ED |
00 |
00 |
00 |
07 |
01 |
03 |
04 |
00 |
7B |
00 |
00 |
|
写单寄存器 0x06
|
请求 响应 |
事务标识符 |
协议标识符 |
长度 |
单元标识符 |
功能码 |
起始地址 |
写入值 |
|||||
|
16 |
51 |
00 |
00 |
00 |
06 |
01 |
06 |
00 |
00 |
00 |
7B |
|
写多寄存器 0x10
|
请求 |
事务标识符 |
协议标识符 |
长度 |
单元标识符 |
功能码 |
写入地址 |
写入数量 |
字节数 |
字节 1 ... |
||||||
|
18 |
81 |
00 |
00 |
00 |
1B |
01 |
10 |
00 |
00 |
00 |
0A |
14 |
00 |
7B |
|
|
响应 |
事务标识符 |
协议标识符 |
长度 |
单元标识符 |
功能码 |
写入地址 |
写入数量 |
|||||
|
18 |
81 |
00 |
00 |
00 |
06 |
01 |
10 |
00 |
00 |
00 |
0A |
|
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。