文章目录

ST优先级处理:如何用 IF-ELSIF 链处理紧急停止与正常逻辑

发布于 2026-03-19 16:47:51 · 浏览 3 次 · 评论 0 条

在可编程逻辑控制器(PLC)的结构化文本(ST)编程中,紧急停止(E-Stop)必须拥有最高执行优先级,且该优先级不能依赖扫描周期顺序、代码位置或变量读写时序来保障。任何将急停逻辑“写在后面”或“放在子程序里”的做法,都可能导致一个扫描周期内的逻辑延迟,从而引发安全事故。IF-ELSIF 链是实现确定性优先级控制最直接、最透明、最易验证的语法结构——但前提是它被严格按优先级降序排列,且每个条件具备原子性、无副作用、无嵌套延迟


一、为什么 IF-ELSIF 是 ST 中处理优先级的黄金结构

ST 是 IEC 61131-3 标准定义的高级文本语言,其执行模型为逐行顺序扫描:从上到下、从左到右,每行语句在单个扫描周期内完成求值与赋值。这与梯形图(LD)的“并行隐式执行”或功能块图(FBD)的“信号流驱动”有本质区别。IF-ELSIF 链天然契合这一模型:

  • 显式优先级声明IF 条件最先被检查;仅当 IFFALSE 时,才检查第一个 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 厂商认证的安全输入滤波参数。
  • 所有安全相关变量名必须包含 EStopSafetySafe 等前缀/后缀,严禁使用 StopKillOff 等歧义词。

三、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;

核心要点解析:

  1. IF 分支无 ELSE 子句:每个 ELSIF 前置条件独立求值,bEStop_HardwiredTRUE 时,后续所有 ELSIFELSE 完全跳过,CPU 不消耗周期执行其中代码。
  2. 安全输出直驱Q_SafePower 等安全输出变量必须绑定至 PLC 的安全输出通道(如 Siemens F-DI/DO,Rockwell GuardLogix Safety I/O),不可用普通 Q 地址模拟。
  3. 状态降级机制:二级优先级中 T_SafeStopTimer.Q 触发时,主动将 bEStop_HardwiredTRUE,使系统立即转入一级处理流程,确保失效导向安全(Fail-Safe)。
  4. 三级优先级不复位轴:区别于急停,过程异常只需暂停,保留当前坐标系和工艺上下文,便于快速恢复。

四、必须规避的 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; 出现在多个分支中 增加维护复杂度,易漏改 统一在链外初始化,各分支仅做状态决策,不重复赋初值

五、调试与验证清单(上线前必做)

  1. 断点注入测试:在 IF bEStop_Hardwired THEN 行设置断点,强制 bEStop_Hardwired := TRUE,观察:

    • bMachineEnabled 是否立即变为 FALSE(下一个扫描周期)?
    • Q_SafePower 是否在同一扫描周期内变为 FALSE
    • 轴控指令 MC_Reset 是否被执行(查看轴状态寄存器)?
  2. 扫描周期压力测试:将主循环逻辑填充至 95% 扫描时间,再次触发急停,用 PLC 内置诊断工具确认:

    • 从输入端子电平变化到 Q_SafePower 下降,总延迟 ≤ 2×扫描周期(典型值 < 2 ms)。
  3. 安全回路完整性验证

    • 断开任一急停按钮接线 → bEStop_Hardwired 必须为 TRUE
    • 短接任一急停触点 → bEStop_Hardwired 必须为 FALSE
    • 拔掉安全输入模块 → PLC 进入安全停止状态(非程序崩溃)。
  4. 静态代码扫描

    • 使用 PLC 厂商工具(如 TIA Portal Safety Advanced Checker)验证:
      • bEStop_Hardwired 是否仅出现在 IF 条件左侧,且未被写入;
      • Q_SafePower 是否未在 ELSEELSIF 中被赋值;
      • 所有 MC_Reset 调用是否位于一级 IF 分支内。

六、进阶:多急停源的归一化处理(适用大型产线)

当设备含多个物理急停点(如操作台、维修门、上下料工位),需避免在 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 并确保它是整个链的起点时,你交付的不再是一段程序,而是一份可审计、可验证、可信赖的安全保障。

评论 (0)

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

扫一扫,手机查看

扫描上方二维码,在手机上查看本文