伟创H5U系列PLC在工业现场与上位机(如SCADA、HMI、MES系统)通过Modbus TCP协议通信时,寄存器地址映射是数据读写的前提。但很多工程师首次配置时会遇到“明明写了40001却读不到值”“写入40005实际改了Q0.0”等现象——根本原因在于对Modbus协议地址规范与H5U内部寄存器物理布局的双重理解偏差。本文不讲理论套话,只聚焦一个实操痛点:如何正确计算H5U PLC中保持寄存器(Holding Register)的Modbus TCP访问地址,特别是当上位机软件默认使用“+40000基址”时,如何做偏移校准。
一、先搞清两个独立概念:Modbus协议地址 vs H5U物理寄存器编号
Modbus协议本身不定义地址数字含义,它只规定四类寄存器类型及各自编号范围:
| 寄存器类型 | 协议功能码 | 地址编号范围(协议层) | 常见上位机显示格式 |
|---|---|---|---|
| 线圈(Coil) | 0x01 / 0x05 / 0x0F | 00001–65536 | 00001, 00002 … |
| 离散输入(Discrete Input) | 0x02 | 10001–65536 | 10001, 10002 … |
| 输入寄存器(Input Register) | 0x04 | 30001–65536 | 30001, 30002 … |
| 保持寄存器(Holding Register) | 0x03 / 0x06 / 0x10 | 40001–65536 | 40001, 40002 … |
注意:这个40001是协议约定的起始逻辑地址,不是内存物理地址。它仅表示“这是第1个保持寄存器”,用于和其它类型区分。而H5U PLC内部存储这些数据的实际位置,由其硬件架构与固件决定——H5U将保持寄存器统一映射到内部D区(数据寄存器),且起始物理地址为D0。
因此,必须建立二者之间的转换关系。关键结论先行:
H5U中,Modbus协议地址
40001对应内部物理寄存器D0;40002对应D1;40003对应D2……依此类推。
换算公式为:
$$\text{H5U物理寄存器编号} = \text{Modbus地址} - 40001$$
或反向:
$$\text{Modbus地址} = \text{H5U物理寄存器编号} + 40001$$
该公式适用于所有标准保持寄存器读写(功能码03/06/10),且与H5U编程软件(AutoShop V3.x)中D区变量定义完全一致。
二、为什么上位机填40001有时读不到?——常见三类偏移错配场景
场景1:上位机软件自动加40000前缀(最普遍)
多数国产HMI(如威纶通、昆仑通态)、SCADA(如组态王、力控)在配置Modbus TCP设备时,地址输入框默认显示4xxxx,并隐式添加40000基址。例如:
- 你在地址栏输入
1→ 实际发送请求的是40001 - 输入
100→ 实际请求40100 - 输入
0→ 部分软件会报错或请求40000(非法地址,Modbus协议规定从40001开始)
✅ 正确做法:在H5U中预先将需要被读取的变量放入D0起始区域,然后上位机直接填1(对应40001)即可。
❌ 典型错误:用户误以为“40001就是D1”,于是把变量放D1,结果上位机填1去读D0,自然读空。
场景2:上位机启用“地址从0开始”模式(如某些Python库或LabVIEW驱动)
部分Modbus库(如pymodbus)默认以0为起始索引。此时:
client.read_holding_registers(address=0, ...)→ 访问40001client.read_holding_registers(address=1, ...)→ 访问40002
这与H5U的D0→40001完全匹配,无需额外偏移。
⚠️ 但若代码写成 address=40001,则实际访问的是44002(因为40001 + 40001 = 80002,再按协议转为4xxxx需减40000 → 44002),导致严重错位。
场景3:H5U工程中启用了“寄存器地址偏移”功能(高级设置)
在AutoShop V3.2+中,“系统配置”→“通信设置”→“Modbus TCP”页存在一项:
☑ 启用寄存器地址偏移
→ 偏移量:______(默认为0)
此项的作用是:对所有Modbus请求的地址,统一减去该偏移量后再映射到内部D区。
例如设偏移量为100:
- 上位机发
40001→ H5U内部计算为40001 - 100 = 39901→ 映射到D(39901 - 40001) = D(-100)→ 非法,返回异常 - 上位机发
40101→40101 - 100 = 40001→ 映射到D0✅
💡 这项通常用于兼容旧设备地址规划,新项目强烈建议保持偏移量为0,避免混淆。
三、实操验证:5步确认你的H5U Modbus TCP保持寄存器地址是否正确
以下步骤全程使用H5U本体+PC端调试工具(无需额外硬件),耗时<3分钟。
-
在AutoShop中创建测试变量
打开工程 → “变量表” → 新建变量:- 名称:
TEST_REG - 类型:
DINT(双整数,占2个字) - 地址:
D100(即物理寄存器D100,对应协议地址40101)
- 名称:
-
下载程序并运行PLC
点击 下载按钮 → 确认 下载至H5U → 点击 运行按钮使PLC处于RUN状态。 -
用Modbus Poll工具发起读请求
- 启动Modbus Poll(v7.6+,免费版可满足)
Connection→Connect→ 选择TCP/IP,IP填H5U的IP(如192.168.1.10),端口502Setup→Read/Write→ 功能码选03 (Read Holding Registers)Read→ 起始地址填101(因40101 - 40000 = 101,Poll默认以1为基准)- 寄存器数量填
2(DINT占2个16位寄存器) - 点击
Read按钮
-
观察返回值与H5U变量监视
- Modbus Poll窗口应显示两列十六进制值(如
00 00),对应D100低字、D101高字 - 同时在AutoShop中打开“在线监控” → 找到
TEST_REG→ 手动修改其值为12345 - 切回Modbus Poll → 点击
Read→ 值变为3039 0000(小端序:低字3039=12345,高字0000)
- Modbus Poll窗口应显示两列十六进制值(如
-
反向验证:从上位机写入
- Modbus Poll中
Setup→Read/Write→ 功能码选16 (Preset Multiple Registers) - 起始地址仍为
101,数量2 - 在数据区输入
0000 0001(即DINT值65536)→ 点击Write - 回到AutoShop监控 →
TEST_REG实时更新为65536
- Modbus Poll中
✅ 全部通过即证明地址映射准确。若失败,请按以下顺序排查:
- 检查H5U IP与PC是否同网段、防火墙是否放行502端口;
- 检查AutoShop中“系统配置”→“Modbus TCP”是否已启用;
- 检查“寄存器地址偏移”是否为
0; - 检查变量地址是否确为
Dxxx格式(不可用M、Q等非保持寄存器类型)。
四、特殊数据类型地址计算规则(必记)
H5U支持多种数据类型,但Modbus协议仅传输16位寄存器(2字节)。因此多字节类型需跨寄存器存放,地址计算需注意字序与对齐。
| 数据类型 | H5U变量地址示例 | 协议起始地址(4xxxx) | 说明 |
|---|---|---|---|
BIT(位) |
D100.0 |
40101(位0) |
一个D寄存器含16位,D100.0~D100.15对应40101.0~40101.15;D100.16不存在,应写D101.0→40102.0 |
INT(整数) |
D100 |
40101 |
占1个寄存器,地址直接D编号 + 40001 |
DINT(双整数) |
D100 |
40101 |
占2个连续寄存器:D100(低字)→40101,D101(高字)→40102;小端序 |
REAL(浮点) |
D100 |
40101 |
同DINT,占2寄存器,IEEE 754单精度,小端序 |
STRING(字符串) |
D100(长度≤15字节) |
40101 |
每2字节存1字符(ASCII),D100存第1-2字符,D101存第3-4字符… |
⚠️ 关键提醒:H5U所有保持寄存器地址必须为偶数D编号(D0/D2/D4…)才能安全存DINT/REAL。若定义D101为DINT,则高字会落在D102,破坏连续性,导致上位机读错。
五、典型应用案例:将H5U的PID输出值(D200)映射为Modbus可读40201
假设你已完成PID控制,输出值存于D200(INT类型)。
-
确认变量定义
AutoShop变量表中:- 名称:
PID_OUTPUT - 类型:
INT - 地址:
D200✅(非D201、D200.0等)
- 名称:
-
计算Modbus地址
$40001 + 200 = 40201$ -
上位机配置
- 设备类型:Modbus TCP
- IP:
192.168.1.10 - 寄存器地址:
40201(或201,取决于软件是否自动加40000) - 数据类型:
INT16(有符号16位整数)
-
验证
在AutoShop中强制D200 = 256→ 上位机应实时显示256。
若显示65792(即256 + 65536),说明上位机按无符号读取,需切换为有符号格式。
六、避坑清单(高频错误速查)
| 现象 | 根本原因 | 解决方案 |
|---|---|---|
读40001返回全0,但D0在AutoShop中显示非0 |
H5U未运行(STOP状态不刷新Modbus响应) | 点击 PLC运行按钮,确认RUN指示灯亮 |
写40001后D0值不变 |
上位机使用功能码04(只读)而非06/10 |
检查上位机功能码配置,写操作必须用06(单寄存器)或10(多寄存器) |
读40101得到D101值而非D100 |
上位机地址填了101但软件自动加40000→40101,而H5U偏移量设为100→实际访问D0 |
进入AutoShop“系统配置”→“Modbus TCP”,将“寄存器地址偏移”改为0 |
REAL类型读数为极小值(如1.175e-38) |
字节序颠倒(大端序写入,小端序读出) | H5U固定小端序,确保上位机也设为小端(Intel格式);勿勾选“大端序”选项 |
| 多个DINT变量地址紧邻导致读取错乱(如D100与D102之间隔D101) | D101被其他变量占用,破坏D100-D101连续性 | 将DINT变量地址设为偶数起始(D100、D102、D104…),或使用ARRAY[0..1] OF DINT集中分配 |
七、终极校验法:用H5U内置Modbus TCP诊断功能
H5U固件V3.0以上提供原生诊断指令,无需外接电脑:
-
在梯形图中插入指令:
MODBUS_DIAG- EN:
SM0.0(始终使能) - DIAG_MODE:
1(启用诊断) - DIAG_DATA:
D1000(诊断数据存入D1000起始)
- EN:
-
下载运行后,查看
D1000~D1010:D1000:当前TCP连接数(正常为1)D1001:最近一次错误码(0=无错)D1002:最后请求的起始地址(十进制,如读40101则此处为40101)D1003:最后请求的寄存器数量
-
若
D1002显示值与上位机发送地址不一致,说明中间有网关或代理做了地址转换,需检查网络拓扑。
立即执行:打开AutoShop,定位一个D区变量,用本文公式算出它的4xxxx地址,现在就用Modbus Poll读一次。

暂无评论,快来抢沙发吧!