4. AOI功能块的逻辑主体编写
AOI 的定义参数和本地标签只是“外壳”,真正决定它行为的,是逻辑主体(Logic Body)。在 Studio 5000 Logix Designer 中,一个 AOI 的逻辑主体只能选择一种语言:梯形图(RLL)、功能块图(FBD)、结构化文本(ST),或顺序功能图(SFC)。语言一旦选定,AOI 内部就按该语言的执行语义运行,因此选型不是审美问题,而是与算法结构、可读性、可维护性直接相关。本节围绕“如何把核心算法写进逻辑主体”展开,重点讲三种语言的适用边界、条件分支与循环的实现方式,以及 AOI 内部特有的执行约束。
一、先判断算法形态,再选语言
选语言前先问三个问题:算法是位逻辑与联锁为主,还是连续量运算与信号流为主,还是带索引、数组、迭代为主?
- 梯形图:适合布尔联锁、启停保持、故障锁存、设备顺序动作。它的“能流”模型与电气图一致,现场排查直观。缺点是大量数学运算和数组遍历会变得臃肿。
- 功能块图:适合模拟量处理链,如滤波、标定、PID、限幅、报警阈值比较。信号从左到右流动,参数在块引脚上直接可见,调参方便。缺点是复杂条件分支表达不如 ST 紧凑。
- 结构化文本:适合带公式、查表、状态机、循环、数组处理的算法。表达力最强,但可读性依赖命名和注释,现场电工不一定能直接读。
一个实用原则:能用梯形图清楚表达的联锁,不要硬写成 ST;能用 ST 三行写完的数组遍历,不要硬拉成二十个梯级。如果算法内部既有联锁又有运算,可以在 AOI 内用所选语言统一实现,但要把“联锁段”和“运算段”在结构上分开,便于阅读。
二、条件分支:三种语言的写法差异
条件分支是逻辑主体的核心。以“根据模式选择输出”为例,假设 AOI 有输入 Mode(INT,0=手动、1=自动、2=维护)和 ManualCmd、AutoCmd,输出 CmdOut。
梯形图用并联分支和比较指令实现:先 EQU Mode 0 串 ManualCmd,再 EQU Mode 1 串 AutoCmd,两路并联后驱动 CmdOut。分支互斥靠模式值保证,若模式值可能越界,需补一路默认处理。
功能块图用 SEL 或 MUX 块:Mode 接选择端,ManualCmd 与 AutoCmd 接数据端,输出接 CmdOut。多路选择可用级联 SEL,或直接用 MUX 的多输入形式。FBD 的优势是分支关系一眼可见,不需要读梯级。
结构化文本用 CASE 最清晰:
CASE Mode OF
0: CmdOut := ManualCmd;
1: CmdOut := AutoCmd;
2: CmdOut := FALSE; // 维护模式禁止输出
ELSE
CmdOut := FALSE; // 越界保护
END_CASE;
注意 CASE 的 ELSE 分支不是可选项,而是安全兜底。AOI 被多处调用时,输入可能来自不同程序,越界值必须被显式处理,否则输出会保持上一次扫描值,形成隐蔽故障。
三、循环:AOI 内必须谨慎使用
AOI 的逻辑主体在每个扫描周期被调用一次,循环会直接增加该周期的执行时间。因此循环的使用要满足两个条件:迭代次数有明确上界,且单次迭代工作量小。
典型场景是数组遍历,例如对 8 个模拟量通道求最大值和平均值。ST 写法:
Sum := 0.0;
MaxVal := Ch[0];
FOR i := 0 TO 7 DO
Sum := Sum + Ch[i];
IF Ch[i] > MaxVal THEN
MaxVal := Ch[i];
END_IF;
END_FOR;
Avg := Sum / 8.0;
这里 i 必须是 AOI 本地标签中的 DINT,不能是全局标签,否则多个 AOI 实例会互相干扰。循环上界 8 是常量,扫描时间可预估。若通道数可变,应把上界做成输入参数并加限幅,例如 IF N > 32 THEN N := 32;,防止误设大值拖垮扫描。
梯形图实现循环较笨拙,通常用 FOR 指令或索引递增配合跳转,可读性差;FBD 更不适合循环。因此含循环的算法优先用 ST 写逻辑主体,这是语言选型的重要依据。
JMP/LBL 做跨段跳转,也不要写无界 WHILE。AOI 被调用在哪个任务、哪个周期,调用者不一定清楚,无界循环会导致任务看门狗超时,且故障现象与 AOI 本身难以关联。四、执行顺序与“先算后用”
逻辑主体内部按从上到下、从左到右执行。AOI 的输入参数在本次调用开始时已就绪,输出参数在本次调用结束时写回。因此同一次调用内,不要假设输出参数已被更新后再读回;需要中间结果时,用本地标签暂存,最后统一赋给输出。
下面这张图给出一个“模式选择 + 数组统计”AOI 的逻辑主体数据流:输入参数进入后,先做模式分支,再进入循环统计,中间结果存本地标签,最后写回输出参数。
五、一个可复用的逻辑主体骨架
把上面的要点整理成 ST 逻辑主体的骨架,可直接作为编写模板:
// 1) 输入合法性检查
IF N < 0 THEN N := 0; END_IF;
IF N > 32 THEN N := 32; END_IF;
// 2) 条件分支:模式选择
CASE Mode OF
0: CmdOut := ManualCmd;
1: CmdOut := AutoCmd;
2: CmdOut := FALSE;
ELSE
CmdOut := FALSE;
END_CASE;
// 3) 循环统计:有界迭代
Sum := 0.0;
MaxVal := Ch[0];
FOR i := 0 TO N-1 DO
Sum := Sum + Ch[i];
IF Ch[i] > MaxVal THEN MaxVal := Ch[i]; END_IF;
END_FOR;
// 4) 输出写回
IF N > 0 THEN Avg := Sum / INT_TO_REAL(N); ELSE Avg := 0.0; END_IF;
MaxOut := MaxVal;
这段骨架体现了三个工程习惯:先限幅再运算、分支必有兜底、除零前先判断。AOI 一旦被多处调用,任何未处理的边界值都会在某个调用点暴露,而排查时往往先怀疑调用方,浪费大量时间。
六、验证逻辑主体的最小方法
AOI 不能像普通程序那样单独下载运行,验证要靠调用它的测试程序。建议建一个专用测试例程,只调用该 AOI 一次,用强制表或测试标签给定输入,观察输出。重点验证四类用例:
- 正常分支:Mode=0/1/2 时 CmdOut 是否符合预期。
- 越界分支:Mode=5 时 CmdOut 是否为 FALSE,而不是保持旧值。
- 边界循环:N=0、N=1、N=32 时 Avg 与 MaxOut 是否正确,N=0 时是否避免除零。
- 扫描影响:把 N 临时设为 1000,观察任务扫描时间是否明显上升,确认限幅生效。
观察手段上,梯形图可直接看能流和标签值;FBD 可在线看各块引脚数值;ST 可在例程中把中间变量映射到测试标签,用趋势或监视表查看。判断依据不是“程序能下载”,而是每个分支和边界都有确定的、可解释的输出。