对于使用 Modbus 作为其通信协议的各种设备,您会发现关于如何访问这些设备中不同类型的数据的许多不同的解释、术语和标签。有时,设备手册可能仅提及支持的 Modbus 功能代码以及这些功能代码可用的偏移范围。聚英电子逐步介绍 Modbus 功能代码的细节以及它们与寻址的关系,以及它们如何影响在 Wonderware 应用程序的 TOP Server 中使用的地址。
TOP 服务器支持的 Modbus 功能码
Modbus 中的功能代码 (FC) 是 Modbus 请求中使用的特定代码,用于告诉 Modbus 从设备访问哪种类型的内存(即保持寄存器、输入线圈等)以及对该内存执行什么操作(即读取或写作)。下表列出了TOP Server Modbus Suite中包含的所有 Modbus 驱动程序用于通信的特定 Modbus 功能代码:
根据您从客户端应用程序读取或写入的地址类型(保持寄存器、内部寄存器、输入线圈或输出线圈),这将决定 TOP 服务器 Modbus 驱动程序将在对您的实际协议请求中使用哪些特定功能代码设备。
TOP 服务器 Modbus 驱动程序中还有一些特殊设置,可以为设备中的不同 Modbus 实现提供更大的灵活性,我们将在稍后介绍。
而且,虽然我们不会在这篇文章中详细介绍,但 TOP 服务器中的 Modbus 灵活性更进一步,它支持特定非标准驱动程序中的 Modbus 变体,例如Enron Modbus、OMNI Flow、Lufkin ELAM、Honeywell UDC和甚至是基于 Yaskawa Memobus 的驱动程序。
Modbus 功能代码如何对应寻址
正如我们上次提到的,当我们谈论 Modbus 协议和寻址特定数据位置(或内存类型)时,通常有四种不同类型的 Modbus 地址:
保持寄存器——具有读/写访问权限的 16 位(模拟)地址 (4xxxxx)
内部寄存器——具有只读访问权限的 16 位(模拟)地址 (3xxxxx)
输入线圈——具有只读访问权限的 1 位(布尔)地址 (1xxxxx)
输出线圈——具有读/写访问权限的 1 位(布尔)地址 (0xxxxx)上次我们还讨论了很多设备文档并不总是根据地址类型(例如 4xxxx 或保持寄存器)提供 Modbus 地址的详细列表。
因此,由于我们正在更深入地讨论 Modbus 功能代码,因此我们必须根据特定地址的内存类型以及它是否可以读取和写入或只能读取来讨论 Modbus 地址从。
这两个因素决定了向设备发送请求时将使用哪个 Modbus 功能代码。 让我们讨论每个功能代码及其执行的相应地址和功能:
Modbus 功能代码 1 (Hex 0x01)
当请求读取一个或多个(一次最多 2000 个)输出线圈或 0xxxxx 类型的离散/布尔地址时,TOP 服务器使用此功能代码。
输出线圈是读/写访问 - 您将在列表的下方看到对功能代码 5 和 15 的支持。
Modbus 功能代码 2 (Hex 0x02)
当请求读取多个(一次最多 2000 个)输入线圈或 1xxxxx 类型离散/布尔地址中的一个时,TOP 服务器使用此功能代码。
输入线圈在 Modbus 设备中是只读的,因此您会注意到没有指定用于写入 1xxxxx 类型地址的功能代码。
Modbus 功能代码 3 (Hex 0x03)
当请求读取一个或多个(一次最多 125 个)保持寄存器或 4xxxxx 类型的模拟地址时,TOP 服务器使用此功能代码。
也可以使用功能代码 3 访问保持寄存器中的各个位,只需在末尾附加一个 .x 语法,其中 x 表示您希望读取的寄存器中的位(即 400001.0 将访问保持寄存器偏移 1 中的位 0) .
因为保持寄存器是大多数支持 Modbus 的设备中最常支持的内存类型,所以 Modbus 功能代码 3 可能是使用最广泛的功能代码。
并且保持寄存器是读/写访问 - 因此您将在列表的下方看到对功能代码 6 和 16 的支持。
Modbus 功能代码 4 (Hex 0x04)
当请求读取一个或多个(一次最多 125 个)内部寄存器或 3xxxxx 类型的模拟地址时,TOP 服务器使用此功能代码。
与保持寄存器一样,也可以使用功能代码 4 *u,e, 300004.2 访问内部寄存器中的各个位 1) - 稍后继续阅读以获取基于 1 与 0 的位寻址的信息寄存器内。
与输入线圈一样,内部寄存器在 Modbus 设备中是只读的,因此您不会看到指定用于写入 3xxxxxx 类型地址的功能代码。
笔记: 是的,如果您注意到,FC 3 用于访问 4xxxxx 地址,FC 4 用于访问 3xxxxx 地址,就像 FC 1 访问 0xxxxx 和 FC 2 访问 1xxxxx 地址一样——这些不是印刷错误。
Modbus 功能代码 5 (Hex 0x05)
此功能代码由 TOP 服务器在写入单个输出线圈 (0xxxxx) 时使用 - 也称为“强制”线圈。
Modbus 功能代码 6 (Hex 0x06)
此功能代码由 TOP 服务器在写入单个保持寄存器 (4xxxxx) 时使用 - 也称为“预置”寄存器。
Modbus 功能代码 15 (Hex 0x0F)
此功能代码由 TOP 服务器在写入(强制)多个输出线圈 (0xxxxx) 时使用。现在,某些设备仅支持 FC 15 对输出线圈进行单次和多次写入的情况并不少见。
为了解决这种情况,TOP 服务器 Modbus 驱动程序在设备设置中有一个特殊设置,用于禁用“Modbus 功能 05” - 当禁用时,驱动程序将仅使用 FC 15 对输出线圈的所有写入。
Modbus 功能代码 16 (Hex 0x10)
此功能代码由 TOP 服务器在写入(预设)多个保持寄存器 (4xxxxx) 时使用。与 FC 15 一样,设备制造商仅支持 FC 16 以对保持寄存器进行单次和多次写入的情况并不少见 - 这是一种更便宜的实施方式,只需添加对一个与两个功能代码的支持。
针对这种情况,TOP 服务器 Modbus 驱动程序中还有一个设置,允许您禁用“Modbus 功能 06”,这样,当禁用时,驱动程序将仅使用 FC 16 对保持寄存器的所有写入。
Modbus 功能代码 22 (Hex 0x16)
此功能专门用于单个事务中保持寄存器 (4xxxxx) 中的位写入 - 默认情况下,在 TOP 服务器的 Modbus 驱动程序设备属性中禁用它,因为许多 Modbus 设备不支持 FC 22、选择代替支持另一种方法。
另一种方法是默认和最常用的方法,即对保持寄存器中的位执行读/修改/写操作。
在此方法中,当客户端应用程序请求写入保持寄存器位时,会发生以下情况:
正如您可能已经猜到的那样,这种常用方法存在一些风险,特别是如果您的 Modbus 设备中的寄存器值经常更改 - 执行读取/修改/写入操作可能会将位更改为不正确的状态,如果它们之前已更改操作完成所需的时间。
例如,假设我们正在对 400001 的第 1 位执行读取/修改/写入操作。如果第 2 位在操作开始时为“on”,但在写入之前已切换为“off”,则它将是再次错误地“打开”。
FC 22 旨在通过直接修改保持寄存器中的各个位来避免这种风险,而周围的位保持不变。问题是 FC 22 只有在实际的 Modbus 从设备实现了对 FC 22 的支持时才能使用,而这种情况通常并非如此。
因此,请务必确认您的设备是否真的支持 FC 22 - 如果支持,您可以在 TOP 服务器的 Modbus 驱动程序的设备属性中启用“Holding Register Bit Writes”。
TOP 服务器将对整个寄存器执行 FC 3 读取
然后驱动程序只修改有问题的位(这会改变该保持寄存器的 16 位值的整体值)
然后使用 FC 6 或 16 将修改后的 16 位值写回 Modbus 从设备(取决于您的设备支持什么以及根据刚才描述的特殊设置启用什么)。因此,该函数确定正在访问哪种类型的内存以及它是读操作还是写操作。但是功能代码与 Modbus 请求中的其他信息一起使用,包括所谓的偏移量。
偏移寻址如何与 Modbus 功能代码一起使用
TOP Server Modbus Suite 驱动程序支持不同内存类型的以下地址范围:
持有登记册 – 400001- 465536
内部寄存器 – 300001- 365536
输入线圈 – 100001- 165536
输出线圈 – 000001- 065536所以我们支持所有内存类型的偏移量 1 到 65,536。但什么是偏移量?
我通常解释偏移量的方式是,您必须查看地址的第一个数字(即 4、3、1 或 0)来告诉驱动程序访问哪种类型的内存。第一个数字之后的所有内容都是偏移量 - 您在该内存类型中感兴趣的特定内存地址。
Modbus 保持寄存器偏移Modbus 文件说:TOP 服务器说它支持:400140000140001400001
Modbus 功能代码和偏移量在 Modbus 请求中协同工作,以告知设备应返回或修改的特定信息。
什么是 Modbus 从零与从一的寻址?
在讨论基于偏移的 Modbus 寻址时,最后一个重要的细节是设备是否支持基于零或一的寻址。最初,从零开始的寻址是 Modbus 的预期实现方式。但是,随着时间的推移和 Modbus 作为一种开放协议被如此广泛地采用,某些设备制造商采用了一种称为 one-based 寻址的概念。
从零开始的寻址涉及从零开始的内存类型的第一个偏移量。因此,例如,如果您请求保持寄存器 400001,则实际的 Modbus 协议请求将为偏移量 0 的 FC 3。而 400002 将请求偏移量 1 的 FC 3,依此类推。
正如您可以想象的那样,这可能会令人困惑。因此,一些制造商采用了一种称为基于一的寻址的实现方式。对于从 1 开始的寻址,偏移量与实际地址请求对齐。例如,如果您请求保持寄存器 1,则该请求仍然使用 FC 3,但用于偏移量 1。而 400002 将请求 FC 3 用于偏移量 2,依此类推。它更加“用户友好”。
但是,由于有些设备支持从零开始寻址,而有些设备支持从一开始的寻址,因此了解这一点很重要。TOP 服务器 Modbus 驱动程序有一个可配置的设置,用于指定您的 Modbus 从设备支持的实现。
“基于零的寻址”的默认设置已启用,因为这是 Modbus 规范的默认设置。将此设置切换为禁用将导致驱动程序使用基于 1 的寻址。始终确保您使用的是正确的设置,否则意味着显示的值可能是您设备中的错误地址。
例如,如果您读取 400001 的值,并且与您期望的值相比,它是“错误”值,请查看它是否是 400001 旁边的寄存器的值。如果是,您需要从 1 交换为从零开始寻址(反之亦然)。
此外,还有基于 1 或基于 0 的位寻址。默认情况下,TOP Server Modbus 驱动程序也支持从零开始的位寻址,因为它是 Modbus 规范的默认设置。这意味着位的寻址范围为 0 到 15。
基于 1 的位寻址意味着位从 1 到 16 寻址——同样,对于计算 16 位的人来说,这感觉更自然。而且,TOP Server Modbus 驱动程序有一个可配置的设置,这取决于您的设备支持什么。
与偏移寻址一样,在 TOP Server 中选择的位寻址方法必须与您的设备支持的匹配 - 否则,如果不正确,您将访问的位值将用于错误的位。该设置应为 0-15 位访问启用,或应为 1-16 位访问禁用。
始终查阅制造商的文档或与制造商交谈以确定他们支持的方法。如果您注意到某位“开启”但应该“关闭”(反之亦然),您可能需要切换此设置。
正如您所看到的,Modbus 有很多怪癖,因为它是一个如此完善和广泛使用的开放协议。一个灵活的 Modbus 主站,如 TOP 服务器,提供了一系列可配置的设置(包括交换字节、字和双字排序,将在以后的文章中介绍)以与最广泛的 Modbus 从站实现一起工作,无论制造商如何,以获得最大的兼容性。