MODBUS协议(功能码及报文解析)

更新时间:2023-07-27 15:43:01 阅读量: 实用文档 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

MODBUS协议

Modbus是一种串行通信协议,是Modicon于1979年,为使用可编程逻辑控制器(PLC)而发表的。事实上,它已经成为工业领域通信协议标准,并且现在是工业电子设备之间相当常用的连接方式。Modbus比其他通信协议使用的更广泛的主要原因有:

公开发表并且无版税要求 相对容易的工业网络部署

对供应商来说,修改移动原生的位或字节没有很多限制 Modbus允许多个设备连接在同一个网络上进行通信,举个例子,一个由测量温度和湿度的装置,并且将结果发送给计算机。在数据采集与监视控制系统(SCADA)中,Modbus通常用来连接监控计算机和remote terminal unit (RTU)。

Modbus协议目前存在用于串口、以太网以及其他支持互联网协议的网络的版本。

大多数Modbus设备通信通过串口EIA-485物理层进行[1]。 对于串行连接,存在两个变种,它们在数值数据表示不同和协议细节上略有不同。Modbus RTU是一种紧凑的,采用二进制表示数据的方式,Modbus ASCII是一种人类可读的,冗长的表示方式。这两个变种都使用串行通讯(serial communication)方式。RTU格式后续的命令/数据带有循环冗余校验的校验和,而ASCII格式采用纵向冗余校验的校验和。被配置为RTU变种的节点不会和设置为ASCII变种的节点通信,反之亦然。

对于通过TCP/IP(例如以太网)的连接,存在多个Modbus/TCP变种,这种方式不需要校验和的计算。

对于所有的这三种通信协议在数据模型和功能调用上都是相同的,只有封装方式是不同的。

Modbus 有一个扩展版本 Modbus Plus(Modbus+或者MB+),不过此协定是Modicon专有的,和 Modbus不同。它需要一个专门的协处理器来处理类似HDLC的高速令牌旋转。它使用1Mbit/s的双绞线,并且每个节点都有转换隔离装置,是一种采用转换/边缘触发而不是电压/水平触发的装置。连接Modbus Plus到计算机需要特别的接口,通常是支持ISA(SA85),PCI或者PCMCIA总线的板卡。

Modbus协议是一个 master/slave 架构的协议。有一个节点是 master 节点,其他使用Modbus协议参与通信的节点是 slave 节点。每一个 slave 设备都有一个唯一的地址。在串行和MB+网络中,只有被指定为主节点的节点可以启动一个命令(在以太网上,任何一个设备都能发送一个Modbus命令,但是通常也只有一个主节点设备启动指令)。

一个ModBus命令包含了打算执行的设备的Modbus地址。所有设备都会收到命令,但只有指定位置的设备会执行及回应指令(地址 0例外,指定地址 0 的指令是广播指令,所有收到指令的设备都会执行,不过不回应指令)。所有的Modbus命令包含了检查码,以确定到达的命令没有被破坏。基本的ModBus命令能指令一个RTU改变

它的寄存器的某个值,控制或者读取一个 I/O 端口,以及指挥设备回 送一个或者多个其寄存器中的数据。 有许多 modems 和网关支持 Modbus 协议,因为 Modbus 协议很简 单而且容易复制。 它们当中一些为这个协议特别设计的。 有使用有线、 无线通信甚至短消息和 GPRS 的不同实现。不过设计者需要克服一些 包括高延迟和时序的问题。 MODBUS 通信过程如下图

MODBUS RTU 报文格式起始位 T1-T2-T3-T4 设备地 功能代 址 8Bit 码 8Bit 数据 CRC 校验 结束符 T1-T2-T3-T4

n 个 8Bit 16Bit

MODBUS ASCII 报文格式

起始位 1 个字符

设备地 功能代码 址

数据

LRC 校 验

结束符 2 个字符

2 个字 2 个字 2 个字符 n 个字符 符 符

MODBUS TCP 报文交互标识 2 字节 一般为 0 协议标识 报文长度 设备标识 功能代码 数据

2 字节 2 字节 1 字节 一般为 0 高字节在 也就是设 1 个字符 n 个字符 前 备地址

