ModbusTCP详解
简介
Modbus 是由美国MODICON公司于1979年开发,是一种工业现场总线协议标准。1997年施耐德公司推出给予以太网TCP/IP的modbus协议————ModbusTCP.
ModubsTCP数据帧
ModbusTCP的数据帧可以分为两部分:MBAP + PDU.
(Modbus Application Protocol——报文头)
(Protocol Data Unit——协议数据单元)
特别说明:在ModbusTCP中,由从站作服务端,主站作客户端,保证主动权在主站手中
报文头MBAP
MBAP为报文头,长度为7字节,组成如下:

事物处理标识:可以理解为报文的序列号,一般每次通信之后就要加1以区别不同的通信数据报文。
协议标识符 :00 00 表示ModbusTCP协议。
长度:表示接下来的数据长度,单位为字节。
单元标识符:可以理解为设备地址。
其中以上四项中,对 长度 做额外举例如下:
00 01 00 00 00 06 01 03 00 00 00 03
上面是一条读取保持寄存器的指令,划横线部份是MBAP。红色字体为长度数据,表示从当前之后的数据总长度。
(注:并不是指PDU的数据长度)
帧结构PDU
PUD由 功能码 + 数据 组成。功能码为1字节,数据长度不定,由具体功能决定。
功能码
modbus的操作对象有四种:线圈、离散输入、输入寄存器、保持寄存器。
- 线圈:PLC的输出位,开关量,在modbus中可读可写。(可以理解为可读可惜的bit)
- 离散量:PCL的输入为,开关量,在modbus中只读。(可以理解为只读的bit)
- 输入寄存器:PLC中只能从模拟量输入端改变的寄存器,在modbus中只读。(可以理解为只读寄存器,一个寄存器占用2个字节)
- 保持寄存器:PLC中用于输出模拟量信号的寄存器,在modbus中可读可写。(可以理解为可读写寄存器,一个寄存器占用2个字节)
根据操作对象/操作内容不同,modbus功能码分为以下几种:
- 0x01:读线圈
- 0x05:写单个线圈
- 0x0F:写多个线圈
- 0x02:读离散量
- 0x04:读输入寄存器
- 0x03:读保持寄存器
- 0x06:写单个保持寄存器
- 0x10:写多个保持寄存器
PDU详细结构
(根据不同功能码,PDU的结构有所变化)
0x01:读线圈
在从站中读取1~8个连续线圈状态,其中ON=1,OFF=0
请求数据:MBAP + 功能码 + 起始地址H(高8位) + 起始地址L(低8位) + 数量H(高8位) + 数量L(低8位)
如: 在从站0x01中,读取开始地址为0x0001的线圈数据,读0x0008位
00 01 00 00 00 06 01 01 00 01 00 08 (事务处理标识) (协议标识) (长度)(设备标识)(功能码) (起始地址) (读取数量)
响应数据:MBAP + 功能码 + 数据长度 + 数据
如: 数据长度为0x01字节(8位),数据值为0x03,第一个和第二个线圈为ON,其余为OFF
00 01 00 00 00 04 01 01 03(事务处理标识) (协议标识) (长度)(设备标识)(数据长度) (数据值)
0x05:写单个线圈
将从站中的一个输出写成ON或OFF,0xFF00表示将目标位写为ON,0x0000表示将目标位写为OFF
- 请求数据:MBAP + 功能码 + 目标地址H(高8位) + 目标地址L(低8位) + 数据值H(高8位) + 数据值L(低8位)
- 如: 在从站0x01中,将地址为0x0001的线圈数据设置为ON
00 01 00 00 00 06 01 05 00 01 FF 00 - 响应数据:MBAP + 功能码 + 目标地址H(高8位) + 目标地址L(低8位) + 数据值H(高8位) + 数据值L(低8位)
- 如: 写入成功
00 01 00 00 00 06 01 05 00 01 FF 00
0x0F:写多个线圈
将一个从站中的一个线圈序列的每个线圈都强制为ON或OFF,数据域中置1的位请求相应输出位ON,置0的位请求响应输出为OFF
- 请求数据:MBAP + 功能码 + 起始地址H(高8位) + 起始地址L(低8位) + 写数量H(高8位) + 写数量L(低8位) + 输出值H(高8位) + 输出值L(低8位)
- 如: 在从站0x01中,将地址为0x0001~0X008的线圈数据设置为ON
00 01 00 00 00 08 01 0F 00 01 00 08 00 FF - 响应数据:MBAP + 功能码 + 起始地址H(高8位) + 起始地址L(低8位) + 写数量H(高8位) + 写数量L(低8位)
- 如: 写入成功
00 01 00 00 00 06 01 0F 00 01 00 08
0x02:读离散量输入
从一个从站中读1~15个连续的离散量输入状态
- 请求数据:MBAP + 功能码 + 起始地址H(高8位) + 起始地址L(低8位) + 读数量H(高8位) + 读数量L(低8位)
- 如: 从地址0x0001开始读15个离散量输入
00 01 00 00 00 06 01 02 00 01 00 0F - 响应数据:MBAP + 功能码 + 数据长度 + 数据
- 如: 读取成功,数据长度为0x02, 数据为0x05 0x01 ,表示第1个、第9个、第11个离散量的值为ON,其余为OFF
00 01 00 00 00 05 01 02 02 05 01
0x04:读输入寄存器
从一个远程设备中读1~5个连续输入寄存器
- 请求数据:MBAP + 功能码 + 起始地址H(高8位) + 起始地址L(低8位) + 寄存器数量H(高8位) + 寄存器数量L(低8位)
- 如: 从地址0x0001开始读5个输入寄存器
00 01 00 00 00 06 01 04 00 01 00 05 - 响应数据:MBAP + 功能码 + 数据长度 + 寄存器数据
- 如: 读取成功,数据长度为0x0A, 第1个数据为0x00A0, 第2个数据为0xFF00 第3个数据为0x4C4C 第4个数据为0x0000 第5个数据为0xAAAA
00 01 00 00 00 0D 01 04 0A 00 A0 FF 00 4C 4C 00 00 AA AA
0x03:读保持寄存器
从一个远程设备中读1~3个连续保持寄存器
- 请求数据:MBAP + 功能码 + 起始地址H(高8位) + 起始地址L(低8位) + 寄存器数量H(高8位) + 寄存器数量L(低8位)
- 如: 从地址0x0001开始读5个输入寄存器
00 01 00 00 00 06 01 03 00 01 00 03 - 响应数据:MBAP + 功能码 + 数据长度 + 寄存器数据
- 如: 读取成功,数据长度为0x06, 第1个数据为0x00A0, 第2个数据为0x0000 第3个数据为0xAAAA
00 01 00 00 00 09 01 03 06 00 A0 00 00 AA AA
0x06:写单个保持寄存器
在一个远程设备中写1个保持寄存器
- 请求数据:MBAP + 功能码 + 寄存器地址H(高8位) + 寄存器地址L(低8位) + 寄存器值H(高8位) + 寄存器值L(低8位)
- 如: 在地址0x0001写入0x00FF
00 01 00 00 00 06 01 06 00 01 00 FF - 响应数据:MBAP + 功能码 + 寄存器地址H(高8位) + 寄存器地址L(低8位) + 寄存器值H(高8位) + 寄存器值L(低8位)
- 如: 写入成功
00 01 00 00 00 06 01 06 00 01 00 FF
0x10:写多个保持寄存器
在一个远程设备中写连续3个保持寄存器
- 请求数据:MBAP + 功能码 + 寄存器起始地址H(高8位) + 寄存器起始地址H(低8位) + 寄存器数量H(高8位) + 寄存器数量L(低8位) + 字节长度 + 寄存器值
- 如: 从地址0x0001开始写入3个保持寄存器值,0x00FF,0xFF00, 0xF0F0
00 01 00 00 00 0D 01 10 00 01 00 03 06 00 FF FF 00 F0 F0 - 响应数据:MBAP + 功能码 + 寄存器起始地址H(高8位) + 寄存器起始地址H(低8位) + 寄存器数量H(高8位) + 寄存器数量L(低8位)
- 如: 写入成功
00 01 00 00 00 06 01 10 00 01 00 03
ModbusTCP通信
通信方式
modbus设备可分为主站(poll)和从站(slave)。主站只有一个,从站有多个,主站向各从站发送请求帧,从站给予相应。在使用TCP通信时,主站为客户端(client),主动建立连接;从站为服务端(server),等待连接。
- 主站请求:功能码+数据
- 从站正常响应:请求功能码+响应数据
- 从站异常响应:异常功能码+异常码,其中异常功能码即将请求功能码的最高有效位置1,异常码指示差错类型
- 注意:需要超时管理机制,避免无期限的等待可能不出现的应答
异常码
异常功能码即将请求功能码的最高有效位置1
- 01:非法功能
对于服务器(或从站)来说,询问中接收到的功能码是不可允许的操作,可能是因为功能码仅适用于新设备而被选单元中不可实现同时,还指出服务器(或从站)在错误状态中处理这种请求,例如:它是未配置的,且要求返回寄存器值。
- 02:非法数据地址
对于服务器(或从站)来说,询问中接收的数据地址是不可允许的地址,特别是参考号和传输长度的组合是无效的。对于带有100个寄存器的控制器来说,偏移量96和长度4的请求会成功,而偏移量96和长度5的请求将产生异常码02。
- 03:非法数据值
对于服务器(或从站)来说,询问中包括的值是不可允许的值。该值指示了组合请求剩余结构中的故障。例如:隐含长度是不正确的。modbus协议不知道任何特殊寄存器的任何特殊值的重要意义,寄存器中被提交存储的数据项有一个应用程序期望之外的值。
- 04:从站设备故障
当服务器(或从站)正在设法执行请求的操作时,产生不可重新获得的差错。
- 05:确认
与编程命令一起使用,服务器(或从站)已经接受请求,并且正在处理这个请求,但是需要长持续时间进行这些操作,返回这个响应防止在客户机(或主站)中发生超时错误,客户机(或主机)可以继续发送轮询程序完成报文来确认是否完成处理。
- 07:从属设备忙
与编程命令一起使用,服务器(或从站)正在处理长持续时间的程序命令,当服务器(或从站)空闲时,客户机(或主站)应该稍后重新传输报文。
- 08:存储奇偶性差错
与功能码20和21以及参考类型6一起使用,指示扩展文件区不能通过一致性校验。服务器(或从站)设备读取记录文件,但在存储器中发现一个奇偶校验错误。客户机(或主机)可重新发送请求,但可以在服务器(或从站)设备上要求服务。
- 0A:不可用网关路径
与网关一起使用,指示网关不能为处理请求分配输入端口值输出端口的内部通信路径,通常意味着网关是错误配置的或过载的。
- 0B:网关目标设备响应失败
与网关一起使用,指示没有从目标设备中获得响应,通常意味着设备未在网络中。
参考资料:
https://wenku.baidu.com/view/c2a9e1cc376baf1ffd4fad5c.html
https://blog.csdn.net/zwxue251/article/details/24154951
https://blog.csdn.net/lakerszhy/article/details/68927178?locationNum=4&fps=1
https://blog.csdn.net/iknow_nothing/article/details/84292914
http://blog.sina.com.cn/s/blog_91a077e50101ina9.html
https://blog.csdn.net/lushoumin/article/details/89073556



