Modbus TCP报文协议详解
概述
Modbus TCP是一种基于TCP/IP协议的工业通信协议,广泛应用于PLC、DCS和SCADA系统中。它继承了Modbus协议简单、可靠的特点,同时利用了以太网的高速和灵活性。
Modbus TCP报文结构
MBAP报头
Modbus TCP报文由MBAP(Modbus Application Protocol)报头和PDU(Protocol Data Unit,协议数据单元)组成。MBAP报头长度为7个字节,包含以下字段:
- 事务标识符(Transaction Identifier,2字节):用于请求和响应的配对。
- 协议标识符(Protocol Identifier,2字节):固定为0,表示Modbus协议。
- 长度(Length,2字节):后续数据的长度,包括单元标识符和PDU。
- 单元标识符(Unit Identifier,1字节):用于多从站的标识,在TCP/IP中通常为0。(注意,如果有多个从站,这个值必须为各个从站指定的地址)
协议数据单元(PDU)
PDU由功能码和数据字段组成:
- 功能码(Function Code,1字节):指定要执行的操作,例如读写寄存器。
- 数据字段(Data,N字节):包含与功能码相关的参数或数据。
常用功能码
- 0x01:读线圈状态
- 0x02:读离散输入状态
- 0x03:读保持寄存器
- 0x04:读输入寄存器
- 0x05:写单个线圈
- 0x06:写单个保持寄存器
- 0x0F:写多个线圈
- 0x10:写多个保持寄存器
报文示例
读保持寄存器请求报文
假设需要从地址为0x0000的寄存器开始读取10个保持寄存器,构建的请求报文如下:
-
MBAP报头
- 事务标识符:0x0001
- 协议标识符:0x0000
- 长度:0x0006(后续6个字节)
- 单元标识符:0x01
-
PDU
- 功能码:0x03
- 起始地址:0x0000
- 数量:0x000A
完整报文(16进制表示):
00 01 00 00 00 06 01 03 00 00 00 0A
00 01 00 00 00 06 01 03 00 00 00 0A
事务标识符 协议标识符 长度 单元标识符 功能码 起始地址 寄存器数量
响应报文
假设从站返回的数据为20个字节,对应10个保持寄存器的值:
-
MBAP报头
- 事务标识符:0x0001
- 协议标识符:0x0000
- 长度:0x0015(后续21个字节)
- 单元标识符:0x01
-
PDU
- 功能码:0x03
- 字节数:0x14(20个字节)
- 数据:20个字节的寄存器值
完整报文(16进制表示):
00 01 00 00 00 15 01 03 14 [20字节数据]
00 01 00 00 00 15 01 03 14 [20字节数据]
事务标识符 协议标识符 长度 单元标识符 功能码 字节计数 数据
Python示例代码
使用pymodbus
库实现Modbus TCP通信的示例代码:
from pymodbus.client.sync import ModbusTcpClient
# 创建Modbus TCP客户端
client = ModbusTcpClient('192.168.1.100', port=502)
# 连接到服务器
client.connect()
# 读取保持寄存器,地址从0开始,读取10个寄存器
result = client.read_holding_registers(address=0, count=10, unit=1)
# 检查是否成功读取
if not result.isError():
# 输出读取的寄存器值
print(result.registers)
else:
print("读取失败")
# 写单个保持寄存器,地址为0,值为123
client.write_register(address=0, value=123, unit=1)
# 关闭连接
client.close()
注意事项
- 端口号:Modbus TCP默认使用502端口,需要确保防火墙或路由器未阻挡此端口。
- 单元标识符:在TCP/IP网络中,单元标识符通常设置为0或1,但在一些网关或路由器中可能有特殊含义。
- 异常码处理:从站可能返回异常码,需要在程序中进行处理,确保通信的可靠性。
- 线程安全:在多线程环境中使用Modbus客户端时,需要注意线程安全,可能需要加锁或使用线程安全的客户端实例。
应用场景
- 工业自动化:用于PLC和上位机之间的数据交换。
- 能源管理:在电力、石油等行业,实现对设备的远程监控和控制。
- 楼宇自动化:对暖通空调、照明等系统进行集中控制。
结论
深入理解Modbus TCP报文协议,有助于在工业应用中实现高效可靠的通信。通过掌握报文结构、功能码和异常处理,可以开发出稳定的通信程序,满足各种工业现场的需求。