实际上 MODBUS RTU 与 ASCII 的内容是完全相同的,不同的的 AS CII 方式用“:”标识帧起始,用“CR LF”标识帧结束。校验采用 L RC,把 RTU 帧中一个字节的内容换成了 2 个 ASCII 字符。比如在 RTU 方式下设备地址 01 只有一个字节, 在 ASCII 方式下转换成字符串 “0 1”(16 进制的 30 31 )。 MODBUS TCP 中的设备标识,功能码等与 MODBUS RTU 相同,可以 认为是在 MODBUS RTU 报文的前边加了一个头,去掉了 CRC 校验这个 尾。 MODBUS 协议定义了 4 种基本数据类型:可读写位数据,只读位 数据,只读 16 位数据,可读写 16 位数据。这些数据分别被称为线圈 状态,输入状态,输入寄存器,保持寄存器。

MODBUS 协议中定义的这些数据都是一个从地址 1 开始的数组, 访问时需要指明从哪个地址开始访问,访问多少个数据。下表是 MOD BUS 的功能码。ModBus 功能码 功能 码 01 02 03 04 05 06 名称 读取线圈状态 读取输入状态 读取保持寄存器 读取输入寄存器 强置单线圈 预置单寄存器 作用 取得一组逻辑线圈的当前状态(ON/OFF) 取得一组开关输入的当前状态(ON/OFF) 在一个或多个保持寄存器中取得当前的二进制 值 在一个或多个输入寄存器中取得当前的二进制 值 强置一个逻辑线圈的通断状态 把具体二进值装入一个保持寄存器 取得 8 个内部线圈的通断状态,这 8 个线圈的 地址由控制器决定,用户逻辑可以将这些线圈 定义,以说明从机状态,短报文适宜于迅速读 取状态 08 09 10 回送诊断校验 把诊断校验报文送从机,以对通信处理进行评 鉴

07

读取异常状态

编程(只用于 484) 使主机模拟编程器作用,修改 PC 从机逻辑 可使主机与一台正在执行长程序任务从机通 控

询(只用于 484) 信,探询该从机是否已完成其操作任务,仅在 含有功能码 9 的报文发送后,本功能码才发送 读取事件计数 可使主机发出单询问,并随即判定操作是否成 功,尤其是该命令或其他应答产生通信错误时 可是主机检索每台从机的 ModBus 事务处理通 信事件记录。如果某项事务处理完成,记录会 给出有关错误

11

12

读取通信事件记录

13

编程(184/384 484 可使主机模拟编程器功能修改 PC 从机逻辑 584) 可使主机与正在执行任务的从机通信,定期控 探询(184/384 484 询该从机是否已完成其程序操作,仅在含有功 584) 能 13 的报文发送后,本功能码才得发送 强置多线圈 强置一串连续逻辑线圈的通断

14 15

16 17 18 19 20 21

预置多寄存器 报告从机标识

把具体的二进制值装入一串连续的保持寄存器 可使主机判断编址从机的类型及该从机运行指 示灯的状态 发生非可修改错误后, 是从机复位于已知状态, 可重置顺序字节 显示扩展存储器文件中的数据信息 把通用参数写入扩展存储文件,或修改之

(884 和 MICRO 84) 可使主机模拟编程功能,修改 PC 状态逻辑 重置通信链路 读取通用参数 (584L) 写入通用参数 (584L)

22~ 保留作扩展功能备 64 用 65~ 保留以备用户功能 72 所用 73~ 非法功能 119 120~ 保留 127 128~ 保留 255 留作内部作用 用于异常应答 留作用户功能的扩展编码

各个功能码对应的数据类型 代 功能 码 01 02 03 04 05 读 读 读 读 写 位 位 16 位整型 16 位整型 位 数据类型

06 15 16

写 写 写

整 16 位整型 位 整 16 位整型

MODBUS 协议相当复杂,但是常用的命令也就简单的几个,01,0 2,03,04,05,06,15,16 号命令。

