da60912d8b
- 050:1~19 有效分支、6/7 缺号、20~24 制丸2 预留已注释、末尾写 LW-310~313 - 发现 IO切换上料(9→158)、IO切换清洗(15→168) 索引与窗口错位;制丸(1→151) 正确 - LW-310~313 与旧文档 X1Y1 的 LW-300~311 重叠 - main-init 未变:127/18/127/18 + RW-61=1
1374 lines
97 KiB
Markdown
1374 lines
97 KiB
Markdown
# 宏指令(全部,逐行注释)
|
||
|
||
> 摘自同目录 `开发主文件.md` 第 6 章,直接复制到 EB Pro 宏编辑器。
|
||
|
||
## 6.0 工程实际清单(2026-10-27 核对,依据 EB Pro「宏指令」窗口)
|
||
|
||
> 现工程 `unitouch1025.cmtp` 共 **50 条**(ID 000~050,**缺 031**)。
|
||
> `{I}` = 当 HMI 启动时即执行一次;`{P}` = **周期执行**;无标记 = 由按钮/窗口事件触发。
|
||
> 本表是“以工程为准”的基准,下文 6.1 起的正文若与本表冲突,**以本表为准**。
|
||
|
||
| ID | 宏名 | 条件 | 用途 | 文档状态 |
|
||
|---|---|---|---|---|
|
||
| 000 | `main-init` | I | 开机初始化 `LW-0/1/2`、页面位图 `LW-70~73`、`RW-61` | 有正文 |
|
||
| 001~007 | `btn-y1`~`btn-y7` | — | Y 页签导航(权限 + 页面存在位图) | 有正文 |
|
||
| 008~011 | `btn-x1`~`btn-x4` | — | X 页签导航 | 有正文 |
|
||
| 012 | `btn-login-index` | — | 索引登入 + 内联提示映射 | 有正文 |
|
||
| 013 | `macro_13` | — | **空宏**:只有 `macro_command main()` / `end macro_command`,无任何语句;无执行条件、非周期、非开机 | ✅ 已核对:**可删** |
|
||
| 014 | `close-msg` | — | 关 11 号无权限窗 | 有正文 |
|
||
| 015~017 | `open-time` / `set-time` / `close-time` | — | 修改时间 | 有正文 |
|
||
| 018 | `logout` | — | 注销并回 10 号窗 | 有正文 |
|
||
| 019 | `user-open` | — | 开 14 号用户管理窗 | 有正文 |
|
||
| 020~027 | `usr-init`/`usr-back`/`usr-add`/`usr-delete`/`usr-delete-ok`/`usr-delete-cancel`/`usr-setlevel`/`usr-setpwd` | — | 用户管理各种命令 | 有正文(模板) |
|
||
| 028~029 | `about-open` / `about-close` | — | 关于窗 | 有正文 |
|
||
| 030 | `usr-getlevel` | — | 按索引读权限 | 有正文(模板) |
|
||
| — | (031 已删除,工程内无此 ID) | — | — | — |
|
||
| 032 | `close-nopage` | — | 关 16 号“无内容”窗 | 有正文 |
|
||
| 033~035 | `admin-close` / `admin-login` / `admin-open` | — | 超管登录弹窗 | 有正文 |
|
||
| 036 | `line-ab-switch` | — | A/B 线切换(仅 role=1) | 有正文 |
|
||
| 037 | `net-apply` | I | 网络参数套用(HMI + 设备 4/5 IP) | 有正文(10-27 已加 IP 保护) |
|
||
| 038 | `net-read` | — | 系统网络值 → 暂存 `RW` | 有正文 |
|
||
| 039~041 | `x2y2-focus-area1`~`area3` | — | X2Y2 三区聚焦 → `LW-50` = 30/31/32 | 已补录(6.2) |
|
||
| 042 | `IO切换上料` | — | IO 组索引 9 → `LW-300`,窗口 158 | 已补录(6.2) |
|
||
| 043 | `x2y2-focus-area-close` | — | 关区域弹窗(`LW-50=0`) | 已补录(6.2) |
|
||
| 044 | `IO切换清洗` | — | IO 组索引 15 → `LW-300`,窗口 168 | 已补录(6.2) |
|
||
| 045 | `IO切换制丸` | — | IO 组索引 1 → `LW-300`,窗口 151 | 已补录(6.2) |
|
||
| 046 | `上料参数` | — | 窗口 210(与「清洗-点动」重名,存疑) | 已补录(6.2) |
|
||
| 047 | `温度监控` | P(1s) | 读 16 个 REAL(`HMI_EM02.Temperature_PV`)→ `LW-200` | 已补录(6.2) |
|
||
| 048 | `屏蔽通讯异常提示` | P(100ms) | 周期置 ON `LB-11960~11967`(设备 1~8 的 “Device No Response”) | 已补录(6.2) |
|
||
| 049 | `出条温度监控` | P(1s) | 读 10 个 REAL(`HIKMICRO_Temp_R`)→ `LW-240` | 已补录(6.2) |
|
||
| 050 | `IO` | P(100ms) | 按 `LW-300` 索引读 `PLC.Tags.Table.Local_*`(1~19) | ✅ 已补全(20~24 注释) |
|
||
|
||
### 6.0.1 与旧文档的差异(已确认)
|
||
|
||
1. **区域弹窗宏名不对**:实际是 `x2y2-focus-area1~3` + `x2y2-focus-area-close`,旧文档的 `area-1~4` / `area-close` 作废;且**只有 3 个区域**,没有 area-4(与“4 区并 3 区”一致)。
|
||
2. **48 号宏 `屏蔽通讯异常提示` 是周期执行(P)**,不是开机一次;它把 `LB-11960~11967` 八台设备全屏蔽,不是文档写的 63/64 两台。
|
||
3. **7 条宏文档完全没有**:`macro_13`、`IO切换上料`、`IO切换清洗`、`IO切换制丸`、`上料参数`、`温度监控`、`出条温度监控`、`IO`(含 3 条周期温度宏)。
|
||
4. **ID 031 缺失**(工程里已删除,文档无记录)。
|
||
5. `macro_13`(ID 013)是**空宏**(无语句、无执行条件),建议直接删除,不留占位。
|
||
|
||
### 6.0.2 核对状态(2026-10-27 收尾)
|
||
|
||
| 项 | 状态 |
|
||
| --- | --- |
|
||
| 38 条原有正文 | 与工程一致,未发现改动 |
|
||
| 039/040/041/043(区域弹窗) | ✅ 已补录:`win` = 30 / 31 / 32,关闭写 0 |
|
||
| 042/044/045(IO 切换) | ✅ 已补录:写 `LW-300`=组索引、`LW-2`=窗口 |
|
||
| 046(上料参数) | ✅ 已补录,但**窗口 210 与「清洗-点动」重名,存疑** |
|
||
| 047/049(温度) | ✅ 已补录,但 **float 拷贝长度与注释不符**(见 6.2.1) |
|
||
| 048(屏蔽通讯) | ✅ 已补录:100 ms 周期压 8 个位 |
|
||
| 050(IO) | ✅ 已补全:1~19 有效,20~24 为制丸2 预留(注释) |
|
||
| 013(macro_13) | ✅ 空宏,可删 |
|
||
| 000(main-init) | ✅ 已核对:仍为 `127/18/127/18` + `RW-61=1`,未变;说明 130~282 新页不走 X/Y 导航 |
|
||
## 6.1 宏正文(逐行注释)
|
||
|
||
> 命名:导航 = `btn-*`、登录 = `main-init`/`btn-login-index`/`logout`、管理员登录 = `admin-open`/`admin-login`/`admin-close`、用户管理 = `user-open` + `usr-*`(你的工程删除类为 `usr-delete*`)、关于窗 = `about-open`/`about-close`、时间 = `open-time`/`set-time`/`close-time`、弹窗 = `close-msg`/`close-nopage`。
|
||
> **登录提示已内联**:`LW-101` 结果码 → `LW-261` 的映射直接写在 `btn-login-index`/`admin-login` 内,零延迟、不轮询、不依赖宏编号。`net-apply` 用宏属性「当 HMI 启动时即执行一次」。
|
||
> 权限判定统一用 `LW-9222` 的类别位(`GETBIT` 取值 + `if`,不用 `and`/`&`)。
|
||
|
||
**`main-init`**(开机执行一次)
|
||
```
|
||
macro_command main() // 宏入口:HMI 启动时执行一次
|
||
short x = 1 // X 初值 = 1
|
||
short y = 1 // Y 初值 = 1
|
||
short win = 0 // 目标窗口号初值 = 0(不切窗)
|
||
short r1 = 127 // X1 段存在位图:bit0=Y1…bit6=Y7,1=有内容(X1 全有 = 127)
|
||
short r2 = 18 // X2 段:只留 Y2/Y5(缺 Y1/Y3/Y4/Y6/Y7)→ 2+16=18
|
||
short r3 = 127 // X3 段:Y1~Y7 全有(X3Y6 已启用)→ 127
|
||
short r4 = 18 // X4 段:只留 Y2/Y5(缺 Y1/Y3/Y4/Y6/Y7)→ 2+16=18
|
||
short one = 1 // 常量 1(默认制丸线别)
|
||
SetData(x, "Local HMI", LW, 0, 1) // X → LW-0
|
||
SetData(y, "Local HMI", LW, 1, 1) // Y → LW-1
|
||
SetData(win, "Local HMI", LW, 2, 1) // 窗口号 0 → LW-2(不触发切窗)
|
||
SetData(r1, "Local HMI", LW, 70, 1) // X1 位图 → LW-70
|
||
SetData(r2, "Local HMI", LW, 71, 1) // X2 位图 → LW-71
|
||
SetData(r3, "Local HMI", LW, 72, 1) // X3 位图 → LW-72
|
||
SetData(r4, "Local HMI", LW, 73, 1) // X4 位图 → LW-73
|
||
SetData(one, "Local HMI", RW, 61, 1) // 开机默认制丸线别 = A(只有人工切换才变 B)
|
||
end macro_command // 宏结束
|
||
```
|
||
|
||
**导航宏说明**:先查权限(`LW-9222` 类别位)→ 再查当前 Y 页面是否存在(`LW-70`~`73` 位图)→ 有内容才切窗,无内容弹 16 号窗。
|
||
|
||
**`btn-x1`**(X1 配料/上料 · 权限 A/B/C)
|
||
```
|
||
macro_command main() // 宏入口:按下 X1 按钮时执行
|
||
short cls = 0 // 当前用户类别位(读 LW-9222)
|
||
short x = 1 // 本按钮固定切到 X=1
|
||
short y = 0 // 运行时读回的当前 Y(1~7)
|
||
short win = 0 // 计算出的目标窗口号
|
||
short ok = 0 // 权限通过标志:1=放行
|
||
short bv = 0 // 页面存在标志:1=有内容
|
||
short vpm = 0 // X1 段页面存在位图(LW-70)
|
||
short pop = 1 // 弹窗置位常量 1
|
||
short bA = 0 // 类别 A 位(工程师)
|
||
short bB = 0 // 类别 B 位(管理员)
|
||
short bC = 0 // 类别 C 位(上料)
|
||
GetData(cls, "Local HMI", LW, 9222, 1) // 读当前用户类别位 → cls
|
||
GETBIT(cls, bA, 0) // 取 bit0 → bA(A 工程师)
|
||
GETBIT(cls, bB, 1) // 取 bit1 → bB(B 管理员)
|
||
GETBIT(cls, bC, 2) // 取 bit2 → bC(C 上料)
|
||
if bA == 1 then // 含类别 A?
|
||
ok = 1 // 权限通过
|
||
end if // 结束判断
|
||
if bB == 1 then // 含类别 B?
|
||
ok = 1 // 权限通过
|
||
end if // 结束判断
|
||
if bC == 1 then // 含类别 C?
|
||
ok = 1 // 权限通过
|
||
end if // 结束判断
|
||
if ok == 1 then // 权限通过 → 继续查页面
|
||
GetData(y, "Local HMI", LW, 1, 1) // 读当前 Y → y
|
||
GetData(vpm, "Local HMI", LW, 70, 1) // 读 X1 段存在位图 → vpm
|
||
if y == 1 then // 当前 Y=1?
|
||
GETBIT(vpm, bv, 0) // 取位 0(Y1)→ bv
|
||
end if // 结束判断
|
||
if y == 2 then // 当前 Y=2?
|
||
GETBIT(vpm, bv, 1) // 取位 1(Y2)→ bv
|
||
end if // 结束判断
|
||
if y == 3 then // 当前 Y=3?
|
||
GETBIT(vpm, bv, 2) // 取位 2(Y3)→ bv
|
||
end if // 结束判断
|
||
if y == 4 then // 当前 Y=4?
|
||
GETBIT(vpm, bv, 3) // 取位 3(Y4)→ bv
|
||
end if // 结束判断
|
||
if y == 5 then // 当前 Y=5?
|
||
GETBIT(vpm, bv, 4) // 取位 4(Y5)→ bv
|
||
end if // 结束判断
|
||
if y == 6 then // 当前 Y=6?
|
||
GETBIT(vpm, bv, 5) // 取位 5(Y6)→ bv
|
||
end if // 结束判断
|
||
if y == 7 then // 当前 Y=7?
|
||
GETBIT(vpm, bv, 6) // 取位 6(Y7)→ bv
|
||
end if // 结束判断
|
||
if bv == 1 then // 该页面有内容?
|
||
SetData(x, "Local HMI", LW, 0, 1) // X=1 → LW-0
|
||
win = 101 + (x - 1) * 7 + (y - 1) // 算窗口号:101+(X-1)*7+(Y-1)
|
||
SetData(win, "Local HMI", LW, 2, 1) // 窗口号 → LW-2(触发切窗)
|
||
else // 该页面无内容
|
||
SetData(pop, "Local HMI", LB, 124, 1) // 置 LB-124 → 弹 16 号窗
|
||
end if // 结束判断
|
||
else // 权限不通过
|
||
SetData(pop, "Local HMI", LB, 110, 1) // 置 LB-110 → 弹 11 号无权限窗
|
||
end if // 结束判断
|
||
end macro_command // 宏结束
|
||
```
|
||
|
||
**`btn-x2`**(X2 上料清洗 · 权限 A/B/C)
|
||
```
|
||
macro_command main() // 宏入口:按下 X2 按钮时执行
|
||
short cls = 0 // 当前用户类别位(读 LW-9222)
|
||
short x = 2 // 本按钮固定切到 X=2
|
||
short y = 0 // 运行时读回的当前 Y(1~7)
|
||
short win = 0 // 计算出的目标窗口号
|
||
short ok = 0 // 权限通过标志:1=放行
|
||
short bv = 0 // 页面存在标志:1=有内容
|
||
short vpm = 0 // X2 段页面存在位图(LW-71)
|
||
short pop = 1 // 弹窗置位常量 1
|
||
short bA = 0 // 类别 A 位(工程师)
|
||
short bB = 0 // 类别 B 位(管理员)
|
||
short bC = 0 // 类别 C 位(上料)
|
||
GetData(cls, "Local HMI", LW, 9222, 1) // 读当前用户类别位 → cls
|
||
GETBIT(cls, bA, 0) // 取 bit0 → bA(A 工程师)
|
||
GETBIT(cls, bB, 1) // 取 bit1 → bB(B 管理员)
|
||
GETBIT(cls, bC, 2) // 取 bit2 → bC(C 上料)
|
||
if bA == 1 then // 含类别 A?
|
||
ok = 1 // 权限通过
|
||
end if // 结束判断
|
||
if bB == 1 then // 含类别 B?
|
||
ok = 1 // 权限通过
|
||
end if // 结束判断
|
||
if bC == 1 then // 含类别 C?
|
||
ok = 1 // 权限通过
|
||
end if // 结束判断
|
||
if ok == 1 then // 权限通过 → 继续查页面
|
||
GetData(y, "Local HMI", LW, 1, 1) // 读当前 Y → y
|
||
GetData(vpm, "Local HMI", LW, 71, 1) // 读 X2 段存在位图 → vpm
|
||
if y == 1 then // 当前 Y=1?
|
||
GETBIT(vpm, bv, 0) // 取位 0(Y1)→ bv
|
||
end if // 结束判断
|
||
if y == 2 then // 当前 Y=2?
|
||
GETBIT(vpm, bv, 1) // 取位 1(Y2)→ bv
|
||
end if // 结束判断
|
||
if y == 3 then // 当前 Y=3?
|
||
GETBIT(vpm, bv, 2) // 取位 2(Y3)→ bv
|
||
end if // 结束判断
|
||
if y == 4 then // 当前 Y=4?
|
||
GETBIT(vpm, bv, 3) // 取位 3(Y4)→ bv
|
||
end if // 结束判断
|
||
if y == 5 then // 当前 Y=5?
|
||
GETBIT(vpm, bv, 4) // 取位 4(Y5)→ bv
|
||
end if // 结束判断
|
||
if y == 6 then // 当前 Y=6?
|
||
GETBIT(vpm, bv, 5) // 取位 5(Y6)→ bv
|
||
end if // 结束判断
|
||
if y == 7 then // 当前 Y=7?
|
||
GETBIT(vpm, bv, 6) // 取位 6(Y7)→ bv
|
||
end if // 结束判断
|
||
if bv == 1 then // 该页面有内容?
|
||
SetData(x, "Local HMI", LW, 0, 1) // X=2 → LW-0
|
||
win = 101 + (x - 1) * 7 + (y - 1) // 算窗口号:101+(X-1)*7+(Y-1)
|
||
SetData(win, "Local HMI", LW, 2, 1) // 窗口号 → LW-2(触发切窗)
|
||
else // 该页面无内容
|
||
SetData(pop, "Local HMI", LB, 124, 1) // 置 LB-124 → 弹 16 号窗
|
||
end if // 结束判断
|
||
else // 权限不通过
|
||
SetData(pop, "Local HMI", LB, 110, 1) // 置 LB-110 → 弹 11 号无权限窗
|
||
end if // 结束判断
|
||
end macro_command // 宏结束
|
||
```
|
||
|
||
**`btn-x3`**(X3 制丸 · 权限 A/B/D)
|
||
```
|
||
macro_command main() // 宏入口:按下 X3 按钮时执行
|
||
short cls = 0 // 当前用户类别位(读 LW-9222)
|
||
short x = 3 // 本按钮固定切到 X=3
|
||
short y = 0 // 运行时读回的当前 Y(1~7)
|
||
short win = 0 // 计算出的目标窗口号
|
||
short ok = 0 // 权限通过标志:1=放行
|
||
short bv = 0 // 页面存在标志:1=有内容
|
||
short vpm = 0 // X3 段页面存在位图(LW-72)
|
||
short pop = 1 // 弹窗置位常量 1
|
||
short bA = 0 // 类别 A 位(工程师)
|
||
short bB = 0 // 类别 B 位(管理员)
|
||
short bD = 0 // 类别 D 位(制丸)
|
||
GetData(cls, "Local HMI", LW, 9222, 1) // 读当前用户类别位 → cls
|
||
GETBIT(cls, bA, 0) // 取 bit0 → bA(A 工程师)
|
||
GETBIT(cls, bB, 1) // 取 bit1 → bB(B 管理员)
|
||
GETBIT(cls, bD, 3) // 取 bit3 → bD(D 制丸)
|
||
if bA == 1 then // 含类别 A?
|
||
ok = 1 // 权限通过
|
||
end if // 结束判断
|
||
if bB == 1 then // 含类别 B?
|
||
ok = 1 // 权限通过
|
||
end if // 结束判断
|
||
if bD == 1 then // 含类别 D?
|
||
ok = 1 // 权限通过
|
||
end if // 结束判断
|
||
if ok == 1 then // 权限通过 → 继续查页面
|
||
GetData(y, "Local HMI", LW, 1, 1) // 读当前 Y → y
|
||
GetData(vpm, "Local HMI", LW, 72, 1) // 读 X3 段存在位图 → vpm
|
||
if y == 1 then // 当前 Y=1?
|
||
GETBIT(vpm, bv, 0) // 取位 0(Y1)→ bv
|
||
end if // 结束判断
|
||
if y == 2 then // 当前 Y=2?
|
||
GETBIT(vpm, bv, 1) // 取位 1(Y2)→ bv
|
||
end if // 结束判断
|
||
if y == 3 then // 当前 Y=3?
|
||
GETBIT(vpm, bv, 2) // 取位 2(Y3)→ bv
|
||
end if // 结束判断
|
||
if y == 4 then // 当前 Y=4?
|
||
GETBIT(vpm, bv, 3) // 取位 3(Y4)→ bv
|
||
end if // 结束判断
|
||
if y == 5 then // 当前 Y=5?
|
||
GETBIT(vpm, bv, 4) // 取位 4(Y5)→ bv
|
||
end if // 结束判断
|
||
if y == 6 then // 当前 Y=6?
|
||
GETBIT(vpm, bv, 5) // 取位 5(Y6)→ bv
|
||
end if // 结束判断
|
||
if y == 7 then // 当前 Y=7?
|
||
GETBIT(vpm, bv, 6) // 取位 6(Y7)→ bv
|
||
end if // 结束判断
|
||
if bv == 1 then // 该页面有内容?
|
||
SetData(x, "Local HMI", LW, 0, 1) // X=3 → LW-0
|
||
win = 101 + (x - 1) * 7 + (y - 1) // 算窗口号:101+(X-1)*7+(Y-1)
|
||
SetData(win, "Local HMI", LW, 2, 1) // 窗口号 → LW-2(触发切窗)
|
||
else // 该页面无内容
|
||
SetData(pop, "Local HMI", LB, 124, 1) // 置 LB-124 → 弹 16 号窗
|
||
end if // 结束判断
|
||
else // 权限不通过
|
||
SetData(pop, "Local HMI", LB, 110, 1) // 置 LB-110 → 弹 11 号无权限窗
|
||
end if // 结束判断
|
||
end macro_command // 宏结束
|
||
```
|
||
|
||
**`btn-x4`**(X4 制丸清洗 · 权限 A/B/D)
|
||
```
|
||
macro_command main() // 宏入口:按下 X4 按钮时执行
|
||
short cls = 0 // 当前用户类别位(读 LW-9222)
|
||
short x = 4 // 本按钮固定切到 X=4
|
||
short y = 0 // 运行时读回的当前 Y(1~7)
|
||
short win = 0 // 计算出的目标窗口号
|
||
short ok = 0 // 权限通过标志:1=放行
|
||
short bv = 0 // 页面存在标志:1=有内容
|
||
short vpm = 0 // X4 段页面存在位图(LW-73)
|
||
short pop = 1 // 弹窗置位常量 1
|
||
short bA = 0 // 类别 A 位(工程师)
|
||
short bB = 0 // 类别 B 位(管理员)
|
||
short bD = 0 // 类别 D 位(制丸)
|
||
GetData(cls, "Local HMI", LW, 9222, 1) // 读当前用户类别位 → cls
|
||
GETBIT(cls, bA, 0) // 取 bit0 → bA(A 工程师)
|
||
GETBIT(cls, bB, 1) // 取 bit1 → bB(B 管理员)
|
||
GETBIT(cls, bD, 3) // 取 bit3 → bD(D 制丸)
|
||
if bA == 1 then // 含类别 A?
|
||
ok = 1 // 权限通过
|
||
end if // 结束判断
|
||
if bB == 1 then // 含类别 B?
|
||
ok = 1 // 权限通过
|
||
end if // 结束判断
|
||
if bD == 1 then // 含类别 D?
|
||
ok = 1 // 权限通过
|
||
end if // 结束判断
|
||
if ok == 1 then // 权限通过 → 继续查页面
|
||
GetData(y, "Local HMI", LW, 1, 1) // 读当前 Y → y
|
||
GetData(vpm, "Local HMI", LW, 73, 1) // 读 X4 段存在位图 → vpm
|
||
if y == 1 then // 当前 Y=1?
|
||
GETBIT(vpm, bv, 0) // 取位 0(Y1)→ bv
|
||
end if // 结束判断
|
||
if y == 2 then // 当前 Y=2?
|
||
GETBIT(vpm, bv, 1) // 取位 1(Y2)→ bv
|
||
end if // 结束判断
|
||
if y == 3 then // 当前 Y=3?
|
||
GETBIT(vpm, bv, 2) // 取位 2(Y3)→ bv
|
||
end if // 结束判断
|
||
if y == 4 then // 当前 Y=4?
|
||
GETBIT(vpm, bv, 3) // 取位 3(Y4)→ bv
|
||
end if // 结束判断
|
||
if y == 5 then // 当前 Y=5?
|
||
GETBIT(vpm, bv, 4) // 取位 4(Y5)→ bv
|
||
end if // 结束判断
|
||
if y == 6 then // 当前 Y=6?
|
||
GETBIT(vpm, bv, 5) // 取位 5(Y6)→ bv
|
||
end if // 结束判断
|
||
if y == 7 then // 当前 Y=7?
|
||
GETBIT(vpm, bv, 6) // 取位 6(Y7)→ bv
|
||
end if // 结束判断
|
||
if bv == 1 then // 该页面有内容?
|
||
SetData(x, "Local HMI", LW, 0, 1) // X=4 → LW-0
|
||
win = 101 + (x - 1) * 7 + (y - 1) // 算窗口号:101+(X-1)*7+(Y-1)
|
||
SetData(win, "Local HMI", LW, 2, 1) // 窗口号 → LW-2(触发切窗)
|
||
else // 该页面无内容
|
||
SetData(pop, "Local HMI", LB, 124, 1) // 置 LB-124 → 弹 16 号窗
|
||
end if // 结束判断
|
||
else // 权限不通过
|
||
SetData(pop, "Local HMI", LB, 110, 1) // 置 LB-110 → 弹 11 号无权限窗
|
||
end if // 结束判断
|
||
end macro_command // 宏结束
|
||
```
|
||
|
||
**`btn-y1`**(Y1 初始状态 · 权限 A/B/C/D)
|
||
```
|
||
macro_command main() // 宏入口:按下 Y1 按钮时执行
|
||
short cls = 0 // 当前用户类别位(读 LW-9222)
|
||
short x = 0 // 运行时读回的当前 X(1~4)
|
||
short y = 1 // 本按钮固定切到 Y=1
|
||
short win = 0 // 计算出的目标窗口号
|
||
short ok = 0 // 权限通过标志:1=放行
|
||
short bv = 0 // 页面存在标志:1=有内容
|
||
short vpm = 0 // 当前 X 段页面存在位图
|
||
short pop = 1 // 弹窗置位常量 1
|
||
short bA = 0 // 类别 A 位(工程师)
|
||
short bB = 0 // 类别 B 位(管理员)
|
||
short bC = 0 // 类别 C 位(上料)
|
||
short bD = 0 // 类别 D 位(制丸)
|
||
GetData(cls, "Local HMI", LW, 9222, 1) // 读当前用户类别位 → cls
|
||
GETBIT(cls, bA, 0) // 取 bit0 → bA(A 工程师)
|
||
GETBIT(cls, bB, 1) // 取 bit1 → bB(B 管理员)
|
||
GETBIT(cls, bC, 2) // 取 bit2 → bC(C 上料)
|
||
GETBIT(cls, bD, 3) // 取 bit3 → bD(D 制丸)
|
||
if bA == 1 then // 含类别 A?
|
||
ok = 1 // 权限通过
|
||
end if // 结束判断
|
||
if bB == 1 then // 含类别 B?
|
||
ok = 1 // 权限通过
|
||
end if // 结束判断
|
||
if bC == 1 then // 含类别 C?
|
||
ok = 1 // 权限通过
|
||
end if // 结束判断
|
||
if bD == 1 then // 含类别 D?
|
||
ok = 1 // 权限通过
|
||
end if // 结束判断
|
||
if ok == 1 then // 权限通过 → 查当前 X 段位图
|
||
GetData(x, "Local HMI", LW, 0, 1) // 读当前 X → x
|
||
if x == 1 then // 当前在 X1 段?
|
||
GetData(vpm, "Local HMI", LW, 70, 1) // 读 X1 段位图 LW-70
|
||
end if // 结束判断
|
||
if x == 2 then // 当前在 X2 段?
|
||
GetData(vpm, "Local HMI", LW, 71, 1) // 读 X2 段位图 LW-71
|
||
end if // 结束判断
|
||
if x == 3 then // 当前在 X3 段?
|
||
GetData(vpm, "Local HMI", LW, 72, 1) // 读 X3 段位图 LW-72
|
||
end if // 结束判断
|
||
if x == 4 then // 当前在 X4 段?
|
||
GetData(vpm, "Local HMI", LW, 73, 1) // 读 X4 段位图 LW-73
|
||
end if // 结束判断
|
||
GETBIT(vpm, bv, 0) // 取位 0(Y1)→ bv
|
||
if bv == 1 then // 该页面有内容?
|
||
SetData(y, "Local HMI", LW, 1, 1) // Y=1 → LW-1
|
||
win = 101 + (x - 1) * 7 + (y - 1) // 算窗口号:101+(X-1)*7+(Y-1)
|
||
SetData(win, "Local HMI", LW, 2, 1) // 窗口号 → LW-2(触发切窗)
|
||
else // 该页面无内容
|
||
SetData(pop, "Local HMI", LB, 124, 1) // 置 LB-124 → 弹 16 号窗
|
||
end if // 结束判断
|
||
else // 权限不通过
|
||
SetData(pop, "Local HMI", LB, 110, 1) // 置 LB-110 → 弹 11 号无权限窗
|
||
end if // 结束判断
|
||
end macro_command // 宏结束
|
||
```
|
||
|
||
**`btn-y2`**(Y2 运行 · 权限 A/B/C/D)
|
||
```
|
||
macro_command main() // 宏入口:按下 Y2 按钮时执行
|
||
short cls = 0 // 当前用户类别位(读 LW-9222)
|
||
short x = 0 // 运行时读回的当前 X(1~4)
|
||
short y = 2 // 本按钮固定切到 Y=2
|
||
short win = 0 // 计算出的目标窗口号
|
||
short ok = 0 // 权限通过标志:1=放行
|
||
short bv = 0 // 页面存在标志:1=有内容
|
||
short vpm = 0 // 当前 X 段页面存在位图
|
||
short pop = 1 // 弹窗置位常量 1
|
||
short bA = 0 // 类别 A 位(工程师)
|
||
short bB = 0 // 类别 B 位(管理员)
|
||
short bC = 0 // 类别 C 位(上料)
|
||
short bD = 0 // 类别 D 位(制丸)
|
||
GetData(cls, "Local HMI", LW, 9222, 1) // 读当前用户类别位 → cls
|
||
GETBIT(cls, bA, 0) // 取 bit0 → bA(A 工程师)
|
||
GETBIT(cls, bB, 1) // 取 bit1 → bB(B 管理员)
|
||
GETBIT(cls, bC, 2) // 取 bit2 → bC(C 上料)
|
||
GETBIT(cls, bD, 3) // 取 bit3 → bD(D 制丸)
|
||
if bA == 1 then // 含类别 A?
|
||
ok = 1 // 权限通过
|
||
end if // 结束判断
|
||
if bB == 1 then // 含类别 B?
|
||
ok = 1 // 权限通过
|
||
end if // 结束判断
|
||
if bC == 1 then // 含类别 C?
|
||
ok = 1 // 权限通过
|
||
end if // 结束判断
|
||
if bD == 1 then // 含类别 D?
|
||
ok = 1 // 权限通过
|
||
end if // 结束判断
|
||
if ok == 1 then // 权限通过 → 查当前 X 段位图
|
||
GetData(x, "Local HMI", LW, 0, 1) // 读当前 X → x
|
||
if x == 1 then // 当前在 X1 段?
|
||
GetData(vpm, "Local HMI", LW, 70, 1) // 读 X1 段位图 LW-70
|
||
end if // 结束判断
|
||
if x == 2 then // 当前在 X2 段?
|
||
GetData(vpm, "Local HMI", LW, 71, 1) // 读 X2 段位图 LW-71
|
||
end if // 结束判断
|
||
if x == 3 then // 当前在 X3 段?
|
||
GetData(vpm, "Local HMI", LW, 72, 1) // 读 X3 段位图 LW-72
|
||
end if // 结束判断
|
||
if x == 4 then // 当前在 X4 段?
|
||
GetData(vpm, "Local HMI", LW, 73, 1) // 读 X4 段位图 LW-73
|
||
end if // 结束判断
|
||
GETBIT(vpm, bv, 1) // 取位 1(Y2)→ bv
|
||
if bv == 1 then // 该页面有内容?
|
||
SetData(y, "Local HMI", LW, 1, 1) // Y=2 → LW-1
|
||
win = 101 + (x - 1) * 7 + (y - 1) // 算窗口号:101+(X-1)*7+(Y-1)
|
||
SetData(win, "Local HMI", LW, 2, 1) // 窗口号 → LW-2(触发切窗)
|
||
else // 该页面无内容
|
||
SetData(pop, "Local HMI", LB, 124, 1) // 置 LB-124 → 弹 16 号窗
|
||
end if // 结束判断
|
||
else // 权限不通过
|
||
SetData(pop, "Local HMI", LB, 110, 1) // 置 LB-110 → 弹 11 号无权限窗
|
||
end if // 结束判断
|
||
end macro_command // 宏结束
|
||
```
|
||
|
||
**`btn-y3`**(Y3 配方 · 权限 A/B/C/D)
|
||
```
|
||
macro_command main() // 宏入口:按下 Y3 按钮时执行
|
||
short cls = 0 // 当前用户类别位(读 LW-9222)
|
||
short x = 0 // 运行时读回的当前 X(1~4)
|
||
short y = 3 // 本按钮固定切到 Y=3
|
||
short win = 0 // 计算出的目标窗口号
|
||
short ok = 0 // 权限通过标志:1=放行
|
||
short bv = 0 // 页面存在标志:1=有内容
|
||
short vpm = 0 // 当前 X 段页面存在位图
|
||
short pop = 1 // 弹窗置位常量 1
|
||
short bA = 0 // 类别 A 位(工程师)
|
||
short bB = 0 // 类别 B 位(管理员)
|
||
short bC = 0 // 类别 C 位(上料)
|
||
short bD = 0 // 类别 D 位(制丸)
|
||
GetData(cls, "Local HMI", LW, 9222, 1) // 读当前用户类别位 → cls
|
||
GETBIT(cls, bA, 0) // 取 bit0 → bA(A 工程师)
|
||
GETBIT(cls, bB, 1) // 取 bit1 → bB(B 管理员)
|
||
GETBIT(cls, bC, 2) // 取 bit2 → bC(C 上料)
|
||
GETBIT(cls, bD, 3) // 取 bit3 → bD(D 制丸)
|
||
if bA == 1 then // 含类别 A?
|
||
ok = 1 // 权限通过
|
||
end if // 结束判断
|
||
if bB == 1 then // 含类别 B?
|
||
ok = 1 // 权限通过
|
||
end if // 结束判断
|
||
if bC == 1 then // 含类别 C?
|
||
ok = 1 // 权限通过
|
||
end if // 结束判断
|
||
if bD == 1 then // 含类别 D?
|
||
ok = 1 // 权限通过
|
||
end if // 结束判断
|
||
if ok == 1 then // 权限通过 → 查当前 X 段位图
|
||
GetData(x, "Local HMI", LW, 0, 1) // 读当前 X → x
|
||
if x == 1 then // 当前在 X1 段?
|
||
GetData(vpm, "Local HMI", LW, 70, 1) // 读 X1 段位图 LW-70
|
||
end if // 结束判断
|
||
if x == 2 then // 当前在 X2 段?
|
||
GetData(vpm, "Local HMI", LW, 71, 1) // 读 X2 段位图 LW-71
|
||
end if // 结束判断
|
||
if x == 3 then // 当前在 X3 段?
|
||
GetData(vpm, "Local HMI", LW, 72, 1) // 读 X3 段位图 LW-72
|
||
end if // 结束判断
|
||
if x == 4 then // 当前在 X4 段?
|
||
GetData(vpm, "Local HMI", LW, 73, 1) // 读 X4 段位图 LW-73
|
||
end if // 结束判断
|
||
GETBIT(vpm, bv, 2) // 取位 2(Y3)→ bv
|
||
if bv == 1 then // 该页面有内容?
|
||
SetData(y, "Local HMI", LW, 1, 1) // Y=3 → LW-1
|
||
win = 101 + (x - 1) * 7 + (y - 1) // 算窗口号:101+(X-1)*7+(Y-1)
|
||
SetData(win, "Local HMI", LW, 2, 1) // 窗口号 → LW-2(触发切窗)
|
||
else // 该页面无内容
|
||
SetData(pop, "Local HMI", LB, 124, 1) // 置 LB-124 → 弹 16 号窗
|
||
end if // 结束判断
|
||
else // 权限不通过
|
||
SetData(pop, "Local HMI", LB, 110, 1) // 置 LB-110 → 弹 11 号无权限窗
|
||
end if // 结束判断
|
||
end macro_command // 宏结束
|
||
```
|
||
|
||
**`btn-y4`**(Y4 设备参数 · 权限仅 A/B)
|
||
```
|
||
macro_command main() // 宏入口:按下 Y4 按钮时执行
|
||
short cls = 0 // 当前用户类别位(读 LW-9222)
|
||
short x = 0 // 运行时读回的当前 X(1~4)
|
||
short y = 4 // 本按钮固定切到 Y=4
|
||
short win = 0 // 计算出的目标窗口号
|
||
short ok = 0 // 权限通过标志:1=放行
|
||
short bv = 0 // 页面存在标志:1=有内容
|
||
short vpm = 0 // 当前 X 段页面存在位图
|
||
short pop = 1 // 弹窗置位常量 1
|
||
short bA = 0 // 类别 A 位(工程师)
|
||
short bB = 0 // 类别 B 位(管理员)
|
||
GetData(cls, "Local HMI", LW, 9222, 1) // 读当前用户类别位 → cls
|
||
GETBIT(cls, bA, 0) // 取 bit0 → bA(A 工程师)
|
||
GETBIT(cls, bB, 1) // 取 bit1 → bB(B 管理员)
|
||
if bA == 1 then // 含类别 A?
|
||
ok = 1 // 权限通过
|
||
end if // 结束判断
|
||
if bB == 1 then // 含类别 B?
|
||
ok = 1 // 权限通过
|
||
end if // 结束判断
|
||
if ok == 1 then // 权限通过 → 查当前 X 段位图
|
||
GetData(x, "Local HMI", LW, 0, 1) // 读当前 X → x
|
||
if x == 1 then // 当前在 X1 段?
|
||
GetData(vpm, "Local HMI", LW, 70, 1) // 读 X1 段位图 LW-70
|
||
end if // 结束判断
|
||
if x == 2 then // 当前在 X2 段?
|
||
GetData(vpm, "Local HMI", LW, 71, 1) // 读 X2 段位图 LW-71
|
||
end if // 结束判断
|
||
if x == 3 then // 当前在 X3 段?
|
||
GetData(vpm, "Local HMI", LW, 72, 1) // 读 X3 段位图 LW-72
|
||
end if // 结束判断
|
||
if x == 4 then // 当前在 X4 段?
|
||
GetData(vpm, "Local HMI", LW, 73, 1) // 读 X4 段位图 LW-73
|
||
end if // 结束判断
|
||
GETBIT(vpm, bv, 3) // 取位 3(Y4)→ bv
|
||
if bv == 1 then // 该页面有内容?
|
||
SetData(y, "Local HMI", LW, 1, 1) // Y=4 → LW-1
|
||
win = 101 + (x - 1) * 7 + (y - 1) // 算窗口号:101+(X-1)*7+(Y-1)
|
||
SetData(win, "Local HMI", LW, 2, 1) // 窗口号 → LW-2(触发切窗)
|
||
else // 该页面无内容
|
||
SetData(pop, "Local HMI", LB, 124, 1) // 置 LB-124 → 弹 16 号窗
|
||
end if // 结束判断
|
||
else // 权限不通过
|
||
SetData(pop, "Local HMI", LB, 110, 1) // 置 LB-110 → 弹 11 号无权限窗
|
||
end if // 结束判断
|
||
end macro_command // 宏结束
|
||
```
|
||
|
||
**`btn-y5`**(Y5 I/O 监控 · 权限仅 A/B)
|
||
```
|
||
macro_command main() // 宏入口:按下 Y5 按钮时执行
|
||
short cls = 0 // 当前用户类别位(读 LW-9222)
|
||
short x = 0 // 运行时读回的当前 X(1~4)
|
||
short y = 5 // 本按钮固定切到 Y=5
|
||
short win = 0 // 计算出的目标窗口号
|
||
short ok = 0 // 权限通过标志:1=放行
|
||
short bv = 0 // 页面存在标志:1=有内容
|
||
short vpm = 0 // 当前 X 段页面存在位图
|
||
short pop = 1 // 弹窗置位常量 1
|
||
short bA = 0 // 类别 A 位(工程师)
|
||
short bB = 0 // 类别 B 位(管理员)
|
||
GetData(cls, "Local HMI", LW, 9222, 1) // 读当前用户类别位 → cls
|
||
GETBIT(cls, bA, 0) // 取 bit0 → bA(A 工程师)
|
||
GETBIT(cls, bB, 1) // 取 bit1 → bB(B 管理员)
|
||
if bA == 1 then // 含类别 A?
|
||
ok = 1 // 权限通过
|
||
end if // 结束判断
|
||
if bB == 1 then // 含类别 B?
|
||
ok = 1 // 权限通过
|
||
end if // 结束判断
|
||
if ok == 1 then // 权限通过 → 查当前 X 段位图
|
||
GetData(x, "Local HMI", LW, 0, 1) // 读当前 X → x
|
||
if x == 1 then // 当前在 X1 段?
|
||
GetData(vpm, "Local HMI", LW, 70, 1) // 读 X1 段位图 LW-70
|
||
end if // 结束判断
|
||
if x == 2 then // 当前在 X2 段?
|
||
GetData(vpm, "Local HMI", LW, 71, 1) // 读 X2 段位图 LW-71
|
||
end if // 结束判断
|
||
if x == 3 then // 当前在 X3 段?
|
||
GetData(vpm, "Local HMI", LW, 72, 1) // 读 X3 段位图 LW-72
|
||
end if // 结束判断
|
||
if x == 4 then // 当前在 X4 段?
|
||
GetData(vpm, "Local HMI", LW, 73, 1) // 读 X4 段位图 LW-73
|
||
end if // 结束判断
|
||
GETBIT(vpm, bv, 4) // 取位 4(Y5)→ bv
|
||
if bv == 1 then // 该页面有内容?
|
||
SetData(y, "Local HMI", LW, 1, 1) // Y=5 → LW-1
|
||
win = 101 + (x - 1) * 7 + (y - 1) // 算窗口号:101+(X-1)*7+(Y-1)
|
||
SetData(win, "Local HMI", LW, 2, 1) // 窗口号 → LW-2(触发切窗)
|
||
else // 该页面无内容
|
||
SetData(pop, "Local HMI", LB, 124, 1) // 置 LB-124 → 弹 16 号窗
|
||
end if // 结束判断
|
||
else // 权限不通过
|
||
SetData(pop, "Local HMI", LB, 110, 1) // 置 LB-110 → 弹 11 号无权限窗
|
||
end if // 结束判断
|
||
end macro_command // 宏结束
|
||
```
|
||
|
||
**`btn-y6`**(Y6 报警 · 权限 A/B/C/D)
|
||
```
|
||
macro_command main() // 宏入口:按下 Y6 按钮时执行
|
||
short cls = 0 // 当前用户类别位(读 LW-9222)
|
||
short x = 0 // 运行时读回的当前 X(1~4)
|
||
short y = 6 // 本按钮固定切到 Y=6
|
||
short win = 0 // 计算出的目标窗口号
|
||
short ok = 0 // 权限通过标志:1=放行
|
||
short bv = 0 // 页面存在标志:1=有内容
|
||
short vpm = 0 // 当前 X 段页面存在位图
|
||
short pop = 1 // 弹窗置位常量 1
|
||
short bA = 0 // 类别 A 位(工程师)
|
||
short bB = 0 // 类别 B 位(管理员)
|
||
short bC = 0 // 类别 C 位(上料)
|
||
short bD = 0 // 类别 D 位(制丸)
|
||
GetData(cls, "Local HMI", LW, 9222, 1) // 读当前用户类别位 → cls
|
||
GETBIT(cls, bA, 0) // 取 bit0 → bA(A 工程师)
|
||
GETBIT(cls, bB, 1) // 取 bit1 → bB(B 管理员)
|
||
GETBIT(cls, bC, 2) // 取 bit2 → bC(C 上料)
|
||
GETBIT(cls, bD, 3) // 取 bit3 → bD(D 制丸)
|
||
if bA == 1 then // 含类别 A?
|
||
ok = 1 // 权限通过
|
||
end if // 结束判断
|
||
if bB == 1 then // 含类别 B?
|
||
ok = 1 // 权限通过
|
||
end if // 结束判断
|
||
if bC == 1 then // 含类别 C?
|
||
ok = 1 // 权限通过
|
||
end if // 结束判断
|
||
if bD == 1 then // 含类别 D?
|
||
ok = 1 // 权限通过
|
||
end if // 结束判断
|
||
if ok == 1 then // 权限通过 → 查当前 X 段位图
|
||
GetData(x, "Local HMI", LW, 0, 1) // 读当前 X → x
|
||
if x == 1 then // 当前在 X1 段?
|
||
GetData(vpm, "Local HMI", LW, 70, 1) // 读 X1 段位图 LW-70
|
||
end if // 结束判断
|
||
if x == 2 then // 当前在 X2 段?
|
||
GetData(vpm, "Local HMI", LW, 71, 1) // 读 X2 段位图 LW-71
|
||
end if // 结束判断
|
||
if x == 3 then // 当前在 X3 段?
|
||
GetData(vpm, "Local HMI", LW, 72, 1) // 读 X3 段位图 LW-72
|
||
end if // 结束判断
|
||
if x == 4 then // 当前在 X4 段?
|
||
GetData(vpm, "Local HMI", LW, 73, 1) // 读 X4 段位图 LW-73
|
||
end if // 结束判断
|
||
GETBIT(vpm, bv, 5) // 取位 5(Y6)→ bv
|
||
if bv == 1 then // 该页面有内容?
|
||
SetData(y, "Local HMI", LW, 1, 1) // Y=6 → LW-1
|
||
win = 101 + (x - 1) * 7 + (y - 1) // 算窗口号:101+(X-1)*7+(Y-1)
|
||
SetData(win, "Local HMI", LW, 2, 1) // 窗口号 → LW-2(触发切窗)
|
||
else // 该页面无内容
|
||
SetData(pop, "Local HMI", LB, 124, 1) // 置 LB-124 → 弹 16 号窗
|
||
end if // 结束判断
|
||
else // 权限不通过
|
||
SetData(pop, "Local HMI", LB, 110, 1) // 置 LB-110 → 弹 11 号无权限窗
|
||
end if // 结束判断
|
||
end macro_command // 宏结束
|
||
```
|
||
|
||
**`btn-y7`**(Y7 数据趋势 · 权限 A/B/C/D)
|
||
```
|
||
macro_command main() // 宏入口:按下 Y7 按钮时执行
|
||
short cls = 0 // 当前用户类别位(读 LW-9222)
|
||
short x = 0 // 运行时读回的当前 X(1~4)
|
||
short y = 7 // 本按钮固定切到 Y=7
|
||
short win = 0 // 计算出的目标窗口号
|
||
short ok = 0 // 权限通过标志:1=放行
|
||
short bv = 0 // 页面存在标志:1=有内容
|
||
short vpm = 0 // 当前 X 段页面存在位图
|
||
short pop = 1 // 弹窗置位常量 1
|
||
short bA = 0 // 类别 A 位(工程师)
|
||
short bB = 0 // 类别 B 位(管理员)
|
||
short bC = 0 // 类别 C 位(上料)
|
||
short bD = 0 // 类别 D 位(制丸)
|
||
GetData(cls, "Local HMI", LW, 9222, 1) // 读当前用户类别位 → cls
|
||
GETBIT(cls, bA, 0) // 取 bit0 → bA(A 工程师)
|
||
GETBIT(cls, bB, 1) // 取 bit1 → bB(B 管理员)
|
||
GETBIT(cls, bC, 2) // 取 bit2 → bC(C 上料)
|
||
GETBIT(cls, bD, 3) // 取 bit3 → bD(D 制丸)
|
||
if bA == 1 then // 含类别 A?
|
||
ok = 1 // 权限通过
|
||
end if // 结束判断
|
||
if bB == 1 then // 含类别 B?
|
||
ok = 1 // 权限通过
|
||
end if // 结束判断
|
||
if bC == 1 then // 含类别 C?
|
||
ok = 1 // 权限通过
|
||
end if // 结束判断
|
||
if bD == 1 then // 含类别 D?
|
||
ok = 1 // 权限通过
|
||
end if // 结束判断
|
||
if ok == 1 then // 权限通过 → 查当前 X 段位图
|
||
GetData(x, "Local HMI", LW, 0, 1) // 读当前 X → x
|
||
if x == 1 then // 当前在 X1 段?
|
||
GetData(vpm, "Local HMI", LW, 70, 1) // 读 X1 段位图 LW-70
|
||
end if // 结束判断
|
||
if x == 2 then // 当前在 X2 段?
|
||
GetData(vpm, "Local HMI", LW, 71, 1) // 读 X2 段位图 LW-71
|
||
end if // 结束判断
|
||
if x == 3 then // 当前在 X3 段?
|
||
GetData(vpm, "Local HMI", LW, 72, 1) // 读 X3 段位图 LW-72
|
||
end if // 结束判断
|
||
if x == 4 then // 当前在 X4 段?
|
||
GetData(vpm, "Local HMI", LW, 73, 1) // 读 X4 段位图 LW-73
|
||
end if // 结束判断
|
||
GETBIT(vpm, bv, 6) // 取位 6(Y7)→ bv
|
||
if bv == 1 then // 该页面有内容?
|
||
SetData(y, "Local HMI", LW, 1, 1) // Y=7 → LW-1
|
||
win = 101 + (x - 1) * 7 + (y - 1) // 算窗口号:101+(X-1)*7+(Y-1)
|
||
SetData(win, "Local HMI", LW, 2, 1) // 窗口号 → LW-2(触发切窗)
|
||
else // 该页面无内容
|
||
SetData(pop, "Local HMI", LB, 124, 1) // 置 LB-124 → 弹 16 号窗
|
||
end if // 结束判断
|
||
else // 权限不通过
|
||
SetData(pop, "Local HMI", LB, 110, 1) // 置 LB-110 → 弹 11 号无权限窗
|
||
end if // 结束判断
|
||
end macro_command // 宏结束
|
||
```
|
||
|
||
**`btn-login-index`**(登录:索引登入 → 按组定位;结果提示已内联,无宏编号依赖)
|
||
```
|
||
macro_command main() // 宏入口:点登录按钮时执行
|
||
short cmd = 2 // 命令=2:使用索引登入(读 LW-102 选中的账号)
|
||
short res = 0 // 存放命令结果(读 LW-101)
|
||
short cls = 0 // 当前用户类别位(读 LW-9222)
|
||
short x = 1 // 登录后入口 X 初值 = 1
|
||
short y = 1 // 登录后入口 Y = 1
|
||
short win = 0 // 计算出的目标窗口号
|
||
short idx = 7 // 提示编号(默认 7=登录失败)
|
||
short bA = 0 // 类别 A 位(工程师)
|
||
short bB = 0 // 类别 B 位(管理员)
|
||
short bC = 0 // 类别 C 位(上料)
|
||
short bD = 0 // 类别 D 位(制丸)
|
||
short z = 0 // 常量 0(清命令/清旧结果用)
|
||
SetData(z, "Local HMI", LW, 101, 1) // 先清旧结果 → 防止读到上一次的码
|
||
SetData(z, "Local HMI", LW, 261, 1) // 清底部提示 → 不显示上一次的信息
|
||
SetData(z, "Local HMI", LW, 100, 1) // 命令先清 0(保证 0→2 有跳变)
|
||
SetData(cmd, "Local HMI", LW, 100, 1) // 发命令 2 → LW-100(索引登入)
|
||
DELAY(300) // 等 0.3 秒
|
||
GetData(res, "Local HMI", LW, 101, 1) // 读命令结果 → res(1=成功)
|
||
if res == 0 then // 结果仍为 0?
|
||
DELAY(300) // 再等 0.3 秒
|
||
GetData(res, "Local HMI", LW, 101, 1) // 再读一次
|
||
end if // 结束判断
|
||
if res == 1 then // 结果=1?
|
||
idx = 1 // 提示编号 1:登录成功
|
||
end if // 结束判断
|
||
if res == 8 then // 结果=8?
|
||
idx = 2 // 提示编号 2:账号不存在
|
||
end if // 结束判断
|
||
if res == 16 then // 结果=16?
|
||
idx = 3 // 提示编号 3:密码错误
|
||
end if // 结束判断
|
||
if res == 32 then // 结果=32?
|
||
idx = 4 // 提示编号 4:命令无法执行
|
||
end if // 结束判断
|
||
if res == 64 then // 结果=64?
|
||
idx = 5 // 提示编号 5:名称不合法
|
||
end if // 结束判断
|
||
if res == 128 then // 结果=128?
|
||
idx = 6 // 提示编号 6:密码含无效字符
|
||
end if // 结束判断
|
||
if res == 0 then // 结果=0?
|
||
idx = 0 // 提示编号 0:不显示
|
||
end if // 结束判断
|
||
SetData(idx, "Local HMI", LW, 261, 1) // 提示编号 → LW-261(立即显示)
|
||
if res == 1 then // 登录成功?
|
||
GetData(cls, "Local HMI", LW, 9222, 1) // 读当前用户类别位 → cls
|
||
GETBIT(cls, bA, 0) // 取 bit0 → bA(A 工程师)
|
||
GETBIT(cls, bB, 1) // 取 bit1 → bB(B 管理员)
|
||
GETBIT(cls, bC, 2) // 取 bit2 → bC(C 上料)
|
||
GETBIT(cls, bD, 3) // 取 bit3 → bD(D 制丸)
|
||
if bD == 1 then // 含类别 D(制丸)?
|
||
x = 3 // 只有制丸组 → 入口 X3
|
||
end if // 结束判断
|
||
if bA == 1 then // 含类别 A?
|
||
x = 1 // 入口 X1
|
||
end if // 结束判断
|
||
if bB == 1 then // 含类别 B?
|
||
x = 1 // 入口 X1
|
||
end if // 结束判断
|
||
if bC == 1 then // 含类别 C?
|
||
x = 1 // 入口 X1
|
||
end if // 结束判断
|
||
win = 101 + (x - 1) * 7 + (y - 1) // 算目标窗口号:101+(X-1)*7+(Y-1)
|
||
SetData(x, "Local HMI", LW, 0, 1) // X → LW-0
|
||
SetData(y, "Local HMI", LW, 1, 1) // Y → LW-1
|
||
SetData(win, "Local HMI", LW, 2, 1) // 窗口号 → LW-2(触发切窗)
|
||
end if // 结束判断
|
||
end macro_command // 宏结束
|
||
```
|
||
|
||
**`logout`**(注销并回登录页;10 号窗「打开窗口时执行」也用它)
|
||
```
|
||
macro_command main() // 宏入口:点注销按钮 / 进 10 号窗时执行
|
||
short cmd = 3 // 命令=3:注销当前账号
|
||
short win = 10 // 目标窗口号 = 10(登录页)
|
||
short z = 0 // 常量 0
|
||
short z8[8] = {0,0,0,0,0,0,0,0} // 8 个 0(清用户名/密码框用)
|
||
SetData(cmd, "Local HMI", LW, 100, 1) // 发命令 3 → LW-100(注销)
|
||
SetData(z, "Local HMI", LW, 0, 1) // X 清 0
|
||
SetData(z, "Local HMI", LW, 1, 1) // Y 清 0
|
||
SetData(z8[0], "Local HMI", LW, 104, 8) // 清用户名框 LW-104~111(下次默认下拉登入)
|
||
SetData(z8[0], "Local HMI", LW, 112, 8) // 清密码框 LW-112~119
|
||
SetData(win, "Local HMI", LW, 2, 1) // 窗口号 10 → LW-2(切回登录页)
|
||
end macro_command // 宏结束
|
||
```
|
||
|
||
**`admin-open`**(登录页 logo 上透明按钮,长按 3 秒)
|
||
```
|
||
macro_command main() // 宏入口:长按登录页隐藏按钮时执行
|
||
short on = 1 // 置位常量 1
|
||
short z8[8] = {0,0,0,0,0,0,0,0} // 8 个 0(先清输入框)
|
||
SetData(z8[0], "Local HMI", LW, 104, 8) // 清用户名框 LW-104~111
|
||
SetData(z8[0], "Local HMI", LW, 112, 8) // 清密码框 LW-112~119
|
||
SetData(on, "Local HMI", LB, 125, 1) // 置 LB-125 → 弹 17 号管理员登录窗
|
||
end macro_command // 宏结束
|
||
```
|
||
|
||
**`admin-login`**(17 号窗「登录」:固定名称登入)
|
||
```
|
||
macro_command main() // 宏入口:点 17 号窗「登录」时执行
|
||
short cmd = 1 // 命令=1:使用名称登入(读 LW-104 + LW-112)
|
||
short res = 0 // 命令结果(读 LW-101)
|
||
short cls = 0 // 当前用户类别位(读 LW-9222)
|
||
short x = 1 // 入口 X 初值 = 1
|
||
short y = 1 // 入口 Y = 1
|
||
short win = 0 // 计算出的目标窗口号
|
||
short idx = 7 // 提示编号(默认 7=登录失败)
|
||
short bA = 0 // 类别 A 位(工程师)
|
||
short bB = 0 // 类别 B 位(管理员)
|
||
short bC = 0 // 类别 C 位(上料)
|
||
short bD = 0 // 类别 D 位(制丸)
|
||
short z = 0 // 常量 0
|
||
SetData(z, "Local HMI", LW, 101, 1) // 先清旧结果 → 防止读到上一次的码
|
||
SetData(z, "Local HMI", LW, 261, 1) // 清旧提示
|
||
SetData(z, "Local HMI", LW, 100, 1) // 命令先清 0
|
||
SetData(cmd, "Local HMI", LW, 100, 1) // 发命令 1 → LW-100(名称登入)
|
||
DELAY(300) // 等 0.3 秒
|
||
GetData(res, "Local HMI", LW, 101, 1) // 读命令结果 → res(1=成功)
|
||
if res == 0 then // 结果仍为 0?
|
||
DELAY(300) // 再等 0.3 秒
|
||
GetData(res, "Local HMI", LW, 101, 1) // 再读一次
|
||
end if // 结束判断
|
||
if res == 1 then // 结果=1?
|
||
idx = 1 // 提示编号 1:登录成功
|
||
end if // 结束判断
|
||
if res == 8 then // 结果=8?
|
||
idx = 2 // 提示编号 2:账号不存在
|
||
end if // 结束判断
|
||
if res == 16 then // 结果=16?
|
||
idx = 3 // 提示编号 3:密码错误
|
||
end if // 结束判断
|
||
if res == 32 then // 结果=32?
|
||
idx = 4 // 提示编号 4:命令无法执行
|
||
end if // 结束判断
|
||
if res == 64 then // 结果=64?
|
||
idx = 5 // 提示编号 5:名称不合法
|
||
end if // 结束判断
|
||
if res == 128 then // 结果=128?
|
||
idx = 6 // 提示编号 6:密码含无效字符
|
||
end if // 结束判断
|
||
if res == 0 then // 结果=0?
|
||
idx = 0 // 提示编号 0:不显示
|
||
end if // 结束判断
|
||
SetData(idx, "Local HMI", LW, 261, 1) // 提示编号 → LW-261(立即显示)
|
||
if res == 1 then // 登录成功?
|
||
SetData(z, "Local HMI", LB, 125, 1) // 清 LB-125 → 关 17 号弹窗
|
||
GetData(cls, "Local HMI", LW, 9222, 1) // 读当前用户类别位 → cls
|
||
GETBIT(cls, bA, 0) // 取 bit0 → bA
|
||
GETBIT(cls, bB, 1) // 取 bit1 → bB
|
||
GETBIT(cls, bC, 2) // 取 bit2 → bC
|
||
GETBIT(cls, bD, 3) // 取 bit3 → bD
|
||
if bD == 1 then // 含类别 D?
|
||
x = 3 // 只有制丸组 → X3
|
||
end if // 结束判断
|
||
if bA == 1 then // 含类别 A?
|
||
x = 1 // 入口 X1
|
||
end if // 结束判断
|
||
if bB == 1 then // 含类别 B?
|
||
x = 1 // 入口 X1
|
||
end if // 结束判断
|
||
if bC == 1 then // 含类别 C?
|
||
x = 1 // 入口 X1
|
||
end if // 结束判断
|
||
win = 101 + (x - 1) * 7 + (y - 1) // 算目标窗口号
|
||
SetData(x, "Local HMI", LW, 0, 1) // X → LW-0
|
||
SetData(y, "Local HMI", LW, 1, 1) // Y → LW-1
|
||
SetData(win, "Local HMI", LW, 2, 1) // 窗口号 → LW-2(触发切窗)
|
||
end if // 结束判断
|
||
end macro_command // 宏结束
|
||
```
|
||
|
||
**`admin-close`**(17 号窗「取消」)
|
||
```
|
||
macro_command main() // 宏入口:点 17 号窗「取消」时执行
|
||
short z = 0 // 常量 0
|
||
short z8[8] = {0,0,0,0,0,0,0,0} // 8 个 0
|
||
SetData(z, "Local HMI", LB, 125, 1) // 清 LB-125 → 关 17 号窗
|
||
SetData(z8[0], "Local HMI", LW, 104, 8) // 清用户名框
|
||
SetData(z8[0], "Local HMI", LW, 112, 8) // 清密码框
|
||
end macro_command // 宏结束
|
||
```
|
||
|
||
**`close-msg`**(关闭无权限提示窗)
|
||
```
|
||
macro_command main() // 宏入口:点 11 号窗「确定」时执行
|
||
short z = 0 // 常量 0
|
||
SetData(z, "Local HMI", LB, 110, 1) // 清 LB-110 → 关闭 11 号无权限窗
|
||
end macro_command // 宏结束
|
||
```
|
||
|
||
**`close-nopage`**(关闭 16 号「无内容」提示窗)
|
||
```
|
||
macro_command main() // 宏入口:点 16 号窗「确定」时执行
|
||
short z = 0 // 常量 0
|
||
SetData(z, "Local HMI", LB, 124, 1) // 清 LB-124 → 关闭 16 号无内容窗
|
||
end macro_command // 宏结束
|
||
```
|
||
|
||
**用户管理 `usr-*`**
|
||
|
||
| 宏 | 命令 | 说明 |
|
||
| --- | --- | --- |
|
||
| `usr-init` | — | 14 号窗「打开窗口时执行」:清 `LW-104`/`LW-112`/`LW-103`/`LW-101`,清 `LB-121` |
|
||
| `user-open` | — | 顶部按钮:仅 B/admin → 置 `LB-122` |
|
||
| `usr-back` | — | 清 `LB-122` |
|
||
| `usr-add` | `5` | 新增(`LW-104`+`LW-112`+`LW-103`) |
|
||
| `usr-delete` | — | 置 `LB-121` 弹确认 |
|
||
| `usr-delete-ok` | `8` | 按索引删除 |
|
||
| `usr-delete-cancel` | — | 清 `LB-121` |
|
||
| `usr-getlevel` | `14` | 按索引读权限 → `LW-103` |
|
||
| `usr-setlevel` | `10` | 按索引设权限 |
|
||
| `usr-setpwd` | `12` | 按索引设密码 |
|
||
|
||
```
|
||
macro_command main() // 宏入口:用户管理按钮(以 cmd=14 读取权限为例)
|
||
short cmd = 14 // 命令值:改成 5/8/10/12 等即为对应功能
|
||
SetData(cmd, "Local HMI", LW, 100, 1) // 发命令 → LW-100
|
||
end macro_command // 宏结束
|
||
```
|
||
> 其余 `usr-*` 同上模板:`cmd` = 5 / 8 / 10 / 12;`user-open` 置 / `usr-back` 清 `LB-122`,`usr-delete` / `usr-delete-cancel` 置 / 清 `LB-121`,`usr-init` 清输入。
|
||
|
||
**关于窗 `about-*`**:`about-open` 置 `LB-123`(弹 13 号窗);`about-close` 清 `LB-123`。
|
||
|
||
**修改时间**
|
||
|
||
| 宏 | 触发 | 作用 |
|
||
| --- | --- | --- |
|
||
| `open-time` | 时钟上透明按钮(仅 B) | 读 `LW-9017`~`9022` → `LW-40`~`45`,置 `LB-120` |
|
||
| `set-time` | 12 号窗「设定」 | `LW-40`~`45` → `LW-9017`~`9022`(设置 RTC),清 `LB-120` |
|
||
| `close-time` | 12 号窗「取消」 | 清 `LB-120` |
|
||
|
||
```
|
||
macro_command main() // 宏入口:改时间弹窗点「设定」时执行
|
||
short v[6] = {0,0,0,0,0,0} // 暂存数组:秒/分/时/日/月/年
|
||
short z = 0 // 常量 0
|
||
GetData(v[0], "Local HMI", LW, 40, 6) // 从 LW-40~45 读入 6 个值 → v
|
||
SetData(v[0], "Local HMI", LW, 9017, 6) // v 写入 RTC 寄存器 LW-9017~9022(设置时间)
|
||
SetData(z, "Local HMI", LB, 120, 1) // 清 LB-120 → 关闭 12 号弹窗
|
||
end macro_command // 宏结束
|
||
```
|
||
|
||
**网络设置 `net-*`**
|
||
|
||
**`net-read`**(13 号窗「打开窗口时执行」:系统值 → 暂存 RW)
|
||
```
|
||
macro_command main() // 宏入口:进 13 号窗时执行
|
||
short v[4] = {0,0,0,0} // 4 字暂存数组
|
||
short line = 1 // 制丸线别(1=A / 2=B)
|
||
GetData(line, "Local HMI", RW, 61, 1) // 读 RW-61 线别
|
||
GetData(v[0], "Local HMI", LW, 9129, 4) // 读 HMI IP
|
||
SetData(v[0], "Local HMI", RW, 20, 4) // → RW-20~23
|
||
GetData(v[0], "Local HMI", LW, 10750, 4) // 读 HMI 掩码
|
||
SetData(v[0], "Local HMI", RW, 24, 4) // → RW-24~27
|
||
GetData(v[0], "Local HMI", LW, 9125, 4) // 读 HMI 网关
|
||
SetData(v[0], "Local HMI", RW, 28, 4) // → RW-28~31
|
||
GetData(v[0], "Local HMI", LW, 9600, 4) // 读上料 PLC(设备4)IP
|
||
SetData(v[0], "Local HMI", RW, 40, 4) // → RW-40~43
|
||
GetData(v[0], "Local HMI", LW, 9605, 4) // 读制丸 PLC(设备5)IP
|
||
if line == 1 then // 当前选 A 线?
|
||
SetData(v[0], "Local HMI", RW, 44, 4) // → RW-44~47(制丸A)
|
||
else // 当前选 B 线
|
||
SetData(v[0], "Local HMI", RW, 48, 4) // → RW-48~51(制丸B)
|
||
end if // 结束判断
|
||
end macro_command // 宏结束
|
||
```
|
||
|
||
**`net-apply`**(工程宏 ID 037;13 号窗「应用」按钮 + 宏属性勾「当 HMI 启动时即执行一次」)
|
||
|
||
> **设备归属(10-27 按 EB 设备列表实测,数字以此为准)**
|
||
> `设备4 = 制丸1(192.168.189.22)`、`设备5 = 上料清洗(192.168.189.2)`,两台都是 S7CommPlus + 符号寻址。
|
||
> 所以:**上料 IP → `LW-9605` / `LB-10071`(设备5)**,**制丸 IP → `LW-9600` / `LB-10070`(设备4)**。
|
||
|
||
```
|
||
macro_command main() // 宏入口:点「应用」/ 开机自动套用
|
||
short v[4] = {0,0,0,0} // 4 字暂存数组
|
||
short hmi0 = 0 // HMI IP 第一段(判断是否配置过)
|
||
short role = 0 // 本机角色(1上料/2制丸A/3制丸B)
|
||
short line = 1 // 制丸线别(1=A/2=B)
|
||
short okp = 0 // 是否连接制丸设备:1=连
|
||
short on = 1 // 置位常量
|
||
short z = 0 // 常量 0
|
||
GetData(hmi0, "Local HMI", RW, 20, 1) // 读 RW-20(HMI IP 第一段)
|
||
GetData(role, "Local HMI", RW, 60, 1) // 读 RW-60(本机角色)
|
||
GetData(line, "Local HMI", RW, 61, 1) // 读 RW-61(线别)
|
||
if line == 0 then // 线别未设置?
|
||
line = 1 // 默认 A 线
|
||
end if // 结束判断
|
||
if role == 1 then // 上料屏?
|
||
okp = 1 // 连制丸设备(线别按 RW-61)
|
||
end if // 结束判断
|
||
if role == 2 then // 制丸A屏?
|
||
line = 1 // 强制 A 线
|
||
okp = 1 // 连制丸设备
|
||
end if // 结束判断
|
||
if role == 3 then // 制丸B屏?
|
||
line = 2 // 强制 B 线
|
||
okp = 1 // 连制丸设备
|
||
end if // 结束判断
|
||
SetData(line, "Local HMI", RW, 61, 1) // 回写线别(界面显示一致)
|
||
if hmi0 == 0 then // HMI IP 没填 → 跳过 HMI 部分
|
||
hmi0 = 0 // (保持原 HMI 网络)
|
||
else // 已填 → 应用 HMI 网络
|
||
GetData(v[0], "Local HMI", RW, 20, 4) // RW → HMI IP
|
||
SetData(v[0], "Local HMI", LW, 9129, 4) // 写 LW-9129~9132
|
||
GetData(v[0], "Local HMI", RW, 24, 4) // RW → HMI 掩码
|
||
SetData(v[0], "Local HMI", LW, 10750, 4) // 写 LW-10750~10753
|
||
GetData(v[0], "Local HMI", RW, 28, 4) // RW → HMI 网关
|
||
SetData(v[0], "Local HMI", LW, 9125, 4) // 写 LW-9125~9128
|
||
SetData(on, "Local HMI", LB, 12094, 1) // 置 LB-12094 → HMI 网络生效
|
||
end if // 结束判断
|
||
GetData(v[0], "Local HMI", RW, 40, 4) // RW → 上料 PLC IP
|
||
if v[0] == 0 then // 没填(新屏/模拟)→ 不写、不重连
|
||
v[0] = 0 // 保留工程里的设备 IP
|
||
else // 已填 → 套用(设备5 = 上料清洗)
|
||
SetData(v[0], "Local HMI", LW, 9605, 4) // 写设备5 IP
|
||
SetData(on, "Local HMI", LB, 10071, 1) // 重连设备5
|
||
end if // 结束判断
|
||
if okp == 1 then // 需要连制丸设备?
|
||
if line == 1 then // 选 A 线
|
||
GetData(v[0], "Local HMI", RW, 44, 4) // RW → 制丸A IP
|
||
else // 选 B 线
|
||
GetData(v[0], "Local HMI", RW, 48, 4) // RW → 制丸B IP
|
||
end if // 结束判断
|
||
if v[0] == 0 then // 没填 → 不写、不重连
|
||
v[0] = 0 // 保留工程里的设备 IP
|
||
else // 已填 → 套用(设备4 = 制丸1)
|
||
SetData(v[0], "Local HMI", LW, 9600, 4) // 写设备4 IP
|
||
SetData(on, "Local HMI", LB, 10070, 1) // 重连设备4
|
||
end if // 结束判断
|
||
end if // 结束判断(角色=0:不连制丸设备,防误连)
|
||
DELAY(1000) // 等 1 秒(嫌开机慢可改 300)
|
||
SetData(z, "Local HMI", LB, 12094, 1) // 清 LB-12094
|
||
SetData(z, "Local HMI", LB, 10070, 1) // 清 LB-10070
|
||
SetData(z, "Local HMI", LB, 10071, 1) // 清 LB-10071
|
||
end macro_command // 宏结束
|
||
```
|
||
|
||
**与工程现版(10-27 摘录)的三个差别**
|
||
|
||
| # | 现版 | 本节 |
|
||
| --- | --- | --- |
|
||
| 1 | 注释把设备号写反(`写上料 PLC(设备4)`) | 注释已改正;**数字一个没改** |
|
||
| 2 | 无 `v[0]==0` 保护,RW 为空时把 IP 刷成 `0.0.0.0` | 首段为 0 跳过写入与重连 |
|
||
| 3 | `DELAY(1000)` | 保留,可改 300 缩短开机等待 |
|
||
|
||
> `LB-11963`/`LB-11964` 那条屏蔽设备 1~8 通讯弹窗的宏(ID 048 `屏蔽通讯异常提示`,周期执行)与本宏无关,别混。
|
||
**`line-ab-switch`**(13 号窗「A/B 切换」按钮;仅本机角色=1 生效)
|
||
```
|
||
macro_command main() // 宏入口:点 A/B 线切换按钮
|
||
short v[4] = {0,0,0,0} // 4 字暂存数组
|
||
short role = 0 // 本机角色(读 RW-60)
|
||
short line = 1 // 当前线别
|
||
short on = 1 // 置位常量
|
||
short z = 0 // 常量 0
|
||
GetData(role, "Local HMI", RW, 60, 1) // 读本机角色
|
||
if role == 1 then // 只有上料屏允许切换
|
||
GetData(line, "Local HMI", RW, 61, 1) // 读当前线别
|
||
if line == 1 then // 当前 A → 切 B
|
||
line = 2 // 目标 B
|
||
else // 当前 B → 切 A
|
||
line = 1 // 目标 A
|
||
end if // 结束判断
|
||
SetData(line, "Local HMI", RW, 61, 1) // 写回 RW-61
|
||
if line == 1 then // 目标 A 线
|
||
GetData(v[0], "Local HMI", RW, 44, 4) // 取制丸A IP
|
||
else // 目标 B 线
|
||
GetData(v[0], "Local HMI", RW, 48, 4) // 取制丸B IP
|
||
end if // 结束判断
|
||
SetData(v[0], "Local HMI", LW, 9605, 4) // 写设备5 IP
|
||
SetData(on, "Local HMI", LB, 10071, 1) // 重连设备5
|
||
DELAY(1000) // 等 1 秒
|
||
SetData(z, "Local HMI", LB, 10071, 1) // 清重连位
|
||
end if // 非上料屏:无动作(线别锁定)
|
||
end macro_command // 宏结束
|
||
```
|
||
|
||
|
||
### X2Y2 分区聚焦弹窗(工程实际名 `x2y2-focus-area*`)
|
||
|
||
> 施工见 `开发主文件.md` 7.7.3。**旧文档的 `area-1~4` / `area-close` 作废**,工程实际是:
|
||
|
||
| 宏 | 触发 | 作用 |
|
||
| --- | --- | --- |
|
||
| `x2y2-focus-area1` | 区域①透明键 | 写 `LW-50` = 目标窗口号 |
|
||
| `x2y2-focus-area2` | 区域②透明键 | 同上 |
|
||
| `x2y2-focus-area3` | 区域③透明键 | 同上 |
|
||
| `x2y2-focus-area-close` | 「关闭」键 / X2Y2 打开窗口时 | `LW-50` = 0 收起 |
|
||
|
||
**只有 3 个区域**(原第④区已并入③),没有 area-4。
|
||
|
||
**窗口号已确认**:工程窗口表里 `30/31/32 = x2y2-focus-area1/2/3`,所以 `LW-50` 写的是 **30/31/32**;旧版本节写的 `141/142/143` 作废(`地址表.md` 5.1 已同步)。
|
||
---
|
||
|
||
## 6.2 补录:2026-10-27 从工程逐个截图核对的宏
|
||
|
||
> 以下正文与 EB 宏编辑器里的实际内容一致(编号/名称取自宏列表)。执行条件:无标记=按钮触发;`P`=周期执行。
|
||
|
||
**`x2y2-focus-area1`(ID 039)**
|
||
```
|
||
macro_command main() // 宏入口:点该区域时执行
|
||
short win = 30 // 目标弹窗窗口号
|
||
SetData(win, "Local HMI", LW, 50, 1) // 写 LW-50 → 间接窗口显示 30
|
||
end macro_command // 宏结束
|
||
```
|
||
|
||
**`x2y2-focus-area2`(ID 040)**:同上,`win = 31`(显示 31)
|
||
**`x2y2-focus-area3`(ID 041)**:同上,`win = 32`(显示 32)
|
||
|
||
```
|
||
macro_command main() // 宏入口:关闭区域弹窗
|
||
short z = 0 // 常量 0
|
||
SetData(z, "Local HMI", LW, 50, 1) // 写 LW-50=0 → 间接窗口收起
|
||
end macro_command // 宏结束
|
||
```
|
||
(`x2y2-focus-area-close`,ID 043)
|
||
|
||
**`IO切换上料`(ID 042)/ `IO切换清洗`(ID 044)/ `IO切换制丸`(ID 045)**
|
||
|
||
三支结构相同,只有两个常量不同:
|
||
|
||
```
|
||
macro_command main()
|
||
unsigned char byteA, byteB
|
||
byteA = 9 // → LW-300:IO 组索引(供 050 IO 判断)
|
||
byteB = 158 // → LW-2:目标窗口号
|
||
SetData(byteA, "Local HMI", LW, 300, 1)
|
||
SetData(byteB, "Local HMI", LW, 2, 1)
|
||
end macro_command
|
||
```
|
||
|
||
| 宏 | `byteA`(LW-300) | `byteB`(LW-2 → 窗口) | 对应窗口 |
|
||
| --- | --- | --- | --- |
|
||
| `IO切换上料` | 9 | 158 | 158 = 上料-IO监控DI1-2 |
|
||
| `IO切换清洗` | 15 | 168 | 168 = 清洗-IO监控DO11-12 |
|
||
| `IO切换制丸` | 1 | 151 | 151 = 制丸-IO监控DI1-2 |
|
||
|
||
**`上料参数`(ID 046)**
|
||
```
|
||
macro_command main()
|
||
unsigned char byteB
|
||
byteB = 210 // 目标窗口号
|
||
SetData(byteB, "Local HMI", LW, 2, 1)
|
||
end macro_command
|
||
```
|
||
> ⚠ **存疑**:窗口 210 在工程窗口表里是「清洗-点动」,不是上料参数页。要么宏值过时,要么窗口被改作他用,需现场确认。
|
||
|
||
**`温度监控`(ID 047,周期 10×100ms = 1 s)**
|
||
```
|
||
macro_command main()
|
||
float temp[16] // 16 个 REAL,每个占 2 个 LW
|
||
GetData(temp[0], "制丸1", "PLC.Blocks.HMI_EM02.Temperature_PV[1]", 0, 16)
|
||
SetData(temp[0], "Local HMI", LW, 200, 16)
|
||
end macro_command
|
||
```
|
||
> ⚠ **长度存疑**:`float` 每个占 2 个寄存器,16 个 REAL = 32 字(LW200~231)。但 `SetData(..., LW, 200, 16)` 只写 16 字 = 8 个 REAL。注释写的 `[16]→LW230/231` 与调用参数**必有一处错**,需核对显示元件的地址范围。
|
||
|
||
**`出条温度监控`(ID 049,周期 10×100ms = 1 s)**
|
||
```
|
||
macro_command main()
|
||
float temp[10]
|
||
GetData(temp[0], "制丸1", "PLC.Blocks.HMI_EM02.HIKMICRO_Temp_R[1]", 0, 10)
|
||
SetData(temp[0], "Local HMI", LW, 240, 10)
|
||
end macro_command
|
||
```
|
||
> ⚠ 同上:10 个 REAL = 20 字(LW240~259),`count=10` 只覆盖到 LW249。
|
||
|
||
**`屏蔽通讯异常提示`(ID 048,周期 1×100ms = 100 ms)**
|
||
```
|
||
macro_command main()
|
||
short ON
|
||
ON = 1
|
||
SetData(ON, "Local HMI", LB, 11960, 1)
|
||
SetData(ON, "Local HMI", LB, 11961, 1)
|
||
SetData(ON, "Local HMI", LB, 11962, 1)
|
||
SetData(ON, "Local HMI", LB, 11963, 1)
|
||
SetData(ON, "Local HMI", LB, 11964, 1)
|
||
SetData(ON, "Local HMI", LB, 11965, 1)
|
||
SetData(ON, "Local HMI", LB, 11966, 1)
|
||
SetData(ON, "Local HMI", LB, 11967, 1)
|
||
end macro_command
|
||
```
|
||
> 含义:每 100 ms 把**设备 1~8** 的 "Device No Response" 弹窗全部压回屏蔽。要恢复提示必须改这支宏。周期可放宽到 1 s,没必要 100 ms。
|
||
|
||
**`IO`(ID 050,周期 1×100ms = 100 ms)**
|
||
|
||
按 `LW-300` 的索引读对应 IO 组到四个字节,并写 `LW-310~313` 供画面调试显示。
|
||
|
||
```
|
||
macro_command main()
|
||
short bTrigger
|
||
unsigned char byteA, byteB, byteC, byteD
|
||
bTrigger = 0
|
||
byteA = 0
|
||
byteB = 0
|
||
byteC = 0
|
||
byteD = 0
|
||
GetData (bTrigger, "Local HMI", LW, 300, 1) // IO 组索引(042/044/045 写入)
|
||
|
||
if bTrigger==1 then // 制丸 DI01-02 → 窗口 151
|
||
GetData (byteA, "制丸1", "PLC.Tags.Table.Local_DI01A", 1)
|
||
GetData (byteB, "制丸1", "PLC.Tags.Table.Local_DI01B", 1)
|
||
GetData (byteC, "制丸1", "PLC.Tags.Table.Local_DI02A", 1)
|
||
GetData (byteD, "制丸1", "PLC.Tags.Table.Local_DI02B", 1)
|
||
end if
|
||
if bTrigger==2 then // 制丸 DI03-04 → 152
|
||
GetData (byteA, "制丸1", "PLC.Tags.Table.Local_DI03A", 1)
|
||
GetData (byteB, "制丸1", "PLC.Tags.Table.Local_DI03B", 1)
|
||
GetData (byteC, "制丸1", "PLC.Tags.Table.Local_DI04A", 1)
|
||
GetData (byteD, "制丸1", "PLC.Tags.Table.Local_DI04B", 1)
|
||
end if
|
||
if bTrigger==3 then // 制丸 DI05 → 153
|
||
GetData (byteA, "制丸1", "PLC.Tags.Table.Local_DI05A", 1)
|
||
GetData (byteB, "制丸1", "PLC.Tags.Table.Local_DI05B", 1)
|
||
end if
|
||
if bTrigger==4 then // 制丸 DO01-02 → 154
|
||
GetData (byteA, "制丸1", "PLC.Tags.Table.Local_DO01A", 1)
|
||
GetData (byteB, "制丸1", "PLC.Tags.Table.Local_DO01B", 1)
|
||
GetData (byteC, "制丸1", "PLC.Tags.Table.Local_DO02A", 1)
|
||
GetData (byteD, "制丸1", "PLC.Tags.Table.Local_DO02B", 1)
|
||
end if
|
||
if bTrigger==5 then // 制丸 DO03-04 → 155
|
||
GetData (byteA, "制丸1", "PLC.Tags.Table.Local_DO03A", 1)
|
||
GetData (byteB, "制丸1", "PLC.Tags.Table.Local_DO03B", 1)
|
||
GetData (byteC, "制丸1", "PLC.Tags.Table.Local_DO04A", 1)
|
||
GetData (byteD, "制丸1", "PLC.Tags.Table.Local_DO04B", 1)
|
||
end if
|
||
// 6、7 未使用(跳过)
|
||
if bTrigger==8 then // 上料 DI01-02 → 158
|
||
GetData (byteA, "上料清洗", "PLC.Tags.Table.Local_DI01A", 1)
|
||
GetData (byteB, "上料清洗", "PLC.Tags.Table.Local_DI01B", 1)
|
||
GetData (byteC, "上料清洗", "PLC.Tags.Table.Local_DI02A", 1)
|
||
GetData (byteD, "上料清洗", "PLC.Tags.Table.Local_DI02B", 1)
|
||
end if
|
||
if bTrigger==9 then // 上料 DI03-04 → 159
|
||
GetData (byteA, "上料清洗", "PLC.Tags.Table.Local_DI03A", 1)
|
||
GetData (byteB, "上料清洗", "PLC.Tags.Table.Local_DI03B", 1)
|
||
GetData (byteC, "上料清洗", "PLC.Tags.Table.Local_DI04A", 1)
|
||
GetData (byteD, "上料清洗", "PLC.Tags.Table.Local_DI04B", 1)
|
||
end if
|
||
if bTrigger==10 then // 上料 DI05-06 → 160
|
||
GetData (byteA, "上料清洗", "PLC.Tags.Table.Local_DI05A", 1)
|
||
GetData (byteB, "上料清洗", "PLC.Tags.Table.Local_DI05B", 1)
|
||
GetData (byteC, "上料清洗", "PLC.Tags.Table.Local_DI06A", 1)
|
||
GetData (byteD, "上料清洗", "PLC.Tags.Table.Local_DI06B", 1)
|
||
end if
|
||
if bTrigger==11 then // 上料 DI07 + Remote DI21 → 161
|
||
GetData (byteA, "上料清洗", "PLC.Tags.Table.Local_DI07A", 1)
|
||
GetData (byteB, "上料清洗", "PLC.Tags.Table.Local_DI07B", 1)
|
||
GetData (byteC, "上料清洗", "PLC.Tags.Table.Remote_DI21A", 1)
|
||
GetData (byteD, "上料清洗", "PLC.Tags.Table.Remote_DI21B", 1)
|
||
end if
|
||
if bTrigger==12 then // 上料 DO01-02 → 162
|
||
GetData (byteA, "上料清洗", "PLC.Tags.Table.Local_DO01A", 1)
|
||
GetData (byteB, "上料清洗", "PLC.Tags.Table.Local_DO01B", 1)
|
||
GetData (byteC, "上料清洗", "PLC.Tags.Table.Local_DO02A", 1)
|
||
GetData (byteD, "上料清洗", "PLC.Tags.Table.Local_DO02B", 1)
|
||
end if
|
||
if bTrigger==13 then // 上料 DO03-04 → 163
|
||
GetData (byteA, "上料清洗", "PLC.Tags.Table.Local_DO03A", 1)
|
||
GetData (byteB, "上料清洗", "PLC.Tags.Table.Local_DO03B", 1)
|
||
GetData (byteC, "上料清洗", "PLC.Tags.Table.Local_DO04A", 1)
|
||
GetData (byteD, "上料清洗", "PLC.Tags.Table.Local_DO04B", 1)
|
||
end if
|
||
if bTrigger==14 then // 上料 DO05-06 → 164
|
||
GetData (byteA, "上料清洗", "PLC.Tags.Table.Local_DO05A", 1)
|
||
GetData (byteB, "上料清洗", "PLC.Tags.Table.Local_DO05B", 1)
|
||
GetData (byteC, "上料清洗", "PLC.Tags.Table.Local_DO06A", 1)
|
||
GetData (byteD, "上料清洗", "PLC.Tags.Table.Local_DO06B", 1)
|
||
end if
|
||
if bTrigger==15 then // 清洗 DI11-12 → 166
|
||
GetData (byteA, "上料清洗", "PLC.Tags.Table.Local_DI11A", 1)
|
||
GetData (byteB, "上料清洗", "PLC.Tags.Table.Local_DI11B", 1)
|
||
GetData (byteC, "上料清洗", "PLC.Tags.Table.Local_DI12A", 1)
|
||
GetData (byteD, "上料清洗", "PLC.Tags.Table.Local_DI12B", 1)
|
||
end if
|
||
if bTrigger==16 then // 清洗 DI13-14 → 167
|
||
GetData (byteA, "上料清洗", "PLC.Tags.Table.Local_DI13A", 1)
|
||
GetData (byteB, "上料清洗", "PLC.Tags.Table.Local_DI13B", 1)
|
||
GetData (byteC, "上料清洗", "PLC.Tags.Table.Local_DI14A", 1)
|
||
GetData (byteD, "上料清洗", "PLC.Tags.Table.Local_DI14B", 1)
|
||
end if
|
||
if bTrigger==17 then // 清洗 DO11-12 → 168
|
||
GetData (byteA, "上料清洗", "PLC.Tags.Table.Local_DO11A", 1)
|
||
GetData (byteB, "上料清洗", "PLC.Tags.Table.Local_DO11B", 1)
|
||
GetData (byteC, "上料清洗", "PLC.Tags.Table.Local_DO12A", 1)
|
||
GetData (byteD, "上料清洗", "PLC.Tags.Table.Local_DO12B", 1)
|
||
end if
|
||
if bTrigger==18 then // 清洗 DO13-14 → 169
|
||
GetData (byteA, "上料清洗", "PLC.Tags.Table.Local_DO13A", 1)
|
||
GetData (byteB, "上料清洗", "PLC.Tags.Table.Local_DO13B", 1)
|
||
GetData (byteC, "上料清洗", "PLC.Tags.Table.Local_DO14A", 1)
|
||
GetData (byteD, "上料清洗", "PLC.Tags.Table.Local_DO14B", 1)
|
||
end if
|
||
if bTrigger==19 then // Remote DO21
|
||
GetData (byteA, "上料清洗", "PLC.Tags.Table.Remote_DO21A", 1)
|
||
GetData (byteB, "上料清洗", "PLC.Tags.Table.Remote_DO21B", 1)
|
||
end if
|
||
// 20~24 为制丸2 预留,现被注释掉
|
||
|
||
// ===== 调试监控输出:画面加 LW-310~313 数值元件查看 =====
|
||
SetData(byteA, "Local HMI", LW, 310, 1)
|
||
SetData(byteB, "Local HMI", LW, 311, 1)
|
||
SetData(byteC, "Local HMI", LW, 312, 1)
|
||
SetData(byteD, "Local HMI", LW, 313, 1)
|
||
end macro_command
|
||
```
|
||
|
||
> `bTrigger` 6、7 **缺号未用**;`20~24` 是「制丸2」的预留分支,已注释。
|
||
> 索引 ↔ 窗口对照:1~5 → 151~155;8~14 → 158~164;15~18 → 166~169;19 → Remote DO21。
|
||
### 6.2.1 补录时发现的问题
|
||
|
||
| # | 问题 | 影响 |
|
||
| --- | --- | --- |
|
||
| 1 | **`LW-300` 被两处占用**:`X1Y1` 文档里是「节点状态」首地址;现在 042/044/045 写它、050 读它 | 若 X1Y1 仍用 `LW-300~311`,节点状态会被 IO 索引覆盖 |
|
||
| 2 | `上料参数` 写 `LW-2 = 210`,而 210 是「清洗-点动」 | 点“上料参数”会跳到清洗点动页 |
|
||
| 3 | 047/049 的 float 拷贝长度与注释不符 | 显示可能只更新一半点位 |
|
||
| 4 | 048 周期 100 ms 写 8 个位 | 无谓负载,建议 1 s |
|
||
| 5 | 050 周期 100 ms 读 4×N 个符号 | IO 页不看时也在刷,建议改成按页面触发 |
|
||
| 6 | **`IO切换上料` 索引 9 却跳窗口 158**(158 是 DI1-2,索引 9 读 DI3-4) | 该页显示的是上一组 IO,值对不上标题 |
|
||
| 7 | **`IO切换清洗` 索引 15 却跳窗口 168**(15=DI11-12,168=DO11-12) | 同上,错 2 组 |
|
||
| 8 | `050` 末尾写 `LW-310~313` 调试值,与旧文档 X1Y1 的 `LW-300~311` 节点状态重叠 | `LW-300` 区已被 IO 占用,X1Y1 地址需重新确认 |
|
||
| 9 | `bTrigger` 6、7 缺号;20~24 是制丸2 预留(已注释) | 索引不连续,日后加页容易再次错位 |
|