Modbus通讯协议解析
Modbus通讯协议解析
Modbus协议诞生于1979年 莫迪康公司 后来被施耐德电气公司收购。
Modbus协议广泛应用于工业领域,是目前工业领域应用最广泛的协议。
支持RS-485、RS-232、以太网等多种物理层接口,覆盖从串行通信到TCP/IP网络的各种应用场景;
Modbus区分为 Modbus-RTU 、 Modbus-ASCII 和 Modbus-TCP 三种协议格式
1. Modbus-RTU协议
Modbus-RTU模式是二进制模式,数据流以字节为单位传输。
Modbus-RTU通常为大端模式,即使用高字节在前,低字节在后的发送顺序。
Modbus-RTU通常使用RS-485作为总线,因为RS-485支持多设备(最多247个设备)和长距离传输。
1.1 Modbus-RTU 帧结构
地址
功能码
数据
校验码
1 Byte
1 Byte
0~252 Byte
2 Byte
地址:从机地址,00为广播地址,从机地址范围1~247
功能码:主机要求从机执行的操作类型
数据:包含了命令的具体参数,格式和长度取决于功能码
校验码:CRC校验,通常使用CRC16-Modbus校验计算,前低后高
1.2 Modbus-RTU 功能码
功能码
名称
用途
0x01
读线圈(Read Coils)
取得一组逻辑线圈的当前状态(ON/OFF)
0x02
读离散输入寄存器(Read Discrete Inputs)
取得一组开关输入的当前状态(ON/OFF)
0x03
读保持寄存器(Read Holding Registers)
在一个或多个保持寄存器中取得当前的二进制值
0x04
读输入寄存器(Read Input Registers)
在一个或多个输入寄存器中取得当前的二进制值
0x05
写单个线圈寄存器 (Write Single Coil)
强置写入一个逻辑线圈的通断状态
0x06
写单个保持寄存器(Write Single Register)
把具体二进制值写入一个保持寄存器
0x0F
写多个线圈寄存器(Write Multiple Coils)
强置写入一串连续逻辑线圈的通断
0x10
写多个保持寄存器(Write Multiple Registers)
把具体的二进制值写入一串连续的保持寄存器
1.2.1 0x01 - 读线圈
用途:读从站线圈寄存器,位操作,可读单个或多个
发送帧:从站地址 + 功能码 + 线圈起始地址 + 线圈数量 + CRC
从站地址:0x01;寄存器开始地址:0x0011;读取线圈数量:8个
从站地址
功能码
寄存器起始地址(高位)
寄存器起始地址(低位)
寄存器数量(高位)
寄存器数量(低位)
CRC-L
CRC-H
0x01
0x01
0x00
0x11
0x00
0x08
0x6D
0xC9
响应帧:从站地址 + 功能码 + 字节数 + 数据 + CRC
返回数据,Bit位对应每个线圈状态,1表示ON,0表示OFF
从站地址
功能码
返回字节数
数据
CRC-L
CRC-H
0x01
0x01
0x01
0x11
0x91
0x84
TX: 01 01 00 11 00 08 6D C9
RX: 01 01 01 11 91 85
1.2.2 0x02 - 读离散输入寄存器
用途:读从站离散输入寄存器,位操作,可读单个或多个
发送帧:从站地址 + 功能码 + 寄存器起始地址 + 寄存器数量 + CRC
从站地址:0x01;寄存器开始地址:0x0011;读取线圈数量:8个
从站地址
功能码
寄存器起始地址(高位)
寄存器起始地址(低位)
寄存器数量(高位)
寄存器数量(低位)
CRC-L
CRC-H
0x01
0x02
0x00
0x11
0x00
0x08
0x29
0xC9
响应帧:从站地址 + 功能码 + 字节数 + 数据 + CRC
返回数据,Bit位对应每个线圈状态,1表示ON,0表示OFF
从站地址
功能码
返回字节数
数据
CRC-L
CRC-H
0x01
0x02
0x01
0x11
0x61
0x84
TX: 01 02 00 11 00 08 29 C9
RX: 01 02 01 11 61 84
1.2.3 0x03 - 读保持寄存器
用途:读从站保持寄存器,字节操作,可读单个或多个(最多读取127个寄存器)
发送帧:从站地址 + 功能码 + 寄存器起始地址 + 寄存器数量 + CRC
从站地址:0x01;寄存器开始地址:0x0011;读取寄存器数量:2个
从站地址
功能码
寄存器起始地址(高位)
寄存器起始地址(低位)
寄存器数量(高位)
寄存器数量(低位)
CRC-L
CRC-H
0x01
0x03
0x00
0x11
0x00
0x02
0x94
0x0E
响应帧:从站地址 + 功能码 + 字节数 + 数据 + CRC
返回数据,数据大端模式(前高后低),CRC小端模式(前低后高)
从站地址
功能码
返回字节数
数据1-H
数据1-L
数据2-H
数据2-L
CRC-L
CRC-H
0x01
0x03
0x04
0x11
0x22
0x33
0x44
0x4B
0xC6
TX: 01 03 00 11 00 02 94 0E
RX: 01 03 04 11 22 33 44 4B C6
1.2.4 0x04 - 读输入寄存器
用途:读从站输入寄存器,字节操作,可读单个或多个
发送帧:从站地址 + 功能码 + 寄存器起始地址 + 寄存器数量 + CRC
从站地址:0x01;寄存器开始地址:0x0011;读取寄存器数量:2个
从站地址
功能码
寄存器起始地址(高位)
寄存器起始地址(低位)
寄存器数量(高位)
寄存器数量(低位)
CRC-L
CRC-H
0x01
0x04
0x00
0x11
0x00
0x02
0x21
0xCE
响应帧:从站地址 + 功能码 + 字节数 + 数据 + CRC
返回数据,数据大端模式(前高后低),CRC小端模式(前低后高)
从站地址
功能码
返回字节数
数据1-H
数据1-L
数据2-H
数据2-L
CRC-L
CRC-H
0x01
0x04
0x04
0x11
0x22
0x33
0x44
0x4A
0x71
TX: 01 04 00 11 00 02 21 CE
RX: 01 04 04 11 22 33 44 4A 71
1.2.5 0x05 - 写单个线圈寄存器
用途:写单个线圈,位操作,只能写一个,写0xFF00表示线圈为ON,写0x0000表示线圈为OFF
发送帧:从站地址 + 功能码 + 起始寄存器地址 + 数据 + CRC
从站地址:0x01;寄存器地址:0x0011;设置线圈值:ON
从站地址
功能码
寄存器起始地址(高位)
寄存器起始地址(低位)
数据1-H
数据1-L
CRC-L
CRC-H
0x01
0x05
0x00
0x11
0xFF
0x00
0xDC
0x3F
响应帧:从站地址 + 功能码 + 起始寄存器地址 + 数据 + CRC
返回数据同发送帧
从站地址
功能码
寄存器起始地址(高位)
寄存器起始地址(低位)
数据1-H
数据1-L
CRC-L
CRC-H
0x01
0x05
0x00
0x11
0xFF
0x00
0xDC
0x3F
TX: 01 05 00 11 FF 00 DC 3F
RX: 01 05 00 11 FF 00 DC 3F
1.2.6 0x06 - 写单个保持寄存器
用途:写单个保持寄存器,字节操作,只能写一个寄存器
发送帧:从站地址 + 功能码 + 起始寄存器地址 + 数据 + CRC
从站地址:0x01;寄存器地址:0x0011;设置寄存器值:0x1234
从站地址
功能码
寄存器起始地址(高位)
寄存器起始地址(低位)
数据1-H
数据1-L
CRC-L
CRC-H
0x01
0x06
0x00
0x11
0x12
0x34
0xD4
0xB8
响应帧:从站地址 + 功能码 + 起始寄存器地址 + 数据 + CRC
返回数据同发送帧
从站地址
功能码
寄存器起始地址(高位)
寄存器起始地址(低位)
数据1-H
数据1-L
CRC-L
CRC-H
0x01
0x06
0x00
0x11
0x12
0x34
0xD4
0xB8
TX: 01 06 00 11 12 34 D4 B8
RX: 01 06 00 11 12 34 D4 B8
1.2.7 0x0F - 写多个线圈寄存器
用途:写多个线圈寄存器,数据区的Bit位,0表示OFF;1表示ON;
发送帧:从站地址 + 功能码 + 起始寄存器地址 + 寄存器数量 + 字节数 + 数据 + CRC
从站地址:0x01;寄存器开始地址:0x0011;写寄存器数量:5个
字节数:*N = Quantity of Outputs / 8, if the remainder is different of 0 N = N+1
字节数应为 线圈数量/8的向上取整
从站地址
功能码
寄存器起始地址(高位)
寄存器起始地址(低位)
寄存器数量(高位)
寄存器数量(低位)
字节数
数据1
CRC-L
CRC-H
0x01
0x0F
0x00
0x11
0x00
0x05
0x01
0x13
0x9A
0x84
响应帧:从站地址 + 功能码 + 起始线圈地址 + 寄存器数量 + CRC
从站地址
功能码
寄存器起始地址(高位)
寄存器起始地址(低位)
寄存器数量(高位)
寄存器数量(低位)
CRC-L
CRC-H
0x01
0x0F
0x00
0x11
0x00
0x05
0x54
0xC8
从站地址:0x01;寄存器开始地址:0x0011;写寄存器数量:9个
从站地址
功能码
寄存器起始地址(高位)
寄存器起始地址(低位)
寄存器数量(高位)
寄存器数量(低位)
字节数
数据1-H
数据1-L
CRC-L
CRC-H
0x01
0x0F
0x00
0x11
0x00
0x09
0x02
0x01
0x3B
0xD6
0x3E
响应帧:从站地址 + 功能码 + 起始线圈地址 + 寄存器数量 + CRC
从站地址
功能码
寄存器起始地址(高位)
寄存器起始地址(低位)
寄存器数量(高位)
寄存器数量(低位)
CRC-L
CRC-H
0x01
0x0F
0x00
0x11
0x00
0x09
0x54
0xCD
TX: 01 0F 00 11 00 05 01 13 9A 84
RX: 01 0F 00 11 00 05 54 C8
TX: 01 0F 00 11 00 09 02 01 3B D6 3E
RX: 01 0F 00 11 00 09 54 CD
1.2.8 0x10 - 写多个保持寄存器
用途:写多个保持寄存器,字节操作,可写多个
发送帧:从站地址 + 功能码 + 起始寄存器地址 + 寄存器数量 + 字节数 + 数据 + CRC
从站地址:0x01;寄存器开始地址:0x0011;写寄存器数量:2个;设置寄存器值:0x1234 0x5678
从站地址
功能码
寄存器起始地址(高位)
寄存器起始地址(低位)
寄存器数量(高位)
寄存器数量(低位)
字节数
数据1-H
数据1-L
数据2-H
数据2-L
CRC-L
CRC-H
0x01
0x10
0x00
0x11
0x00
0x02
0x04
0x12
0x34
0x56
0x78
0x48
0x5B
响应帧:从站地址 + 功能码 + 起始寄存器地址 + 寄存器数量 + CRC
从站地址
功能码
寄存器起始地址(高位)
寄存器起始地址(低位)
寄存器数量(高位)
寄存器数量(低位)
CRC-L
CRC-H
0x01
0x10
0x00
0x11
0x00
0x02
0x11
0xCD
TX: 01 10 00 11 00 02 04 12 34 48 5B
RX: 01 10 00 11 00 02 11 CD
