Modbus协议介绍
MODBUS 是一个请求/应答协议,包括ASCII、RTU、TCP等,是1979年开发出的一种工业通信协议,并没有规定物理层。此协议定义了控制器能够认识和使用的消息结构,而不管它们是通过何种硬件方式进行通信的。所以硬件接口可以是RS-232、RS-422、RS-485和以太网等设备。TCP和RTU比ASCII常见,其中TCP的使用频率更高一些。
关于主站与从站:RTU模式下,一个主站可以连接多个从站,且主站有且只能有一个,从站至少一个;TCP模式下主要分为服务器与客户端,可认为客户端是主站。
1. Modbus协议相关术语及含义:
寄存器种类 |
数据类型 |
访问类型 |
功能码 |
线圈 |
位 |
读写 |
01H 05H 0FH |
离散输入 |
位 |
读写(主站只读) |
02H |
保持寄存器 |
字 |
读写 |
04H |
输入寄存器 |
字 |
读写(主站只读) |
03H 06H 10H |
Memory Block
Coils:线圈、Discrete Inputs:离散输入、Holding Registers:保持寄存器、
Input Registers输入寄存器
Data Type
只有布尔型与无符号整型,即无法传输负数与浮点数,当然,我们可以通过其他方式实
现。
同许多规范一样,不同行业可能会有不同的称呼。如保持寄存器可以被称为输出寄存器,而线圈可以被称为数字或离散输出。
2. 常用功能码
Modbus中常用的功能码有 8个,可以分为位操作和字操作两类,如下表
功能码 |
描述 |
PLC地址 |
寄存器地址 |
位/字操作 |
操作数量 |
01H |
读线圈寄存器 |
00001-09999 |
0000H-FFFFH |
位 |
单个或多个 |
02H |
读离散输入寄存器 |
10001-19999 |
0000H-FFFFH |
位 |
单个或多个 |
03H |
读保持寄存器 |
40001-49999 |
0000H-FFFFH |
字 |
单个或多个 |
04H |
读输入寄存器 |
30001-39999 |
0000H-FFFFH |
字 |
单个或多个 |
05H |
写单个线圈寄存器 |
00001-09999 |
0000H-FFFFH |
位 |
单个 |
06H |
写单个保持寄存器 |
40001-49999 |
0000H-FFFFH |
字 |
单个 |
0FH |
写多个线圈寄存器 |
00001-09999 |
0000H-FFFFH |
位 |
多个 |
10H |
写多个保持寄存器 |
40001-49999 |
0000H-FFFFH |
字 |
多个 |
3. Modbus消息结构
接下来重点说下Modbus的消息结构,以功能码01(0x01)为例进行说明。
功能码01H读取Modbus从站中线圈寄存器的状态,可以是单个寄存器,或者是多个连续的寄存器。
发送:
假设从站地址为01H,读取线圈寄存器的起始地址为0017H,读取38(十进制)个寄存器,指令结构如下表:
从站地址 |
功能码 |
起始地址高位 |
起始地址低位 |
寄存器数量高位 |
寄存器数量低位 |
CRC高位 |
CRC低位 |
01 |
01 |
00 |
17 |
00 |
26 |
0D |
D4 |
响应:各线圈的状态与数据内容的每个bit对应,1代表ON,0代表OFF.若查询线圈的数量不是8的倍数,则在最后一个字节的高位补0.
读线圈结果举例:
从站地址 |
功能码 |
返回字节数 |
数据1 |
数据2 |
数据3 |
数据4 |
数据5 |
CRC高位 |
CRC低位 |
01 |
01 |
05 |
CD |
6B |
B2 |
0E |
1B |
44 |
EA |
第一个字节CDH对应线圈0017H到001E的状态,转为二进制是11001101,其中bit0对应0017H,bit7对应001E,如下表:
001EH |
001DH |
001CH |
001BH |
001AH |
0019H |
0018H |
0017H |
1 |
1 |
0 |
0 |
1 |
1 |
0 |
1 |
ON |
ON |
OFF |
OFF |
ON |
ON |
OFF |
ON |
对于刚接触的老铁们看到这里有点蒙圈吧?正常,我开始看到这里的时候也蒙圈。其实说白了就是规定了交换数据的方式,大家都按这个方式来,这就是“协议”啊,至于这个协议具体叫什么也不重要,重要的是大家都能明白我发的东西是什么意思就好了。就像以前谍战片里的电报一样,发过来的东西需要“协议”解读下,就是这个意思了。
下次和大家分享下Modbus调试助手的使用,那个更直观!
欢迎关注公众号,一起交流