内容目录
本文目录
- 1. 1. start_read:后台自动轮询
- 2. 2. cycle 与 cycle_run:高低频任务调度
- 3. 3. 读写从机寄存器
- 4. 3.1 读(缓存直读)
- 5. 3.2 写
- 6. 3.3 批量写寄存器
- 7. 4. 多从站(一主多从)
HMI 做主站(Modbus Master / FX2N / FX3U 主站模式)时,用 start_read 做后台自动轮询读从机,用 set_xxx 写从机。这篇讲主从模式下的读写套路,以及多从站怎么调度。
1. start_read:后台自动轮询
start_read(index, vtype, addr, quantity, cycle, cycle_run, mode) -- index: 任务索引号 0~127, 用于 stop_read(index) 停止 -- vtype: 数据类型 VT_3x/VT_4x/VT_0x... -- addr: 起始寄存器地址 -- quantity: 读取数量 1~120 个寄存器 -- cycle: 轮询周期倍数(默认0=每个通信周期都读) -- cycle_run:周期内第几次执行(0-based, 需 < cycle) -- mode: 0=持续周期读取(默认), 1=仅读一次(需先 create_resp_que())
调用后 HMI 把该任务加入通信调度队列,每个通信周期自动发 Modbus 请求,返回数据写入内存镜像。脚本用 get_uint16(VT_4x, addr) 直接读缓存,无通信延迟。

2. cycle 与 cycle_run:高低频任务调度
HMI 把通信周期划分为多个子周期,用来区分高频/低频任务:
| 调用 | 行为 |
|---|---|
| start_read(0, VT_4x, 0x1000, 10) | 每个通信周期都读 4×1000~1009(高频) |
| start_read(1, VT_4x, 0x2000, 10, 3, 2) | 每 3 个周期读一次,且在第 3 个周期执行(低频) |
调度时序:周期#0(0ms)读 0x1000(高频任务);周期#1 再读 0x1000;周期#2 读 0x1000 + 0x2000(低频任务到点)。这样把不同实时性要求的数据错开,避免总线拥堵。
3. 读写从机寄存器
3.1 读(缓存直读)
local v = get_uint16(VT_4x, 0x1000) -- 读保持寄存器 local f = get_float(VT_4x, 0x1002) -- 读单精度浮点(占2寄存器)
3.2 写
set_uint16(VT_4x, 0x1000, 100) -- 写保持寄存器(功能码06) set_uint16_ex(VT_4x, 0x1010, 1,2,3,4) -- 批量写(功能码10)
3.3 批量写寄存器
local tb = {1, 2, 3, 4, 5}
set_array(VT_4x, 0x1010, tb) -- 表方式批量写
4. 多从站(一主多从)
项目创建两个从站,站号 10 和 20。读写前用 select_slave() 切换当前从机,或用 set_slave_site() 建立索引到站号的映射:
set_slave_site(0, 10) -- 索引0 = 站号10 set_slave_site(1, 20) -- 索引1 = 站号20 select_slave(0) -- 切到从站10 set_uint16(VT_4x, 0x0000, 1) select_slave(1) -- 切到从站20 local v = get_uint16(VT_4x, 0x1000)

一主多从的关键:①start_read 的 index 是任务索引不是站号,停止用 stop_read(index);②从站切换后读写要重新 select_slave;③高频数据用短周期、低频数据用 cycle 倍数错开,不然总线上全是 HMI 的请求帧。
整理自 广州大彩科技 VisualHMI 开发文档(hmi-doc.gz-dc.com)LUA 教程「Modbus 一主多从」,版权归大彩科技所有。
发表回复