电子说
Modbus TCP协议
(1)、Modbus TCP数据帧:
在TCP/IP以太网上传输,支持Ethernet II和802.3两种帧格式。图3所示,Modbus TCP数据帧包含报文头、功能代码和数据3部分。
图6:TCP/IP上的MODBUS的请求/响应
(2)、MBAP报文头描述:
MBAP报文头(MBAP、Modbus Application Protocol、Modbus应用协议)分4个域,共7个字节,如表1所示。
表1:MBAP报文头
域 | 长度(B) | 描述 |
传输标识 | 2 个字节 | 标志某个MODBUS 询问/应答的传输 |
协议标志 | 2 个字节 | 0=MODBUS协议 |
长度 | 2 个字节 | 后续字节计数 |
单元标识符 | 1 个字节 | 串行链路或其它总线上连接的远程从站的识别码 |
(3)、Modbus功能代码:
Modbus功能码分为3种类型,分别是:
(1)公共功能代码:已定义好的功能码,保证其唯一性,由Modbus.org认可;
(2)用户自定义功能代码有两组,分别为65~72和100~110,无需认可,但不保证代码使用的唯一性。如变为公共代码,需交RFC认可;
(3)保留的功能代码,由某些公司使用在某些传统设备的代码,不可作为公共用途。
在常用的公共功能代码中,IBF96支持部分的功能码,详见如下:
功能码 | 名称 | 说明 | |
01 | Read Coil Status | 读取线圈状态 | 1表示高电平, 0表示低电平。 |
03 | Read Holding Register | 读保持寄存器 | 1表示高电平, 0表示低电平。 |
05 | Write Single Coil | 写单个线圈 | 1表示三极管导通, 0表示三极管断开。 |
06 | Write Single Register | 写单个寄存器 | 1表示三极管导通, 0表示三极管断开。 |
15 | Write Multiple Coils | 写多个线圈 | |
16 | Write Multiple Registers | 写多个寄存器 |
(4)、支持的功能码描述
01(0x01)读线圈
在一个远程设备中,使用该功能码读取线圈的1 至2000 连续状态。请求PDU详细说明了起始地址,即指定的第一个线圈地址和线圈编号。从零开始寻址线圈。因此寻址线圈1-16 为0-15。
根据数据域的每个位(bit)将响应报文中的线圈分成为一个线圈。指示状态为1= ON 和0= OFF。第一个数据作为字节的LSB(最低有效位),后面的线圈数据依次向高位排列,来组成8位一个的字节。如果返回的输出数量不是八的倍数,将用零填充最后数据字节中的剩余位(bit)(一直到字节的高位端)。字节数量域说明了数据的完整字节数
功能码01举例,读8通道DI数据,寄存器地址00033~00040:
请求 | 响应 | ||||
字段名称 | 十六进制 | 字段名称 | 十六进制 | ||
MBAP报文头 | 传输标识 | 01 | MBAP报文头 | 传输标识 | 01 |
00 | 00 | ||||
协议标志 | 00 | 协议标志 | 00 | ||
00 | 00 | ||||
长度 | 00 | 长度 | 00 | ||
06 | 04 | ||||
单元标识符 | 01 | 单元标识符 | 01 | ||
功能码 | 01 | 功能码 | 01 | ||
起始地址Hi | 00 | 字节数 | 01 | ||
起始地址Lo | 20 | 输出状态DI7-DI0 | 00 | ||
输出数量Hi | 00 | ||||
输出数量Lo | 08 |
03(0x03)读保持寄存器
在一个远程设备中,使用该功能码读取保持寄存器连续块的内容。请求PDU说明了起始寄存器地址和寄存器数量。从零开始寻址寄存器。因此,寻址寄存器1-16 为0-15。在响应报文中,每个寄存器有两字节,第一个字节为数据高位,第二个字节为数据低位。
功能码03举例,读8通道DI数据,寄存器地址40033:
请求 | 响应 | ||||
字段名称 | 十六进制 | 字段名称 | 十六进制 | ||
MBAP报文头 | 传输标识 | 01 | MBAP报文头 | 传输标识 | 01 |
00 | 00 | ||||
协议标志 | 00 | 协议标志 | 00 | ||
00 | 00 | ||||
长度 | 00 | 长度 | 00 | ||
06 | 05 | ||||
单元标识符 | 01 | 单元标识符 | 01 | ||
功能码 | 03 | 功能码 | 03 | ||
起始地址Hi | 00 | 字节数 | 02 | ||
起始地址Lo | 20 | 寄存器值Hi(0x00) | 00 | ||
寄存器编号Hi | 00 | 寄存器值Lo(DI7-DI0) | 00 | ||
寄存器编号Lo | 01 |
05(0x05)写单个线圈
在一个远程设备上,使用该功能码写单个输出为ON 或OFF。请求PDU说明了强制的线圈地址。从零开始寻址线圈。因此,寻址线圈地址1为0。线圈值域的常量说明请求的ON/OFF 状态。十六进制值0xFF00请求线圈为ON。十六进制值0x0000请求线圈为OFF。其它所有值均为非法的,并且对线圈不起作用。
正确的响应应答是和请求一样的。
功能码05举例,设置通道DO0为ON,也就是为1,寄存器地址00001:
请求 | 响应 | ||||
字段名称 | 十六进制 | 字段名称 | 十六进制 | ||
MBAP报文头 | 传输标识 | 01 | MBAP报文头 | 传输标识 | 01 |
00 | 00 | ||||
协议标志 | 00 | 协议标志 | 00 | ||
00 | 00 | ||||
长度 | 00 | 长度 | 00 | ||
06 | 06 | ||||
单元标识符 | 01 | 单元标识符 | 01 | ||
功能码 | 05 | 功能码 | 05 | ||
输出地址Hi | 00 | 输出地址Hi | 00 | ||
输出地址Lo | 00 | 输出地址Lo | 00 | ||
输出值Hi | FF | 输出值Hi | FF | ||
输出值Lo | 00 | 输出值Lo | 00 |
06(0x06)写单个寄存器
在一个远程设备中,使用该功能码写单个保持寄存器。请求PDU说明了被写入寄存器的地址。从零开始寻址寄存器。因此,寻址寄存器地址1为0。
正确的响应应答是和请求一样的。
功能码06举例,设置通道DO0~DO7全部为1,16进制为0xFF,寄存器地址40001:
请求 | 响应 | ||||
字段名称 | 十六进制 | 字段名称 | 十六进制 | ||
MBAP报文头 | 传输标识 | 01 | MBAP报文头 | 传输标识 | 01 |
00 | 00 | ||||
协议标志 | 00 | 协议标志 | 00 | ||
00 | 00 | ||||
长度 | 00 | 长度 | 00 | ||
06 | 06 | ||||
单元标识符 | 01 | 单元标识符 | 01 | ||
功能码 | 06 | 功能码 | 06 | ||
寄存器地址Hi | 00 | 寄存器地址Hi | 00 | ||
寄存器地址Lo | 00 | 寄存器地址Lo | 00 | ||
寄存器值Hi | 00 | 寄存器值Hi | 00 | ||
寄存器值Lo | FF | 寄存器值Lo | FF |
15(0x0F)写多个线圈
在一个远程设备上,使用该功能码写多个输出为ON 或OFF。请求PDU说明了强制的线圈地址。从零开始寻址线圈。因此,寻址线圈地址1为0。线圈值域的常量说明请求的ON/OFF 状态。数据由16进制换算成二进制按位排列,位值为1请求线圈为ON,位值为0请求线圈为OFF。
功能码15举例,设置通道DO0,DO1为ON,也就是为00000011,寄存器地址00001:
请求 | 响应 | ||||
字段名称 | 十六进制 | 字段名称 | 十六进制 | ||
MBAP报文头 | 传输标识 | 01 | MBAP报文头 | 传输标识 | 01 |
00 | 00 | ||||
协议标志 | 00 | 协议标志 | 00 | ||
00 | 00 | ||||
长度 | 00 | 长度 | 00 | ||
06 | 06 | ||||
单元标识符 | 01 | 单元标识符 | 01 | ||
功能码 | 0F | 功能码 | 0F | ||
开始地址Hi | 00 | 开始地址Hi | 00 | ||
开始地址Lo | 00 | 开始地址Lo | 00 | ||
线圈数量Hi | 00 | 线圈数量Hi | 00 | ||
线圈数量Lo | 02 | 线圈数量Lo | 02 | ||
字节数 | 01 | ||||
输出值 | 02 |
16(0x10)写多个寄存器
在一个远程设备中,使用该功能码写多个保持寄存器。请求PDU说明了被写入寄存器的地址。从零开始寻址寄存器。因此,寻址寄存器地址1为0。功能码16举例,设置通道DO0和DO1的PWM值为5和6,寄存器地址40001:
请求 | 响应 | ||||
字段名称 | 十六进制 | 字段名称 | 十六进制 | ||
MBAP报文头 | 传输标识 | 01 | MBAP报文头 | 传输标识 | 01 |
00 | 00 | ||||
协议标志 | 00 | 协议标志 | 00 | ||
00 | 00 | ||||
长度 | 00 | 长度 | 00 | ||
06 | 06 | ||||
单元标识符 | 01 | 单元标识符 | 01 | ||
功能码 | 10 | 功能码 | 10 | ||
开始寄存器地址Hi | 00 | 开始寄存器地址Hi | 00 | ||
开始寄存器地址Lo | 00 | 开始寄存器地址Lo | 00 | ||
寄存器数量Hi | 00 | 寄存器数量Hi | 00 | ||
寄存器数量Lo | 02 | 寄存器数量Lo | 02 | ||
字节数 | 04 | ||||
寄存器值Hi | 00 | ||||
寄存器值Lo | 05 | ||||
寄存器值Hi | 00 | ||||
寄存器值Lo | 06 |
全部0条评论
快来发表一下你的评论吧 !