各个命令的功能和报文如下: 01 命令 读取线圈状态 MODBUS 地址 00001~MODBUS 请求 功能码 起始地址 读取数量 MODBUS 响应 功能码 字节计数 线圈状态 N =读取数量/8 错误 响应 功能码 错误代码 举例 请求 域名称 功能码 起始地址高(字节) 起始地址低(字节) 读取数量高(字节) 读取数量低(字节) 数据(hex) 01 00 13 00 13 域名称 功能码 字节计数 27(h)~20 状态 35(h)~28 状态 38(h)~36 状态 响应 数据(hex) 01 03 CD 6B 05 1 1 BYTE BYTE 0X01 N n =N or N+1 1 BYTE 2 BYTE 2 BYTE 0X01 0X0000 TO 0XFFFF 1 TO 2000(0X7D0)

n BYTE 如果余数不为 0 则 N=N+1 1 1 BYTE BYTE

0X01+ 0X80 0x1 or 0x2 or 0x3 or 0x4

02 命令 读取输入状态 MODBUS 地址 10001~

MODBUS 请求 功能码 起始地址 读取数量 MODBUS 响应 功能码 字节计数 输入状态 N =读取数量/8 错误 响应 功能码 错误代码 举例 请求 域名称 功能码 起始地址高(字节) 起始地址低(字节) 读取数量高(字节) 读取数量低(字节) 数据(hex) 02 00 C4 00 16 域

名称 功能码 字节计数 204(h)~197 状态 212(h)~205 状态 218(h)~213 状态 响应 数据(hex) 02 03 AC DB 35 1 1 BYTE BYTE 0X02 N n =N or N+1 1 BYTE 2 BYTE 2 BYTE 0X02 0X0000 TO 0XFFFF 1 TO 2000(0X7D0)

n BYTE 如果余数不为 0 则 N=N+1 1 1 BYTE BYTE

0X02+ 0X80 0x1 or 0x2 or 0x3 or 0x4

03 读保持寄存器

MODBUS 地址 40001~

MODBUS 请求 功能码 起始地址 读取数量 MODBUS 响应 1 BYTE 2 BYTE 2 BYTE 0X03 0X0000 TO 0XFFFF 1 TO 125(0X7D)

功能码 字节计数 输入状态 错误 响应 功能码 错误代码 举例 请求 域名称 功能码 起始地址高(字节) 起始地址低(字节) 读取数量高(字节) 读取数量低(字节)

1 1 N*2

BYTE BYTE BYTE

0X03 N*2

1 1

BYTE BYTE

0X03+ 0X80 0x1 or 0x2 or 0x3 or 0x4

响应 数据(hex) 03 00 6B 00 03 域名称 功能码 字节计数 寄存器高(108) 寄存器低(108) 寄存器高(109) 寄存器低(109) 寄存器高(110) 寄存器低(110) 数据(hex) 03 06 02 2B 00 00 00 64

04 输入寄存器 MODBUS 地址 30001~

MODBUS 请求 功能码 起始地址 读取数量 MODBUS 响应 功能码 字节计数 输入状态 错误 响应 功能码 错误代码 举例 1 1 BYTE BYTE 0X04+ 0X80 0x1 or 0x2 or 0x3 or 0x4 1 1 N*2 BYTE BYTE BYTE 0X04 N*2 1 BYTE 2 BYTE 2 BYTE 0X04 0X0000 TO 0XFFFF 1 TO 125(0X7D)

请求 域名称 功能码 起始地址高(字节) 起始地址低(字节) 读取数量高(字节) 读取数量低(字节) 数据(hex) 04 00 08 00 01 域名称 功能码 字节计数

响应 数据(hex) 04 02 00 0A

输入寄存器高(9) 输入寄存器低(9)

05

设置单个继电器状态

MODBUS 请求 功能码 设置地址 设置内容 1 BYTE 2 BYTE 2 BYTE 0X05 0X0000 TO 0XFFFF 0x0000 OR 0XFF00 0x0000 释放继电器 0xff00 吸合继电器

MODBUS 响应 功能码 设置地址 设置内容 错误 响应 功能码 错误代码 举例(吸合 6 号继电器) 请求 域名称 功能码 设置地址高(字节) 设置地址低(字节) 设置内容高(字节) 设置内容低(字节) 数据(hex) 05 00 05 FF 00 域名称 功能码 设置地址高(字节) 设置地址低(字节) 设置内容高(字节) 设置内容低(字节) 响应 数据(hex) 05 00 05 FF FF 1 1 BYTE BYTE 0X05+ 0X80 0x1 or 0x2 or 0x3 or 0x4 1 BYTE 2 BYTE 2 BYTE 0X05 0X0000 TO 0XFFFF 0x0000 OR 0XFF00

