问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

Modbus tcp 协议详解

创作时间:
作者:
@小白创作中心

Modbus tcp 协议详解

引用
CSDN
1.
https://m.blog.csdn.net/duwufeng/article/details/143934277

Modbus TCP是一种基于以太网TCP/IP的应用层协议,它保留了Modbus协议的核心功能和数据模型,但对消息封装进行了调整,使其符合TCP/IP的要求。本文将详细介绍Modbus TCP协议的基本概念、存储区、功能码、协议报文结构,并通过工具使用和Java代码示例展示如何模拟主站与从站之间的通信。

1. 相关概念

1.1 Modbus

Modbus是一种广泛应用于工业自动化领域的通信协议。它提供了通用的语言在设备之间建立主从式的通信。Modbus协议简单、开放、易于实现,且支持多种物理层通信介质(RS232、RS485、TCP/IP网络等),因此成为了工业领域通信协议的业界标准之一。我们今天要介绍的是一种基于以太网TCP/IP的应用层协议——Modbus TCP/IP协议。

1.2 Modbus TCP

Modbus TCP是Modbus协议在以太网上的一种实现,它保留了Modbus协议的核心功能和数据模型,但对消息封装进行了调整,使其符合TCP/IP的要求。在进行下一步之前我们首先对Modbus中的一些概念做一个了解。

1.3 存储区

存储的数据类型分为布尔量和寄存器

  • 布尔量:如水阀的开关、灯的开关等数据。
  • 寄存器:如流速、导电率、温湿度、空气浓度等数据。

Modbus规定了4个存储区,分别是0、1、3、4,对应下面表格内容,具体为:

  • 0区:可读可写的布尔量
  • 1区:只读布尔量
  • 3区:只读寄存器
  • 4区:可读可写的寄存器

1.4 功能码

Modbus定义了一系列的功能码,这些功能码表示了主站请求从站执行的具体操作,下面表格是一些常见的功能码,具体为:

  • 读操作

  • 0x01:读输出线圈状态。

  • 0x02:读输入线圈状态。

  • 0x03:读输出寄存器的值。

  • 0x04:读输入寄存器的值。

  • 写操作

  • 0x05:写单个线圈状态。

  • 0x06:写单个寄存器的值。

  • 0x0F:写多个线圈状态。

  • 0x10:写多个寄存器的值。

1.5 协议报文

Modbus TCP/IP的报文被封装在一个标准的TCP数据段内,而不是像串行通信那样直接在物理层上发送。TCP报文提供了端到端的可靠传输,包括数据分段、重传、流量控制和拥塞控制等机制。

Modbus TCP/IP的报文帧主要包括:

  • MBAP头:包含事务标识符、协议标识符、消息长度、设备地址
  • Modbus PDU:原始Modbus协议的数据部分,包括功能码、数据地址和数据值。

下面我们用一个表格来根据一段报文解释这两部分的具体内容:

从上面的报文中我们可以知道:

  • 事务标识符:占2个字节,一次通信的过程中主站和从站的报文帧的事务标识符是一致的。
  • 协议标识符:占2个字节,00 00表示Modbus TCP协议。
  • 后面报文的长度:占2个字节,表示后面报文的长度。
  • 从站地址:占1个字节,表示设备的地址,也就是Salve ID的值。
  • 功能码:占1个字节,例子中的03表示的是读输出寄存器的值。
  • 起始地址:占2个字节,表示从该设备的哪个位置开始读。
  • 读取数量:占2个字节,表示从起始位置往后读的数量。
  • 长度:占2个字节,表示后面还报文的长度。
  • 对应的值:根据不同的存储类型所占的字节不同。

接下来我们通过工具来模拟Modbus TCP通讯。

2. 工具使用

2.1 Modbus Slave

打开软件之后点击菜单栏的Connection→Connect,如图所示:

在弹出的界面选择协议类型为Modbus TCP/IP,输入IP,端口号点击OK

随后点击Setup→Slave Definition...进入从站设置界面

下面我们新建四个不同存储区的窗口来为后面模拟通讯做准备

根据图中任意方式都可以新建窗口。

可以看到四个窗口在从站地址为2,功能码分别为01、02、03、04。

需要注意的是01、02表示的是读输出线圈和输入线圈,只有开关量,对应的数值为1=On,0=Off。

03、04表示的是读输出寄存器和输入寄存器。

好了,接下来我们去使用工具模拟主站来读取从站的数据。在此之前我们可以勾选Auto increment模拟数据处于变化状态。

2.2 Modbus Poll

使用和从站相同的方法连接之后新建四个窗口分别读取,可以看到读取实时数据成功。

