2. Modbus协议核心机制
Modbus 是工业现场最常用的串行/以太网应用层协议之一。它本身不定义物理层,而是把“主站问、从站答”的交互规则、数据模型和错误处理方式固定下来。理解 Modbus 的关键,不是背功能码表,而是先分清三种传输方式如何把同一套协议数据单元(PDU)封装成不同的帧,再理解功能码如何映射到四类数据区,最后掌握异常响应的判断方法。
一、三种传输方式:同一 PDU,不同封装
Modbus 的核心是 PDU:功能码 + 数据。例如读保持寄存器请求的 PDU 是 03 00 00 00 02,其中 03 是功能码,后面是起始地址和数量。三种传输方式在 PDU 前后加上不同字段,形成 ADU(应用数据单元)。
Modbus RTU 使用二进制编码,帧与帧之间靠至少 3.5 个字符时间的静默间隔分隔。典型帧结构为:从站地址(1 字节)+ PDU + CRC16 校验(2 字节,低字节在前)。例如从站 1 读 40001 开始的 2 个保持寄存器,请求帧为 01 03 00 00 00 02 C4 0B。RTU 效率高,是串行现场最常用的方式。
Modbus ASCII 把每个字节用两个 ASCII 字符表示,帧以冒号 : 开始,以 CRLF 结束,并带 LRC 校验。例如同样的请求会变成 :010300000002FA\r\n。ASCII 可读性好、字符间隔容忍度高,但传输效率约为 RTU 的一半,现代工程中较少使用。
Modbus TCP 在 PDU 前加 7 字节 MBAP 报文头:事务标识(2 字节)、协议标识(2 字节,固定 0)、长度(2 字节)、单元标识(1 字节)。它没有 CRC,因为 TCP/IP 已提供校验和可靠传输。MBAP 中的事务标识用于把请求和响应配对,单元标识在网关场景中常用来标识后端串行从站。
二、功能码与四类数据区
Modbus 把从站数据抽象为四类数据区,用“区号 + 地址”定位。功能码决定操作哪类区、是读还是写。工程中最常用的功能码如下:
| 功能码 | 名称 | 数据区 | 地址范围(协议地址) | 常用 PLC 地址 |
|---|---|---|---|---|
| 01 | 读线圈 | 线圈(可读写位) | 0x0000–0xFFFF | 00001–09999 |
| 02 | 读离散输入 | 离散输入(只读位) | 0x0000–0xFFFF | 10001–19999 |
| 03 | 读保持寄存器 | 保持寄存器(可读写字) | 0x0000–0xFFFF | 40001–49999 |
| 04 | 读输入寄存器 | 输入寄存器(只读字) | 0x0000–0xFFFF | 30001–39999 |
| 05 | 写单个线圈 | 线圈 | 0x0000–0xFFFF | 00001–09999 |
| 06 | 写单个寄存器 | 保持寄存器 | 0x0000–0xFFFF | 40001–49999 |
| 15 | 写多个线圈 | 线圈 | 0x0000–0xFFFF | 00001–09999 |
| 16 | 写多个寄存器 | 保持寄存器 | 0x0000–0xFFFF | 40001–49999 |
这里最容易出错的是“协议地址”和“PLC 地址”的偏移。协议帧里出现的地址从 0 开始,而工程习惯用 1 起始的 40001 表示第一个保持寄存器。因此 40001 对应协议地址 0x0000,40002 对应 0x0001。写代码或配置网关时,必须确认工具要求填哪一种,否则会出现整体偏移一位的典型故障。
三、寄存器映射:把设备数据翻译成 Modbus 地址
寄存器映射的本质是“设备内部变量 ↔ Modbus 地址”的对照表。以一台支持 Modbus RTU 的温控器为例,假设其说明书给出如下映射(示例参数,仅用于说明方法):
设备变量 类型 协议地址 功能码 说明
当前温度 输入寄存器 0x0000 04 单位 0.1℃,只读
设定温度 保持寄存器 0x0000 03/06 单位 0.1℃,可读写
运行状态 离散输入 0x0000 02 0=停止,1=运行
启停命令 线圈 0x0000 01/05 写 1 启动,写 0 停止
报警代码 输入寄存器 0x0001 04 0=无报警
若主站要读取当前温度,请求 PDU 为 04 00 00 00 01;从站返回 04 02 01 2C,其中 01 2C 是十六进制 300,按 0.1℃ 换算即 30.0℃。若要把设定温度改为 25.0℃,则用功能码 06 写 06 00 00 00 FA,其中 00 FA 是 250,即 25.0℃。可以看到,映射表决定了“地址 + 功能码 + 数据格式”三要素,缺一不可。
四、异常响应:从站如何告诉主站“我做不到”
当从站无法正常执行请求时,它不会沉默,而是返回异常响应。异常响应的 PDU 结构为:功能码最高位置 1 + 异常码。例如功能码 03 的异常响应功能码是 0x83(03 | 0x80)。常见异常码包括:
- 01 非法功能:从站不支持该功能码,例如只支持 03/06 却收到 16。
- 02 非法数据地址:请求的地址超出从站映射范围,例如访问 0x0100 但设备只有 0x0000–0x000F。
- 03 非法数据值:写入的值不合法,例如设定温度超出允许范围。
- 04 从站设备故障:从站执行时发生内部错误。
- 05 确认:从站已接受请求但需要较长时间处理,主站应稍后重试。
- 06 从站忙:从站正在处理长任务,暂时无法响应。
- 0B 网关目标设备无响应:网关后面的串行从站没有应答,常见于接线、波特率或站号错误。
排查时,先看异常码,再回到请求帧核对功能码、地址、数量和值。例如收到 83 02,说明功能码 03 被识别,但地址越界,应检查映射表地址范围;收到 83 0B,则问题多半在网关后端链路,而不是 Modbus TCP 本身。