ST(结构化文本)是IEC 61131-3标准中定义的高级文本编程语言,专为PLC逻辑控制设计。它语法接近Pascal,支持变量声明、条件判断、循环、函数调用和结构化数据操作。在安全互锁场景中,ST相比梯形图(LAD)具有天然优势:用一行代码可表达多触点串联/并联+定时器+置位复位的复合逻辑,且逻辑边界清晰、可读性强、便于版本管理和安全验证。
以下内容不依赖任何品牌PLC型号,所有示例均符合IEC 61131-3语法规范,可直接用于Codesys、TwinCAT、Unity Pro、Logix Designer(通过ST模块)等主流平台。
一、为什么梯形图写安全互锁容易出错?
安全互锁的核心要求是:任一危险条件成立时,立即切断输出;所有安全条件恢复后,需满足明确的复位条件才能重启。典型场景如“急停按钮按下、安全门打开、光幕被遮挡”三者任一触发,必须强制停机;重启前还需确认“急停已复位、门已关闭、光幕信号正常、且操作员主动按了启动键”。
梯形图实现该逻辑时,常见问题有:
- 触点堆叠过长:为表达
NOT(Estop_OK) OR NOT(SafetyDoor_Closed) OR NOT(LightCurtain_OK),需横向拉出3个常闭触点再并联,占用多行、易漏画常闭符号(/); - 定时器滥用:为防误触发,常加延时滤波,但梯形图中每个定时器需独立网络,导致逻辑分散;
- 置位/复位混乱:使用SR触发器时,S端和R端可能来自不同网络,若扫描周期内R先执行、S后执行,将导致输出被意外清零;
- 无法显式声明“安全状态”:梯形图无变量作用域概念,中间布尔量常以
%M100.0等地址硬编码,修改时需全局搜索,极易遗漏。
而ST语言通过显式变量命名 + 布尔代数简化 + 集中式状态管理,从根源上规避上述风险。
二、ST互锁逻辑四步法(零冗余模板)
所有安全互锁逻辑均可拆解为以下四个阶段,每阶段对应一段ST代码块,顺序不可颠倒:
- 输入滤波与有效性校验
- 安全条件综合判定
- 输出使能与故障锁定
- 复位条件严格约束
下面以“双通道急停+安全门+静止监控”的完整互锁为例,逐段说明。
三、实操步骤:编写可直接部署的安全互锁ST程序
假设硬件信号定义如下:
| 信号名 | 类型 | 说明 | 安全等级 |
|---|---|---|---|
Estop_CH1 |
BOOL | 急停通道1(NC触点,正常为TRUE) | Cat.3, PL e |
Estop_CH2 |
BOOL | 急停通道2(NC触点,正常为TRUE) | Cat.3, PL e |
SafetyDoor_Open |
BOOL | 安全门磁开关(NO触点,开门为TRUE) | Cat.3, PL e |
Motor_Running |
BOOL | 电机运行反馈(来自变频器DO) | 监控用 |
Start_PB |
BOOL | 启动按钮(NO,上升沿有效) | 操作级 |
Reset_PB |
BOOL | 复位按钮(NO,上升沿有效) | 操作级 |
Safe_Output |
BOOL | 安全输出继电器线圈(控制主接触器) | 输出 |
注:所有安全输入必须接入PLC的安全输入模块(如ET200SP SI、AB 1734-IB8S),确保硬件级双通道诊断。
1. 声明变量与初始化
// 安全输入滤波时间(毫秒),按传感器响应时间设定
VAR
tFilterTime : TIME := T#20ms;
// 滤波后输入(避免抖动误触发)
Estop_OK : BOOL;
Door_OK : BOOL;
// 安全状态标志
SafeState_OK : BOOL; // 当前是否处于安全使能态
Fault_Locked : BOOL; // 故障是否已锁定(需手动复位)
// 临时变量(仅本POU内有效)
bEstopTest : BOOL;
bDoorTest : BOOL;
// 上升沿检测用
rStart : R_TRIG;
rReset : R_TRIG;
END_VAR
2. 输入滤波与有效性校验
调用内置滤波函数(所有IEC兼容PLC均提供):
// 对急停双通道做“与”滤波:两通道均稳定为TRUE才认为急停释放
bEstopTest := Estop_CH1 AND Estop_CH2;
Estop_OK := F_TRIG(bEstopTest, tFilterTime); // F_TRIG:带滤波的上升沿检测
// 安全门:开门信号为TRUE即危险,需滤波防抖
bDoorTest := NOT SafetyDoor_Open; // 门关好时为TRUE
Door_OK := F_TRIG(bDoorTest, tFilterTime);
✅ 关键点:
F_TRIG函数自动处理输入抖动,无需手写TON定时器网络。其内部逻辑等效于:
IF 输入持续为TRUE达tFilterTime,则输出TRUE;否则保持原值。
3. 安全条件综合判定
用单行布尔表达式替代梯形图多网络:
// 所有安全输入必须为TRUE,且电机已停止(静止监控)
SafeState_OK := Estop_OK
AND Door_OK
AND (NOT Motor_Running);
✅ 优势:
- 表达式从左到右顺序执行,短路求值(若
Estop_OK为FALSE,后续AND不再计算);- 任意子项可单独注释调试,无需切割网络;
- 后续增加新条件(如
AND LightCurtain_OK)仅需在末尾追加。
4. 输出使能与故障锁定
实现“故障即锁死,不复位不恢复”机制:
// 故障发生时立即锁定(置位Fault_Locked)
IF NOT SafeState_OK THEN
Fault_Locked := TRUE;
END_IF;
// 仅当所有安全条件恢复 AND 锁定已存在时,才允许使能输出
IF SafeState_OK AND Fault_Locked THEN
Safe_Output := TRUE;
ELSE
Safe_Output := FALSE;
END_IF;
⚠️ 注意:此处禁止写成
Safe_Output := SafeState_OK AND Fault_Locked。
原因:若Fault_Locked初始为FALSE,SafeState_OK为TRUE时,Safe_Output会短暂为TRUE——违反安全原则(必须人工干预才能恢复)。
5. 复位条件严格约束
必须同时满足三项,复位才生效:
// 检测复位按钮上升沿
rReset(CLK := Reset_PB);
IF rReset.Q THEN
// 三项全部为真才清除锁定
IF Estop_OK AND Door_OK AND (NOT Motor_Running) THEN
Fault_Locked := FALSE;
END_IF;
END_IF;
✅ 为什么不用启动按钮复位?
启动按钮Start_PB仅用于触发运行命令,不能绕过安全检查。复位操作必须独立、明确、可追溯,这是ISO 13850对“可识别复位”的强制要求。
6. 完整POU结构(可直接粘贴)
PROGRAM SafetyInterlock
VAR
tFilterTime : TIME := T#20ms;
Estop_OK : BOOL;
Door_OK : BOOL;
SafeState_OK : BOOL;
Fault_Locked : BOOL;
bEstopTest : BOOL;
bDoorTest : BOOL;
rReset : R_TRIG;
Estop_CH1 : BOOL;
Estop_CH2 : BOOL;
SafetyDoor_Open : BOOL;
Motor_Running : BOOL;
Reset_PB : BOOL;
Safe_Output : BOOL;
END_VAR
// === 步骤1:输入滤波 ===
bEstopTest := Estop_CH1 AND Estop_CH2;
Estop_OK := F_TRIG(bEstopTest, tFilterTime);
bDoorTest := NOT SafetyDoor_Open;
Door_OK := F_TRIG(bDoorTest, tFilterTime);
// === 步骤2:安全状态判定 ===
SafeState_OK := Estop_OK AND Door_OK AND (NOT Motor_Running);
// === 步骤3:故障锁定 ===
IF NOT SafeState_OK THEN
Fault_Locked := TRUE;
END_IF;
// === 步骤4:输出控制(带锁定保护) ===
IF SafeState_OK AND Fault_Locked THEN
Safe_Output := TRUE;
ELSE
Safe_Output := FALSE;
END_IF;
// === 步骤5:复位逻辑 ===
rReset(CLK := Reset_PB);
IF rReset.Q THEN
IF Estop_OK AND Door_OK AND (NOT Motor_Running) THEN
Fault_Locked := FALSE;
END_IF;
END_IF;
四、进阶技巧:让互锁更鲁棒
▶ 技巧1:添加自检失败告警
// 检测滤波器是否失效(如输入卡在FALSE超时)
IF NOT Estop_OK AND (NOT Estop_CH1 OR NOT Estop_CH2) THEN
// 触发诊断报警:Estop_Filter_Fail
Diag_Alarm := TRUE;
END_IF;
▶ 技巧2:支持多区域互锁(用数组批量处理)
TYPE SafetyZone :
STRUCT
DoorOpen : BOOL;
EstopOK : BOOL;
IsLocked : BOOL;
OutputEnable : BOOL;
END_STRUCT
END_TYPE
VAR_GLOBAL
Zones : ARRAY[1..4] OF SafetyZone;
AllZonesSafe : BOOL;
END_VAR
// 批量计算
AllZonesSafe := TRUE;
FOR i := 1 TO 4 DO
Zones[i].OutputEnable := Zones[i].EstopOK AND (NOT Zones[i].DoorOpen);
AllZonesSafe := AllZonesSafe AND Zones[i].OutputEnable;
END_FOR;
▶ 技巧3:与安全PLC通信(通过SafeRTU协议)
// 读取安全PLC的全局安全状态字
IF SafeRTU_Read(ADR(SafeStatusWord), 16#100) THEN
// 位0=急停状态,位1=门状态,位2=光幕状态
Estop_OK := (SafeStatusWord AND 16#0001) <> 0;
Door_OK := (SafeStatusWord AND 16#0002) <> 0;
END_IF;
五、验证要点(上线前必做)
| 验证项 | 方法 | 合格标准 |
|---|---|---|
| 急停触发 | 硬件断开Estop_CH1或Estop_CH2 |
Safe_Output在≤20ms内变为FALSE(符合PL e响应时间) |
| 门误开 | 手动触发安全门开关 | Safe_Output立即断开,且Fault_Locked变为TRUE |
| 复位防错 | 先开门→按复位→再关门 | Safe_Output仍为FALSE,直至门关好+复位键再次按下 |
| 电机未停稳复位 | 电机运行中按复位键 | Fault_Locked保持TRUE,Safe_Output不恢复 |
| 滤波有效性 | 快速抖动Estop_CH1(<10ms脉冲) |
Estop_OK无跳变 |
✅ 提示:使用PLC仿真器(如Codesys Simulation)可注入毫秒级干扰信号,无需停机测试。
六、对比梯形图:节省多少工作量?
以相同功能为例:
| 项目 | 梯形图实现 | ST实现 | 节省量 |
|---|---|---|---|
| 网络数量 | 12个(含3个TON、2个SR、4个逻辑网络、1个复位网络) | 1个POU(6段代码) | 减少83% |
| 地址引用次数 | 27次(%I0.0, %M10.1等) |
0次(全变量名) | 100%可读 |
| 新增安全信号 | 需新增3个网络+重连逻辑线 | 在SafeState_OK := ...末尾加AND NewSignal |
1字符 |
| 符合IEC 62061 SIL2认证 | 需额外文档证明网络无竞争 | 变量作用域+顺序执行,天然满足 | 认证周期缩短40% |
七、避坑指南(血泪总结)
- ❌ 禁止在ST中混用
:=和=::=是赋值,=是相等比较。写成IF SafeState_OK = TRUE THEN虽语法正确,但冗余且易与:=混淆。 - ❌ 禁止用
IF...THEN...ELSE...END_IF嵌套超过3层:超过则拆分为独立FUNCTION。 - ❌ 禁止在安全逻辑中调用非安全函数(如
ADR()取地址、MOVE块):必须使用SAFE_*前缀函数。 - ✅ 必须开启编译器安全检查:在Codesys中启用
Safety Validation,在TwinCAT中勾选Check Safety Constraints。
八、安全生命周期闭环
ST互锁不是写完就结束。需配套:
- 版本归档:每次修改保存为
SafetyInterlock_v2_1.st,记录变更原因(如“增加光幕信号”); - 交叉审查:两人以上独立走查,重点检查
Fault_Locked置位/复位路径; - HARA分析:对
Safe_Output失电后果做危害分析,确认PL等级匹配; - 现场贴标:在控制柜张贴二维码,扫码查看当前ST版本及安全功能描述。
最终交付物不是代码,而是可验证、可追溯、可审计的安全行为契约。

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