也可以通过查看日志确保主机处于正常读取状态。

下面我们通过使用modbus-master-tcp模拟一个主站去和从站之间进行通信。

3. Java模拟主站

3.1 使用modbus-master-tcp库

modbus-master-tcp是基于Netty编写,支持异步与并发。

下面通过Java模拟主站读取从站线圈状态:

Modbus由MODICON公司于1979年开发,是一种工业现场总线协议标准。1996年施耐德公司推出基于以太网TCP/IP的Modbus协议,ModbusTCP。

Modbus通信的设备分为主站(mater)和从站(slave),主站为主动方,从站为被动方。

通信过程

通信的过程为:

  1. 主站设备主动向从站设备发送请求
  2. 从站设备处理主站的请求后,向主站返回结果。
  3. 如果从站设备处理请求出现异常,则向主站设备返回异常功能码。

数据传输方式

modbus的数据传输被定义为对以下4个存储块的读写:

  1. 线圈(coils) 操作单位为1位字的开关量,PLC的输出位,在Modbus中可读可写
  2. 离散量(discreteinputs) 操作单位为1位字的开关量,PLC的输入位,在Modbus中只读
  3. 输入寄存器(inputregisters) 操作单位为16位字(两个字节)数据,PLC中只能从模拟量输入端改变的寄存器,在Modbus中只读
  4. 保持寄存器(holdingregisters) 操作单位为16位字(两个字节)数据,PLC中用于输出模拟量信号的寄存器,在Modbus中可读可写

MODBUS-TCP报文结构

modbus-tcp报文结构:
如上图所示:modbus-tcp的报文由MBAP+PDU组成。

MBAP报文头
其中MBAP报文头的组成为:
域 长度 描述
事务元标识符 2 个字节 MODBUS 请求/响应事务处理的识别码,主要用于在主站设备在接收到响应时能知道是哪个请求的响应
协议标识符 2 个字节 对于MODBUS 协议来说,这里恒为0
长度 2 个字节 以下字节的数量,也就是完整报文的字节数减去6
单元标识符 1 个字节 串行链路或其它总线上连接的远程从站的识别码,也就是要访问的从站的标识号,因为只有一个字节,所以一个主站最多只能访问256个从站设备

由上表可知,报文头为 7 个字节长。

PDU报文体
PDU的组成为功能码(一个字节)和数据(n个字节)

其中功能码为一个字节,modbus定义的功能码有:

  • 01 读线圈(coils)状态,读取单个或多个
  • 02 读离散输入(discreteinputs)状态,读取单个或多个
  • 03 读保持寄存器(holdingregisters),读取单个或多个
  • 04 读输入寄存器(inputregisters),读取单个或多个
  • 05 写单个线圈(coils)状态,单个写入
  • 06 写单个保持寄存器(holdingregisters),单个写入
  • 15 写多个线圈(coils),多个写入
  • 16 写多个保持寄存器(holdingregisters),多个写入

另外,当响应报文的功能码最高位为1时(即:(function & 0x80) != 0),表示为异常响应,这时数据为一个字节的异常码,具体的异常码定义有:

  • 01 功能码不能被从机识别
  • 02 从机的单元标识符不正确
  • 03 值不被从机接受
  • 04 当从机试图执行请求的操作时,发生了不可恢复的错误。
  • 05 从机已接受请求并正在处理,但需要很长时间。返回此响应是为了防止在主机中发生超时错误。主站可以在下一个轮询程序中发出一个完整的消息,以确定处理是否完成。
  • 06 从站正在处理长时间命令。Master应该稍后重试。
  • 07 从站不能执行程序功能。主站应该向从站请求诊断或错误信息。
  • 08 从站在内存中检测到奇偶校验错误。主设备可以重试请求,但从设备上可能需要服务。
  • 10 专门用于Modbus网关。表示配置错误的网关。
  • 11 专用于Modbus网关的响应。当从站无法响应时发送。

PDU报文详情
1、读线圈
请求报文:
正常响应报文:
异常响应报文:

2、读离散输入
请求报文:
正常响应报文:
异常响应报文:

3、读保持寄存器
请求报文:
正常响应报文:
异常响应报文:

4、读输入寄存器
请求报文:
正常响应报文:
异常响应报文:

5、写单个线圈
请求报文:
正常响应报文:
异常响应报文:

6、写单个保持寄存器
请求报文:
正常响应报文:
异常响应报文:

7、写多个线圈
请求报文:
正常响应报文:
异常响应报文:

8、写多个保持寄存器
请求报文:
正常响应报文:
异常响应报文:

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号