MODBUS

简介

在阅读此页之前,请确保您已阅读Modbus RTU 基础知识Modbus TCP/IP 基本知识,并且非常了解如何将二进制和浮点数转换为十六进制。点击此处获取涵盖所有基础知识的长篇总结,或者您可使用下述工具。

Modbus是最古老的工业协议之一,由于其设置简单,因此在Alicat中用作工业协议的入门步骤,并且可在我们的设备上使用Modbus,无需更改硬件,只需定制固件即可。

工具

许多工具可随时满足您的Modbus需求。以下为几个要点:

Modbus Poll

Modbus Poll是Modbus主站设备模拟程序,通常用于Modbus从站设备的开发。这是一种可通过个人电脑与一些Modbus设备进行通信的便捷方式。可下载免费试用版。Alicat的Modbus软件许可证数量有限,目前都在使用中。

Realterm

Realterm是一个开放源代码的串行捕获程序,可以多种不同的方式进行通信。它的作用之一是发送Modbus命令。

由于此程序免费且易于使用,因此所有示例都将使用该模型。

如需设置与Alicat设备一起使用的RealTerm,请执行以下操作:

  • 在显示界面下,将“显示为”改为“十六进制[间隔]”,然后选择“半双工”
  • 在端口界面下,将“波特率”改为“19200”,然后选择设备所连接的COM端口。在打开程序之前,必须将设备连接至COM端口,该选项可选。
  • 在发送界面下,在“EOL”中选择“+crc”,在“/n”中选择“前部”和“后部”。然后选择“Modbus 16”。

IEEE浮点转换器

IEEE 浮点转换器程序无法通过Modbus进行通信,但IEEE浮点转换器是数制和基数的有效转换工具。该工具使用方便,也可使用在线工具轻松对数制进行转换。

Windows计算器

当在编程模式下使用时,Windows计算机自带的计算器也对数制和基数的转换非常有益。

如需进入编程模式,请从下拉菜单中选择编程模式。这将打开一个界面稍长的计算器,允许您输入十六进制、十进制(又称为“以10为基数”)、八进制(“以8为基数”)或二进制数,然后计算器将自动输出其他三种数制的数字。例如,如果您单击“DEC”并输入1203,计算器将输出十进制数120310的十六进制、八进制和二进制数。

Modbus帧结构

Modbus帧结构分为6个部分:

静默→地址→命令→数据→CRC→静默

静默

必须通过28位(3.5字节)的空值缓冲存储Modbus RTU。假定一个无限空值。当使用19200波特率时,无限空值可能只有1.46ms长,但该无限空值不能小于这个时间长度。如若不存在该种静默,则这些帧结构将被解释为单命令或响应的一部分,且结果无意义。

地址

所有Modbus命令都包含接收命令或响应命令设备的地址。假定我们发送以下命令:

01 03 00 00 00 02 C4 0B

开头的01是接收我们所发送命令的设备地址。

随后,设备可能会响应:

01 03 04 FF FF FF FF FB A7

开头的01是发出响应的设备地址。

命令

我们将在下面详细讨论命令的有关细节。现在,我们只需知道每个Modbus命令有一个两位数的数字代码。当一个命令发送成功时,Modbus从站设备重复该命令(不会做出更改)。

例如,假定我们发送以下命令:

01 03 00 00 00 02 C4 0B

此处的03是命令。

如命令发送成功,我们可能会收到:

01 03 04 FF FF FF FF FB A7

设备将重复此处的03,且不会做出更改。命令中的错误将导致设备使用不同的数字进行应答。

数据

Modbus数据帧中最长的部分通常是数据。数据可以是命令参数或读数。例如,如果我们请求从0000开始的0002数据寄存器中的数据,则我们将发送以下命令。

01 03 00 00 00 02 C4 0B

然后我们将收到一个命令,其中包含所请求的数据。

01 03 FF FF FF FF FB A7

在本例中,我们已收到04字节的数据:FF FF FF FF,表示寄存器未被使用。当读取任何未使用的寄存器时,Alicats返回FF。因此,我们读取了两个未使用的寄存器。

CRC

“CRC”=循环冗余校验

CRC是一种检错码。它使用消息的其余部分进行计算并将其附加到帧中。这种计算可以在一些程序中自动完成,如RealTerm程序。您只需选择一个框,要求它将循环冗余校验附加到行尾(EOL)。

