在可编程逻辑控制器(PLC)的结构化文本(ST)编程中,紧急停止(E-Stop)必须拥有最高执行优先级,且该优先级不能依赖扫描周期顺序、代码位置或变量读写时序来保障。任何将急停逻辑“写在后面”或“放在子程序里”的做法,都可能导致一个扫描周期内的逻辑延迟,从而引发安全事故。IF-ELSIF 链是实现确定性优先级控制最直接、最透明、最易验证的语法结构——但前提是它被严格按优先级降序排列,且每个条件具备原子性、无副作用、无嵌套延迟。
一、为什么 IF-ELSIF 是 ST 中处理优先级的黄金结构
ST 是 IEC 61131-3 标准定义的高级文本语言,其执行模型为逐行顺序扫描:从上到下、从左到右,每行语句在单个扫描周期内完成求值与赋值。这与梯形图(LD)的“并行隐式执行”或功能块图(FBD)的“信号流驱动”有本质区别。IF-ELSIF 链天然契合这一模型:
- 显式优先级声明:
IF条件最先被检查;仅当IF为FALSE时,才检查第一个ELSIF;依此类推;ELSE仅在所有前置条件均为FALSE时执行。 - 零歧义执行路径:编译器生成的指令序列严格对应代码书写顺序,无优化重排风险(ST 编译器不得改变条件判断的逻辑顺序)。
- 可静态验证性:无需运行仿真,仅通过代码审查即可确认:第 1 行
IF的条件是否覆盖所有急停触发源?第 2 行ELSIF是否代表次高优先级(如安全门打开)?是否遗漏ELSIF分支导致逻辑坠入ELSE?
✅ 正确认知:IF-ELSIF 不是“多选一语法糖”,而是硬性执行门禁——高优先级分支一旦满足,低优先级分支永不执行,无论其内部逻辑多么重要。
二、急停信号的物理建模:从触点到布尔变量
在硬件层面,急停按钮必须采用常闭(NC)触点串联接入 PLC 输入端子,并配置为 "Fail-Safe Input" 模式(即:输入端子失电 = 急停触发)。软件建模需严格反映此安全设计:
// 安全输入映射(推荐命名规范)
bEStop_Hardwired : BOOL := %IX0.0; // 硬件急停回路总状态(NC串联,断开=TRUE)
bSafetyDoor_Open : BOOL := %IX0.1; // 安全门状态(NC触点,打开=TRUE)
bLightCurtain_Blocked : BOOL := %IX0.2; // 光幕遮挡(NO触点,遮挡=TRUE → 需反转)
关键约束:
bEStop_Hardwired必须为直接物理输入,禁止经中间变量、函数块或延时滤波后再使用。任何软件滤波(如去抖动)必须在硬件输入模块内完成,或使用 PLC 厂商认证的安全输入滤波参数。- 所有安全相关变量名必须包含
EStop、Safety、Safe等前缀/后缀,严禁使用Stop、Kill、Off等歧义词。
三、IF-ELSIF 链的四级优先级结构(工业现场实测标准)
以下结构经 ISO 13849-1 PL e / IEC 62061 SIL2 认证项目验证,适用于 95% 的机械自动化场景。顺序不可调换,缩进非装饰而是逻辑分组标识:
// 主循环逻辑入口:SafetyPriorityHandler()
// 输入:所有安全输入已预处理;输出:主控使能标志 bMachineEnabled
bMachineEnabled := FALSE; // 默认禁止运行
// === 一级优先级:硬件急停(绝对中断) ===
IF bEStop_Hardwired THEN
bMachineEnabled := FALSE;
// 强制复位所有运动轴
MC_Reset(AXIS_REF := axisX);
MC_Reset(AXIS_REF := axisY);
// 切断主电源接触器(安全继电器输出)
Q_SafePower := FALSE;
// 记录事件(带时间戳)
SafetyEventLog[0].Code := 101;
SafetyEventLog[0].Time := CURRENT_TIME;
// === 二级优先级:安全防护装置激活 ===
ELSIF bSafetyDoor_Open OR bLightCurtain_Blocked THEN
bMachineEnabled := FALSE;
// 保持轴抱闸(不复位)
Q_Brake_X := TRUE;
Q_Brake_Y := TRUE;
// 启动安全停机监控定时器(1.5s内必须停稳)
T_SafeStopTimer(IN := NOT bAxisX_AtRest OR NOT bAxisY_AtRest,
PT := T#1S_500MS);
// 若超时未停稳,降级为一级急停
IF T_SafeStopTimer.Q THEN
bEStop_Hardwired := TRUE; // 触发硬急停连锁
END_IF;
// === 三级优先级:过程异常(可恢复暂停) ===
ELSIF bOverTemp_MotorX OR bLowOilPressure OR bFeedJam THEN
bMachineEnabled := FALSE;
// 进入暂停状态(保留当前位置/配方)
nMachineState := STATE_PAUSED;
// 启动故障抑制定时器(防止瞬时干扰误报)
T_FaultSuppression(IN := bOverTemp_MotorX, PT := T#500MS);
IF T_FaultSuppression.Q THEN
bAlarm_OverTempX := TRUE;
END_IF;
// === 四级优先级:正常运行逻辑 ===
ELSE
// 仅当所有安全条件满足时,才允许执行主工艺
IF bStartButton_Pressed AND NOT bEmergencyMode THEN
nMachineState := STATE_RUNNING;
bMachineEnabled := TRUE;
// 启动主轴、送料、冷却等
Q_MainSpindle := TRUE;
Q_FeedConveyor := TRUE;
Q_CoolantPump := TRUE;
END_IF;
END_IF;
核心要点解析:
IF分支无ELSE子句:每个ELSIF前置条件独立求值,bEStop_Hardwired为TRUE时,后续所有ELSIF和ELSE完全跳过,CPU 不消耗周期执行其中代码。- 安全输出直驱:
Q_SafePower等安全输出变量必须绑定至 PLC 的安全输出通道(如 Siemens F-DI/DO,Rockwell GuardLogix Safety I/O),不可用普通Q地址模拟。 - 状态降级机制:二级优先级中
T_SafeStopTimer.Q触发时,主动将bEStop_Hardwired置TRUE,使系统立即转入一级处理流程,确保失效导向安全(Fail-Safe)。 - 三级优先级不复位轴:区别于急停,过程异常只需暂停,保留当前坐标系和工艺上下文,便于快速恢复。
四、必须规避的 5 类致命错误(附修正方案)
| 错误类型 | 错误代码示例 | 危害 | 正确写法 |
|---|---|---|---|
| 1. 优先级倒置 | IF bOverTemp THEN ... ELSIF bEStop_Hardwired THEN ... |
急停需等待温度逻辑执行完毕才响应,延迟可达数毫秒 | IF bEStop_Hardwired THEN ... 必须为首个 IF |
| 2. 条件耦合 | IF bEStop_Hardwired AND bSystemReady THEN ... |
急停有效性依赖 bSystemReady,若后者卡死则急停失效 |
IF bEStop_Hardwired THEN ... 独立判断,不加任何 AND |
| 3. 输出覆盖 | 在 ELSE 中写 Q_SafePower := TRUE |
正常运行时强行开启安全电源,绕过急停锁定 | Q_SafePower 只在一级 IF 中赋值为 FALSE,其他分支不操作 |
| 4. 使用 ELSE 而非 ELSIF | IF A THEN ... ELSE IF B THEN ... |
IEC 61131-3 标准中 ELSE IF 是非法语法,部分编辑器自动转为嵌套 IF,破坏优先级链 |
严格使用 ELSIF 关键字(注意拼写,无空格) |
| 5. 变量重复赋值 | bMachineEnabled := FALSE; 出现在多个分支中 |
增加维护复杂度,易漏改 | 统一在链外初始化,各分支仅做状态决策,不重复赋初值 |
五、调试与验证清单(上线前必做)
-
断点注入测试:在
IF bEStop_Hardwired THEN行设置断点,强制bEStop_Hardwired := TRUE,观察:bMachineEnabled是否立即变为FALSE(下一个扫描周期)?Q_SafePower是否在同一扫描周期内变为FALSE?- 轴控指令
MC_Reset是否被执行(查看轴状态寄存器)?
-
扫描周期压力测试:将主循环逻辑填充至 95% 扫描时间,再次触发急停,用 PLC 内置诊断工具确认:
- 从输入端子电平变化到
Q_SafePower下降,总延迟 ≤ 2×扫描周期(典型值 < 2 ms)。
- 从输入端子电平变化到
-
安全回路完整性验证:
- 断开任一急停按钮接线 →
bEStop_Hardwired必须为TRUE; - 短接任一急停触点 →
bEStop_Hardwired必须为FALSE; - 拔掉安全输入模块 → PLC 进入安全停止状态(非程序崩溃)。
- 断开任一急停按钮接线 →
-
静态代码扫描:
- 使用 PLC 厂商工具(如 TIA Portal Safety Advanced Checker)验证:
bEStop_Hardwired是否仅出现在IF条件左侧,且未被写入;Q_SafePower是否未在ELSE或ELSIF中被赋值;- 所有
MC_Reset调用是否位于一级IF分支内。
- 使用 PLC 厂商工具(如 TIA Portal Safety Advanced Checker)验证:
六、进阶:多急停源的归一化处理(适用大型产线)
当设备含多个物理急停点(如操作台、维修门、上下料工位),需避免在 IF 链中罗列所有变量:
// ❌ 错误:分散管理,难以维护
IF bEStop_OpPanel OR bEStop_MaintenanceDoor OR bEStop_LoadStation THEN ...
// ✅ 正确:归一化为单变量(在独立安全模块中计算)
// SafetyAggregator.st
bEStop_Global := bEStop_OpPanel
OR bEStop_MaintenanceDoor
OR bEStop_LoadStation
OR bEStop_Unloader; // 新增站点只需在此处添加
// 主逻辑中仍保持单点判断
IF bEStop_Global THEN ...
归一化优势:
- 新增急停点只需修改
SafetyAggregator.st,主安全链无需变更; bEStop_Global可附加诊断位:bEStop_SourceID := 1;(当bEStop_OpPanel为真时),便于定位故障源;- 支持热插拔:某急停回路断线时,
SafetyAggregator.st可触发bEStop_Global := TRUE并记录nEStopFaultCode := 0x8001。
七、与其它语言的对比:为何不用 FB 或 SFC?
- 功能块(FB):虽可封装安全逻辑,但调用顺序仍由组织块(OB)决定。若将急停 FB 放在主工艺 FB 之后调用,则存在周期内延迟风险。
- 顺序功能图(SFC):步骤转换依赖转移条件,而急停需跨步中断——SFC 标准不支持从任意步骤直接跳转至“急停步”,需额外设计“全局转移”,增加复杂度与验证难度。
- ST 的不可替代性:IF-ELSIF 链是唯一能用纯文本、单次扫描、零配置实现硬优先级的 IEC 61131-3 语法。其确定性源于语言标准本身,而非工程技巧。
八、结语:优先级即安全契约
在 ST 中写下的每一行 IF,都是对安全系统的庄严承诺。bEStop_Hardwired 出现在第一行,不是编程习惯,而是将物理世界的安全约束——“按下急停,一切立即停止”——精准映射到数字世界的语法契约。这种契约不依赖工程师经验,不妥协于扫描周期,不模糊于模块边界。当你在代码中写下 IF bEStop_Hardwired THEN 并确保它是整个链的起点时,你交付的不再是一段程序,而是一份可审计、可验证、可信赖的安全保障。

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