急停保护是工业安全的第一道防线,而中断程序是实现毫秒级响应的核心技术。 本文将完整拆解PLC中断程序的设计逻辑与落地方法,从原理到代码,从配置到调试,手把手教你搭建可靠的急停系统。
一、核心原理:为什么必须用中断
普通PLC程序采用循环扫描机制:读取输入 → 执行程序 → 刷新输出,周而复始。典型扫描周期为5~20毫秒,这意味着如果你的急停信号只接在普通输入点,最坏情况下要等一个完整扫描周期才能被响应。
中断的本质是硬件级抢答:当急停信号触发时,CPU立即暂停当前任务,跳转执行中断服务程序(ISR),处理完毕后再返回原任务。响应时间可压缩至微秒级,而非毫秒级。
| 对比项 | 普通程序扫描 | 中断程序 |
|---|---|---|
| 响应机制 | 被动等待本周期扫描 | 主动抢占CPU |
| 典型延迟 | 5~20 ms + 程序执行时间 | 几十微秒(硬件响应) |
| 优先级 | 无 | 可设置最高优先级 |
| 适用场景 | 普通逻辑控制 | 安全联锁、高速计数 |
二、硬件配置:急停信号的物理接入
1. 信号类型选择
优先使用常闭触点(NC)而非常开(NO)
常闭触点的安全优势在于:断线、脱落、失电都会自然触发停机,属于故障安全型设计。
| 故障场景 | 常闭触点(NC)结果 | 常开触点(NO)结果 |
|---|---|---|
| 线路断裂 | 回路断开 → 立即停机 | 回路仍断 → 无法检测,急停失效 |
| 端子松动 | 接触不良 → 回路断开 → 停机 | 可能虚接 → 信号抖动或丢失 |
| 24V电源丢失 | 输入点失电 → 视为触发 | 输入点失电 → 无法触发 |
2. 接线规范
以西门子S7-1200为例,急停按钮双触点接入:
- 第一组触点 →
I0.0(普通输入,用于状态指示) - 第二组触点 →
I0.1(硬件中断输入,触发急停程序)
关键动作:在设备属性中,勾选 I0.1 的"启用上升沿/下降沿中断"选项。
三、中断程序开发:以西门子TIA Portal为例
步骤1:创建硬件中断组织块(OB40)
// 在PLC项目树中:
// 双击"程序块" → 点击"添加新块" → 选择"组织块" → 类型选"硬件中断" → 编号自动分配为OB40+
命名建议:EmergencyStop_ISR(一目了然,维护时快速定位)
步骤2:关联触发事件
| 设置项 | 操作 |
|---|---|
| 事件名称 | I0.1 下降沿(对应常闭触点断开) |
| 触发条件 | 选择"下降沿"(常闭触点从通到断) |
| 优先级 | 设置为 26(S7-1200最高硬件中断优先级) |
关键动作:确认 急停按钮的物理触点类型与软件触发边沿匹配——常闭触点用下降沿,常开触点用上升沿。
步骤3:编写中断服务程序
// 组织块:EmergencyStop_ISR (OB40)
// 功能:急停触发后的安全处置
// 第1步:立即切断所有运动输出
"M_FastStop" := TRUE; // 置位快速停机标志
// 第2步:关闭主接触器(硬件互锁)
"Q_MainContactor" := FALSE; // 主电源接触器断开
// 第3步:触发伺服快速停止(如有)
"Q_Servo_QuickStop" := TRUE; // 伺服驱动器快速停止信号
// 第4步:记录事件时间戳
"DT_EstopTriggered" := DTL#(TOD); // 获取当前时间
// 第5步:设置安全状态机
"StateMachine_Safety".CurrentState := 0; // 强制进入安全态
关键原则:中断程序内禁止调用复杂功能块(如通信、PID运算),执行时间必须极短,避免丢失其他中断。
四、安全状态机设计:从急停到复位
急停不是简单断电,需要有序的安全状态流转。
State=1"] -- "急停触发" --> B["中断执行
切断输出"] B --> C["安全锁定
State=0"] C -- "故障清除
+ 手动复位" --> D["待机状态
State=2"] D -- "系统自检
通过" --> A C -- "故障未清除" --> C
状态定义与转换条件
| 状态值 | 含义 | 进入条件 | 离开条件 |
|---|---|---|---|
| 0 | 安全锁定 | 急停触发/安全门打开/光幕遮挡 | 人工确认+故障清除 |
| 1 | 正常运行 | 自检通过+启动命令 | 急停触发/任意安全信号 |
| 2 | 待机/复位等待 | 安全锁定中+急停按钮释放 | 复位按钮按下+自检通过 |
复位安全的关键设计
禁止自动复位:急停按钮释放后,设备绝不可自动重启。
// 主循环程序(OB1)中的复位检测
IF "StateMachine_Safety".CurrentState = 0 THEN
// 检测急停按钮已物理释放(常闭触点恢复)
IF "I_Estop_Physical" = TRUE THEN
"HMI_EstopReleased" := TRUE; // 提示操作员可复位
// 必须人工触发复位(如HMI按钮或物理复位键)
IF "I_ResetButton" = TRUE AND "HMI_SafetyConfirmed" = TRUE THEN
// 执行自检序列
"StateMachine_Safety".NextState := 2; // 进入待机
END_IF;
END_IF;
END_IF;
五、西门子S7-1500的高级中断功能
S7-1500系列支持时间中断与诊断中断,可构建多层保护。
快速响应比较
I0.1"] --> B["硬件中断
OB4x"] B -- "50us内" --> C["切断主回路"] A --> D["输入延时滤波
默认3ms"] D --> E["循环程序处理
OB1"] E -- "最坏20ms+" --> F["普通停机"] style B fill:#f96,stroke:#333 style C fill:#f96,stroke:#333
诊断中断应用:检测模块故障
// 诊断中断OB82:当IO模块故障时触发
// 例如:急停输入模块通信中断
IF "OB82_MDL_TYPE" = 16#54 THEN // 模块类型为输入模块
"Safety_Flag_ModuleFault" := TRUE;
"StateMachine_Safety".CurrentState := 0; // 强制安全态
// 记录故障模块槽位
"Diag_SlotNumber" := "OB82_MDL_ADDR";
END_IF;
六、三菱FX5U的编程差异
不同品牌PLC的中断机制略有差异,以下对比关键配置:
| 项目 | 西门子S7-1200/1500 | 三菱FX5U |
|---|---|---|
| 中断OB编号 | 自动分配(OB40起) | 固定:I0 ~ I15 |
| 触发方式 | 硬件配置绑定 | 程序中EI指令启用+IRET返回 |
| 输入点限制 | 仅支持特定高速输入点 | X0~X7可配置为中断 |
| 优先级设置 | 软件内1~26级 | 固定优先级(X0最高) |
FX5U中断程序示例
// 主程序中启用中断
EI; // 允许中断
// ... 正常程序 ...
// 中断程序(文件:I1,对应X1输入)
I1:
SET Y0; // 立即切断输出示例
SET M8000; // 急停标志
IRET; // 中断返回
关键动作:三菱PLC需用EI指令显式开启中断,否则即使硬件触发也不响应。
七、调试与验证:必须做的测试
测试清单
| 测试项 | 操作方法 | 预期结果 |
|---|---|---|
| 响应时间测量 | 示波器抓取输入→输出时间差 | < 1ms(硬件中断) |
| 断线模拟 | 拔掉急停输入端子 | 立即停机,HMI报"急停触发" |
| 触点粘连 | 短接急停触点模拟卡住 | 复位流程无法完成,保持锁定 |
| 电源丢失 | 关闭24V开关 | 等同于急停触发(NC触点) |
| 多重中断 | 同时触发急停+安全门 | 均响应,状态机正确跳转 |
响应时间计算公式
若需量化评估,中断总延迟为:
$$T_{total} = T_{hardware} + T_{input\_filter} + T_{ISR\_execution} + T_{output}$$
典型值:
- $T_{hardware}$(硬件响应):约 10 μs
- $T_{input\_filter}$(输入滤波):可设为 0 μs(高速输入)
- $T_{ISR\_execution}$(程序执行):< 100 μs(需实际测量)
- $T_{output}$(输出刷新):约 10 μs
合计通常 < 200 μs,比循环扫描快两个数量级。
八、常见错误与规避
| 错误现象 | 根本原因 | 修正方法 |
|---|---|---|
| 急停偶尔"漏响应" | 输入滤波时间过长 | 设置 滤波时间为0或最小值 |
| 复位后设备乱跳 | 中断程序修改了全局状态 | ISR内仅操作安全专用变量 |
| 急停后伺服未停 | 未使用伺服快速停止功能 | 连接 伺服硬接线急停端子 |
| 无法进入复位流程 | 急停触点粘连未释放 | 增加触点状态诊断,HMI可视化 |
| 中断程序执行过长 | ISR内包含复杂运算 | 迁移 到主循环,ISR仅置位标志 |
九、完整代码框架(西门子风格)
// ========== 变量定义 ==========
// 安全状态机
TYPE "UDT_SafetyState"
STRUCT
CurrentState : Int; // 0=锁定, 1=运行, 2=待机
NextState : Int;
EstopActive : Bool; // 急停触发标志
ResetRequest : Bool; // 复位请求
END_STRUCT;
// ========== 硬件中断 OB40 ==========
"EmergencyStop_ISR":
// 原子操作:立即切断
"SafetyState".EstopActive := TRUE;
"Q_All_Motor_Contactors" := FALSE;
"Q_Servo_Enable" := FALSE;
"SafetyState".CurrentState := 0;
// ========== 主循环 OB1 ==========
// 状态机处理
CASE "SafetyState".CurrentState OF
0: // 安全锁定
IF "SafetyState".ResetRequest AND NOT "I_Estop_Physical" THEN
// 故障仍存在,禁止复位
"HMI_Warning" := "故障未清除";
ELSIF "SafetyState".ResetRequest AND "I_Estop_Physical" THEN
"SafetyState".NextState := 2;
END_IF;
2: // 待机,执行自检
IF "SelfTest_Passed" THEN
"SafetyState".NextState := 1;
END_IF;
1: // 正常运行
// 主控制逻辑...
;
END_CASE;
// 状态切换
"SafetyState".CurrentState := "SafetyState".NextState;
最终检查点:
- 急停输入是否为常闭触点?
- 中断优先级是否设为最高?
- 复位流程是否强制人工确认?
- 是否在所有安全设备上实测响应时间?

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