例如,当我们发送:

01 03 00 00 00 02 C4 0B

最后4个字符(两个字节)是CRC。

然后,我们可能会收到:

01 03 04 FF FFFF FF FB A7

基于响应消息内容而产生独自的CRC。

数据传输均会用到循环冗余校验。高速硬盘、手机和互联网均用到循环冗余校验。例如Modbus TCP,由于其使用的TCP报文已带有独自CRC ,因此Modbus TCP的帧中并未使用CRC。

CRC精致简练,但又细致复杂。了解CRC可帮助您理解一些关于计算机通信的实用知识,以及二进位算术和有限代数相关的知识,时间有限,我们在演示中暂时略过这些内容。如果您想了解更多内容,请看下面的视频(时长为47分钟,应预先做好准备!)。

Modbus命令

Modbus命令不多。Modbus只定义了八个命令(又称为“功能代码”)。

1 读取线圈
2 读取离散输入
3 读取保持寄存器
4 读取输入寄存器
5 写入单个线圈
6 写入单个保持寄存器
15 写入多个线圈
16 写入多个保持寄存器

Alicat只使用3、4和16。即便如此,Alicat对3和4的处理方式相同!

读取寄存器

功能命令03的工作原理如下:

  1. 发送您正在寻址的设备ID
  2. 使用命令(03)对其进行跟随
  3. 然后是您将要读取的第一个Modbus寄存器(2字节)
  4. 随后是您将要读取的连续寄存器个数(2字节)
  5. 不要忘记使用您的程序计算CRC!

查看《Modbus手册》中的寄存器号列表。此处有一部分列表:

1.5.1    质量流量控制器

寄存器编号 统计数据
1203-04 压力
1205-06 流动温度
1207-08 容积流量
1209-10 质量流量
1211-12 质量流量设定点
1213-14 质量总计*

*质量总计仅适用于配有累加器的机组。

示例1

读取温度

假设装置的Modbus ID是01,我们知道帧的开头为地址(01)和读取命令(03)。

01 03

从上表可以看出,流动温度存储于两个寄存器中:1205和1206寄存器。第一个寄存器1205对应的Modbus地址为1204,然后将其转换为十六进制为4B4。加上前述内容,我们得到:

01 03 04 B4

最后,我们通过使用同一列表,发现要读取的寄存器数量为2。以下是完整命令:

01 03 04 B4 00 02

本程序自动计算出85 1D的CRC,并且我们可能会收到以下响应:

01 03 04 41 C2 E0 00 06 33

这表明设备1(01)已接受读取命令(03),现在将返回4字节的数据(04)。后面的4个字节,即41 C2 E0 00被转换成十进制数24.359375,这是温度值,单位为℃。最后一部分(06 33)为CRC。

注意:RealTerm中通过在数字前加上“0x”前缀来表示十六进制数。

示例2

读取气体选择

假设设备的Modbus ID是01,我们知道帧的开头为地址(01)和读取命令(03)。

01 03

根据《Modbus 手册》第4页的内容,我们知道可从Modbus寄存器1200中读取气体,该寄存器对应的Modbus地址为1199,该地址以十六进制表示为4AF。至此,我们得到:

01 03 07 CF

气体寄存器是一个1字节的单寄存器,向本命令中添加00 01:

01 03 07 CF 00 01

本程序自动计算出B5 1B的CRC,并且我们可能会收到以下响应:

01 03 02 00 0A 38 43

这表明设备1(01)已接受读取命令(03),现在将返回2字节的数据(02)。后面的2个字节,即00 0A转换为十进制为10,根据我们的气体表,00 0A代表氖气。最后一部分(38 43)为CRC。

注意:示例2中的响应比示例1短,因为仅报告了1个字节来指示气体选择。

写入寄存器

功能命令16的工作原理如下:

  1. 发送您正在寻址的设备ID
  2. 使用命令(10)对其进行跟随
  3. 然后是您将要写入的第一个Modbus寄存器(2字节)
  4. 随后是您将要读取的连续寄存器个数(2字节)
  5. 然后将该值写入那些寄存器(尺寸相关)
  6. 不要忘记使用您的程序计算CRC!

查看《Modbus手册》中的寄存器号列表。

每个命令的格式如下:

Modbus ID→命令→第一个要写入的寄存器→要写入寄存器的数量→发送的字节数量→要写入寄存器的值→CRC

