- Blog
- MODBUS
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的工作原理如下:
- 发送您正在寻址的设备ID
- 使用命令(03)对其进行跟随
- 然后是您将要读取的第一个Modbus寄存器(2字节)
- 随后是您将要读取的连续寄存器个数(2字节)
- 不要忘记使用您的程序计算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的工作原理如下:
- 发送您正在寻址的设备ID
- 使用命令(10)对其进行跟随
- 然后是您将要写入的第一个Modbus寄存器(2字节)
- 随后是您将要读取的连续寄存器个数(2字节)
- 然后将该值写入那些寄存器(尺寸相关)
- 不要忘记使用您的程序计算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的设定点对于所使用的设备而言过大。
艾里卡特Alicat提供先进的质量流量计、质量流量控制器、压力控制器、压力传感器解决方案。
如需查看或下载产品说明书,请点击Alicat文件中心。