Modbus协议_modbus功能码
Modbus协议是一种请求/应答方式的交互过程,主机主动发起通讯请求,从机响应主机的请求,从机在没有收到主机的请求时,不会主动发送数据,从机之间不会进行通讯。
一、Modbus 4种数据类型/寄存器分类
寄存器种类
读写状态
数据类型
功能码
PLC地址
线圈寄存器
读/写
位(bit)
01H(读单/多个位);05H(写单个位);0FH(写多个位);
00001-09999
离散输入寄存器
只读
位(bit)
02H(读单/多个位)
10001-19999
保持寄存器
读/写
字(byte)
03H(读);06H(写单个字节);0FH(写多个字节)
30001-39999
输入寄存器
只读
字(byte)
04H(读单/多个字)
40001-49999
二、Modbus数据帧格式
RTU帧
起始位
设备地址
功能码
数据
CRC校验
结束符
T1-T2-T3-T4
8Bit
8Bit
n个8Bit
16Bit
T1-T2-T3-T4
不超过256字节。
三、Modbus功能码/异常码/错误码
Modbus功能码
功能码
说明
01
读取线圈状态
02
读取输入状态
03
读取保持寄存器
04
读取输入寄存器
05
强置单线圈
06
预置单寄存器
07
读取异常状态
08
回送诊断校验
09
编程(只用于 484)
10
控询
11
读取事件计数
12
读取通信事件记录
13
编程(184/384/484/584 等)
14
探寻
15
强置多线圈
16
预置多线圈
17
报告多寄存器
18
可使主机模拟编程功能
19
重置通信链路
20
读取通用参数
21
写入通用参数
22
屏蔽写寄存器
23
读 / 写多个寄存器
43
读设备别识码
22-42,44-64
保留作为扩展功能
65-72
保留以备用功能所用
73-119
非法功能
120-127
保留,留作内部作用
128-255
保留,用于异常应答
Modbus异常码
(ExceptionCode)
ExceptionCode: Function Code 的最左边 Bit 设定为 1
举例:86 01, 功能码 06 最左边 Bit 设定为 1,即为 86
参照下表
Modbus 错误码(10 进制)
(ErrorCode)
功能码
说明
01
非法功能。对于服务器(或从站)来说,询问中接收到的功能码是不可允许的操作,可能是因为功能码仅适用于新设备而被选单元中不可实现同时,还指出服务器(或从站)在错误状态中处理这种请求,例如:它是未配置的,且要求返回寄存器值。
02
非法数据地址。对于服务器(或从站)来说,询问中接收的数据地址是不可允许的地址,特别是参考号和传输长度的组合是无效的。对于带有 100 个寄存器的控制器来说,偏移量 96 和长度 4 的请求会成功,而偏移量 96 和长度 5 的请求将产生异常码 02。
03
非法数据值。对于服务器(或从站)来说,询问中包括的值是不可允许的值。该值指示了组合请求剩余结构中的故障。例如:隐含长度是不正确的。modbus 协议不知道任何特殊寄存器的任何特殊值的重要意义,寄存器中被提交存储的数据项有一个应用程序期望之外的值。
04
从站设备故障。当服务器(或从站)正在设法执行请求的操作时,产生不可重新获得的差错。
05
确认。与编程命令一起使用,服务器(或从站)已经接受请求,并且正在处理这个请求,但是需要长持续时间进行这些操作,返回这个响应防止在客户机(或主站)中发生超时错误,客户机(或主机)可以继续发送轮询程序完成报文来确认是否完成处理。
06
从属设备忙。与编程命令一起使用。服务器 (或从站) 正在处理长持续时间的程序命令。张服务器 (或从站) 空闲时,用户 (或主站) 应该稍后重新传输报文。
08
存储奇偶差错。与功能码 20 和 21 以及参考类型 6 一起使用,指示扩展文件区不能通过一致性校验。服务器 (或从站) 设法读取记录文件,但是在存储器中发现一个奇偶校验错误。客户机 (或主方) 可以重新发送请求,但可以在服务器 (或从站) 设备上要求服务。
10
不可用网关路径。与网关一起使用,指示网关不能为处理请求分配输入端口至输出端口的内部通信路径。通常意味着网关是错误配置的或过载的。
11
网关目标设备响应失败。与网关一起使用,指示没有从目标设备中获得响应。通常意味着设备未在网络中。
四、Modbus常用功能码应用举例
MODBUS协议相当复杂,但是常用的命令也就简单的几个,01,02,03,04,05,06,15,16号命令。
各个命令的功能和报文如下:
01 命令 读取线圈状态 MODBUS地址 00001~
MODBUS 请求
功能码
1 BYTE
0X01
起始地址
2 BYTE
0X0000 TO 0XFFFF
读取数量
2 BYTE
1 TO 2000(0X7D0)
MODBUS 响应
功能码
1 BYTE
0X01
字节计数
1 BYTE
N
线圈状态
n BYTE
n =N or N+1
N =读取数量/8 如果余数不为0 则N=N+1
错误 响应
功能码
1 BYTE
0X01+ 0X80
错误代码
1 BYTE
0x1 or 0x2 or 0x3 or 0x4
举例
请求
响应
域名称
数据(hex)
域名称
数据(hex)
功能码
01
功能码
01
起始地址高(字节)
00
字节计数
03
起始地址低(字节)
13
27(h)~20状态
CD
读取数量高(字节)
00
35(h)~28状态
6B
读取数量低(字节)
13
38(h)~36状态
05
02 命令 读取输入状态 MODBUS地址 10001~
MODBUS 请求
功能码
1 BYTE
0X02
起始地址
2 BYTE
0X0000 TO 0XFFFF
读取数量
2 BYTE
1 TO 2000(0X7D0)
MODBUS 响应
功能码
1 BYTE
0X02
字节计数
1 BYTE
N
输入状态
n BYTE
n =N or N+1
N =读取数量/8 如果余数不为0 则N=N+1
错误 响应
功能码
1 BYTE
0X02+ 0X80
错误代码
1 BYTE
0x1 or 0x2 or 0x3 or 0x4
举例
请求
响应
域名称
数据(hex)
域名称
数据(hex)
功能码
02
功能码
02
起始地址高(字节)
00
字节计数
03
起始地址低(字节)
C4
204(h)~197状态
AC
读取数量高(字节)
00
212(h)~205状态
DB
读取数量低(字节)
16
218(h)~213状态
35
03 读保持寄存器 MODBUS地址 40001~
MODBUS 请求
功能码
1 BYTE
0X03
起始地址
2 BYTE
0X0000 TO 0XFFFF
读取数量
2 BYTE
1 TO 125(0X7D)
MODBUS 响应
功能码
1 BYTE
0X03
字节计数
1 BYTE
N*2
输入状态
N*2 BYTE
错误 响应
功能码
1 BYTE
0X03+ 0X80
错误代码
1 BYTE
0x1 or 0x2 or 0x3 or 0x4
举例
请求
响应
域名称
数据(hex)
域名称
数据(hex)
功能码
03
功能码
03
起始地址高(字节)
00
字节计数
06
起始地址低(字节)
6B
寄存器高(108)
02
读取数量高(字节)
00
寄存器低(108)
2B
读取数量低(字节)
03
寄存器高(109)
00
寄存器低(109)
00
寄存器高(110)
00
寄存器低(110)
64
04 输入寄存器 MODBUS地址 30001~
MODBUS 请求
功能码
1 BYTE
0X04
起始地址
2 BYTE
0X0000 TO 0XFFFF
读取数量
2 BYTE
1 TO 125(0X7D)
MODBUS 响应
功能码
1 BYTE
0X04
字节计数
1 BYTE
N*2
输入状态
N*2 BYTE
错误 响应
功能码
1 BYTE
0X04+ 0X80
错误代码
1 BYTE
0x1 or 0x2 or 0x3 or 0x4
举例
请求
响应
域名称
数据(hex)
域名称
数据(hex)
功能码
04
功能码
04
起始地址高(字节)
00
字节计数
02
起始地址低(字节)
08
输入寄存器高(9)
00
读取数量高(字节)
00
输入寄存器低(9)
0A
读取数量低(字节)
01
05 设置单个继电器状态
MODBUS 请求
功能码
1 BYTE
0X05
设置地址
2 BYTE
0X0000 TO 0XFFFF
设置内容
2 BYTE
0x0000 OR 0XFF00
0x0000 释放继电器
0xff00 吸合继电器
MODBUS 响应
功能码
1 BYTE
0X05
设置地址
2 BYTE
0X0000 TO 0XFFFF
设置内容
2 BYTE
0x0000 OR 0XFF00
错误 响应
功能码
1 BYTE
0X05+ 0X80
错误代码
1 BYTE
0x1 or 0x2 or 0x3 or 0x4
举例(吸合6号继电器)
请求
响应
域名称
数据(hex)
域名称
数据(hex)
功能码
05
功能码
05
设置地址高(字节)
00
设置地址高(字节)
00
设置地址低(字节)
05
设置地址低(字节)
05
设置内容高(字节)
FF
设置内容高(字节)
FF
设置内容低(字节)
00
设置内容低(字节)
FF
06 设置单个保持寄存器
MODBUS 请求
功能码
1 BYTE
0X06
设置地址
2 BYTE
0X0000 TO 0XFFFF
设置内容
2 BYTE
0x0000 to 0XFF00
MODBUS 响应
功能码
1 BYTE
0X06
设置地址
2 BYTE
0X0000 TO 0XFFFF
设置内容
2 BYTE
0x0000 to 0XFF00
错误 响应
功能码
1 BYTE
0X06+ 0X80
错误代码
1 BYTE
0x1 or 0x2 or 0x3 or 0x4
举例
设置9号保持寄存器内容为25
请求
响应
域名称
数据(hex)
域名称
数据(hex)
功能码
06
功能码
06
设置地址高(字节)
00
设置地址高(字节)
00
设置地址低(字节)
08
设置地址低(字节)
08
设置内容高(字节)
00
设置内容高(字节)
00
设置内容低(字节)
19
设置内容低(字节)
19
15 设置多个继电器状态
MODBUS 请求
功能码
1 BYTE
0X0F
设置起始地址
2 BYTE
0X0000 TO 0XFFFF
设置长度
2 BYTE
0X0000 TO 0X7B0
字节计数
1 BYTE
N
设置内容
N BYTE
MODBUS 响应
功能码
1 BYTE
0X0F
设置起始地址
2 BYTE
0X0000 TO 0XFFFF
设置长度
2 BYTE
0X0000 TO 0X7B0
错误 响应
功能码
1 BYTE
0X0F+ 0X80
错误代码
1 BYTE
0x1 or 0x2 or 0x3 or 0x4
举例
设置继电器
请求
响应
域名称
数据(hex)
域名称
数据(hex)
功能码
0F
功能码
0F
设置地址高(字节)
00
设置地址高(字节)
00
设置地址低(字节)
13
设置地址低(字节)
13
设置数量高(字节)
00
设置数量高(字节)
00
设置数量低(字节)
0A
设置数量低(字节)
0A
字节计数
02
设置内容高(字节)
CD
设置内容低(字节)
01
16 设置多个保持寄存器
MODBUS 请求
功能码
1 BYTE
0X10
设置起始地址
2 BYTE
0X0000 TO 0XFFFF
设置长度
2 BYTE
0X0000 TO 0X7B0
字节计数
1 BYTE
N*2
设置内容
N*2 BYTE
MODBUS 响应
功能码
1 BYTE
0X10
设置起始地址
2 BYTE
0X0000 TO 0XFFFF
设置长度
2 BYTE
0X0000 TO 0X7B0
错误 响应
功能码
1 BYTE
0X10+ 0X80
错误代码
1 BYTE
0x1 or 0x2 or 0x3 or 0x4
举例
设置多个保持寄存器
请求
响应
域名称
数据(hex)
域名称
数据(hex)
功能码
10
功能码
0F
设置地址高(字节)
00
设置地址高(字节)
00
设置地址低(字节)
01
设置地址低(字节)
01
设置数量高(字节)
00
设置数量高(字节)
00
设置数量低(字节)
02
设置数量低(字节)
02
字节计数
04
设置内容高(字节)
00
设置内容低(字节)
0A
设置内容高(字节)
01
设置内容低(字节)
02
MODBUS协议在智能设备中的应用
上面讲述了MODBUS协议的报文以及命令,那么在智能设备中如何使用这个协议呢?
如果智能设备有开关量输入输出,模拟量输入输出,有计数器等。很明显开关量输入可以映射到 10001地址,第一路开关量输入为10001,第二路为10002,………
开关量输出映射到 00001地址,第一路为00001,第二路为00002,…….
模拟量输入映射到 30001地址,第一路为 30001,第二路为30002,……
模拟量输出和计数器输入映射到40001地址,第一路为 40001,第二路为40002,……
当然也可以把所有的数据都放在保持寄存器中,这样对于MODBUS主设备访问时要简单,访问效率能提高,但是处理起来略显繁琐。