示例1

写入设定点2.000

假设Modbus ID为01。根据所要写入的内容,我们使用命令10。可从寄存器1010开始更改设定点,寄存器1010对应的Modbus地址为1009,以十六进制表示为3F1。设定点横跨两个寄存器,对应4个字节。最后,我们输入所需的值2.000,以十六进制表示为40 00 00 00。注意:将根据设备上当前选择的任一工程机组接收设定点。

总结:

Modbus ID=1 → 01

命令=16(十进制)→ 10

要写入的第一个地址=1009 → 03 F1

要写入的寄存器数量=2 → 02

发送的字节数量=4 → 04

要写入的值=2.000(十进制)→ 40 00 00 00

CRC(由程序自动完成)

最终命令:01 10 03 F1 00 02 04 40 00 00 00

发送命令后,我们可能会收到:

01 10 03 F1 00 02 10 7F 这表明Modbus 机组1(01)已收到一个针对Modbus地址1009(3F1)的写入命令(10),其长度为2字节(00 02)。10 7F为CRC。注意:响应不包括写入寄存器的值。

示例2

显示锁定

假设Modbus ID为01。根据所要写入的内容,我们使用命令10。Modbus命令相当于写寄存器1000和1001,这两个寄存器对应的起始Modbus地址为999,以十六进制表示为3E7。由于我们试图使用锁定/解锁命令,因此我们要将7写入寄存器1000,并将数字1所代表的锁定写入寄存器1001。

总结:

Modbus ID=1 → 01

命令=16(十进制)→ 10

要写入的第一个地址=1009 → 03 E7

要写入的寄存器数量=2 → 02

发送的字节数量=4 → 04

要写入的值=7 1(十进制)→ 00 07 00 01

CRC(由程序自动完成)

最终命令:01 10 03 E7 00 02 04 00 07 00 01

发送命令后,我们应该收到:

01 10 03 E7 00 02 F1 BB 这表明Modbus ID 1(01)已收到一个针对地址999(03 E7)的写入命令(10),其长度为2字节(00 02)。F1 BB为CRC。

完成后不要忘记解锁显示

错误代码

如果一个命令(又称为“功能代码”)没有正确执行,则Modbus将返回一个错误。

功能代码 异常响应
基数10 Hex 基数10 Hex
01 01 129 81
02 02 130 82
03 03 131 83
04 04 132 84
05 05 133 85
06 06 134 86
07 07 135 87
08 08 136 88
09 09 137 89
10 0A 138 8A
11 0B 139 8B
12 0C 140 8C
13 0D 141 8D
14 0E 142 8E
15 0F 143 8F
16 10 144 90

错误代码将以十六进制(hex)形式出现,以此取代所使用的命令。第一个错误代码将告诉我们哪个命令出错。第二个错误代码告诉我们出错原因。

代码 错误 含义
01 非法功能 用户发送了一个我们不使用的命令功能代码
02 非法数据地址 查询中收到的寄存器地址并非设备所允许的地址
03 非法数据值 数据中包含的值并非从站设备允许值
04 从站设备故障 从站设备尝试执行请求操作时出现不可恢复的错误
06 从站设备忙碌 从站设备正在处理一个耗时的命令。主站设备应稍后再试。

示例1

命令:

01 01 00 13 00 25

响应:

01 81 01

我们向Modbus从站设备1发送了一个读取线圈命令。该响应告诉我们Modbus从站设备1(01)在命令01(81)上出现错误,因为这是该设备(01)上的非法功能。回忆前述内容,Alicat设备不使用读取线圈命令。

示例2

命令:

01 03 12 03 00 12

响应:

01 83 02

我们向Modbus从站设备1发送了一个读取命令。该响应告诉我们Modbus从站设备1(01)在命令03(83)上出现错误,因为该地址并非设备(02)所允许的地址。

示例3

命令:

01 10 03 F1 00 02 04 42 C8

响应:

01 90 03

我们向Modbus从站设备1发送了一个写入命令,将设定点更改为100.0。该响应告诉我们Modbus从站设备1(01)在命令16(10)上出现错误,因为写入的值无效(03)。其原因在于100.0的设定点对于所使用的设备而言过大。

更多产品信息请查看质量流量计质量流量控制器压力控制器压力传感器

WordPress Video Lightbox Plugin