06

设置单个保持寄存器

MODBUS 请求 功能码 设置地址 设置内容 MODBUS 响应 功能码 设置地址 设置内容 错误 响应 功能码 错误代码 举例 设置 9 号保持寄存器内容为 25 请求 域名称 功能码 设置地址高(字节) 设置地址低(字节) 设置内容高(字节) 设置内容低(字节) 数据(hex) 06 00 08 00 19 域名称 功能码 设置地址高(字节) 设置地址低(字节) 设置内容高(字节) 设置内容低(字节) 响应 数据(hex) 06 00 08 00 19 1 1 BYTE BYTE 0X06+ 0X80 0x1 or 0x2 or 0x3 or 0x4 1 BYTE 2 BYTE 2 BYTE 0X06 0X0000 TO 0XFFFF 0x0000 to 0XFF00 1 BYTE 2 BYTE 2

BYTE 0X06 0X0000 TO 0XFFFF 0x0000 to 0XFF00

15 设置多个继电器状态MODBUS 请求 功能码 设置起始地址 设置长度 1 BYTE 2 BYTE 2 BYTE 0X0F 0X0000 TO 0XFFFF 0X0000 TO 0X7B0

字节计数 设置内容 MODBUS 响应 功能码 设置起始地址 设置长度 错误 响应 功能码 错误代码 举例 设置继电器 请求 域名称 功能码 设置地址高(字节) 设置地址低(字节) 设置数量高(字节) 设置数量低(字节) 字节计数 设置内容高(字节) 设置内容低(字节)

1 BYTE N BYTE

N

1 BYTE 2 BYTE 2 BYTE

0X0F 0X0000 TO 0XFFFF 0X0000 TO 0X7B0

1 1

BYTE BYTE

0X0F+ 0X80 0x1 or 0x2 or 0x3 or 0x4

响应 数据(hex) 0F 00 13 00 0A 02 CD 01 域名称 功能码 设置地址高(字节) 设置地址低(字节) 设置数量高(字节) 设置数量低(字节) 数据(hex) 0F 00 13 00 0A

16 设置多个保持寄存器MODBUS 请求 功能码 设置起始地址 设置长度 1 BYTE 2 BYTE 2 BYTE 0X10 0X0000 TO 0XFFFF 0X0000 TO 0X7B0

字节计数 设置内容 MODBUS 响应 功能码 设置起始地址 设置长度 错误 响应 功能码 错误代码 举例 设置多个保持寄存器 请求 域名称 功能码 设置地址高(字节) 设置地址低(字节) 设置数量高(字节) 设置数量低(字节) 字节计数 设置内容高(字节) 设置内容低(字节) 设置内容高(字节) 设置内容低(字节)

1 BYTE N*2 BYTE

N*2

1 BYTE 2 BYTE 2 BYTE

0X10 0X0000 TO 0XFFFF 0X0000 TO 0X7B0

1 1

BYTE BYTE

0X10+ 0X80 0x1 or 0x2 or 0x3 or 0x4

响应 数据(hex) 10 00 01 00 02 04 00 0A 01 02 域名称 功能码 设置地址高(字节) 设置地址低(字节) 设置数量高(字节) 设置数量低(字节) 数据(hex) 0F 00 01 00 02

MODBUS 协议在智能设备中的应用 上面讲述了 MODBUS 协议的报文以及命令, 那么在智能设备中如何 使用这个协议呢?

如果智能设备有开关量输入输出,模拟量输入输出,有计数器等。很明显开关量输入可以映射到 10001地址,第一路开关量输入为10001,第二路为10002,

开关量输出映射到 00001地址,第一路为00001,第二路为00002, .

模拟量输入映射到 30001地址,第一路为 30001,第二路为30002,

模拟量输出和计数器输入映射到40001地址,第一路为 40001,第二路为40002,

当然也可以把所有的数据都放在保持寄存器中,这样对于MODBUS主设备访问时要简单,访问效率能提高,但是处理起来略显繁琐。

本文来源:https://www.bwwdw.com/article/yejm.html

Top