Modbus 保持寄存器最小单位是 1 个字 = 2 字节 (VW),没有直接按 VB(单字节)访问的寄存器;VB3033 属于VW3032 这个字里面的高 / 低其中一个字节。
先确认你的 MBUS_INIT 设置
情况 A:HoldStart=&VB3000(V 区缓冲区起始 VB3000)
缓冲区第一个字:VW3000 → Modbus 40001
每 + 2 个 V 字节,Modbus 寄存器号 + 1
VW 编号公式:VWx = VBx + VBx+1
VW3032 = VB3032(低字节) + VB3033(高字节)
计算偏移: 起始 VB3000;VW3032 距离起始:(3032‑3000) ÷2 =16 寄存器号 = 40001 +16 = 40017
结论:
VB3033 属于保持寄存器 40017(VW3032)里面的高字节!40017 这个 16 位字:低字节 = VB3032;高字节 = VB3033。
Modbus 协议不能单独读 VB3033 一个字节;只能整体读取 40017 这整个 16 位字,上位机软件再解析提取高字节就是 VB3033 的值。
公式通用(S7‑200 SMART):
Modbus寄存器号 = 40001 + (VW编号 ‑ HoldStart_VB)/2
HoldStart_VB 是 MBUS_INIT 设置的缓冲区起始 VB 号。
举例:HoldStart=&VB2800,VW3032: (3032‑2800)/2=116 →40001+116 =40117。
上位机怎么拿到 VB3033 的值?
上位机读取保持寄存器 40017(功能码 03),读到 16 位 Word;
取这个 Word 的高 8 位字节,就是 VB3033;低 8 位就是 VB3032。
举例子:读到字值 = 0x1234;低字节 0x34=VB3032;高字节 0x12=VB3033。
常见踩坑提醒
Modbus 没有字节寄存器,只能按字读写;不能直接写 4xxxx 地址去单独改写 VB3033,会同时改写相邻 VB3032;PLC 程序内部再拆分字节处理。
如果你是 S7‑1200/1500 MB_SLAVE,缓冲区是 DB 块,不再使用 V 区 VB3033,逻辑完全不一样。
一定要确认 MBUS_INIT 的 HoldStart 起始地址,这是换算的基准,很多人算错就是起始点搞错。
小结(HoldStart=&VB3000 时)
VW3032 →Modbus 地址 40017
VB3032 =40017 字的低 8bit
VB3033 =40017 字的高 8bit





