需要编写 PLC 程序,实现设备断电后再次上电时恢复断电前的运行状态、关键数据(如定位位置、生产工序、计数数值等),而非从头执行,这是工业自动化设备的核心容错需求。
结合你之前做的三轴机、变频器控制、脉冲定位场景,我以西门子 S7-1200/1500(TIA Portal)为例,给出现场直接能用的完整程序逻辑,其他品牌 PLC(三菱、台达)逻辑完全通用,仅指令名称不同。
核心思路(先记)
断电重启程序的核心是:
断电前:实时把关键数据保存到 PLC 的「掉电保持区」(普通变量断电会丢失);
上电后:在 PLC 启动组织块(OB100)中读取保存的数据,恢复设备状态;
运行中:区分「首次上电」和「断电重启」,避免重复初始化。
一、第一步:配置 PLC 掉电保持(基础,必须做)
西门子 S7-1200/1500 默认有部分掉电保持区,但需确认 / 扩展:
打开 TIA Portal → 选中 PLC → 「属性」→ 「常规」→ 「存储区」;
找到「掉电保持」:
位存储器(M 区):设置需保持的字节数(如 100 字节);
数据块(DB 块):新建 DB 块时,勾选「优化的块访问」→ 「保持」(整 DB 块掉电保持);
确认后下载到 PLC,这些区域的数据断电后不会丢失。
二、第二步:定义需保存的关键变量(以三轴机为例)
新建保持型 DB 块(DB1),存储断电前的核心数据:
plaintext
DATA_BLOCK DB1 // 掉电保持DB块,勾选「保持」 VAR_GLOBAL // 1. 运行状态 Run_Status: BOOL; // 断电前是否在运行(TRUE=运行,FALSE=停止) Current_Step: INT; // 断电前执行到第几步(如阵列第23个点) // 2. 轴位置数据 X_Pos: REAL; // X轴断电前位置(mm) Y_Pos: REAL; // Y轴断电前位置(mm) Z_Pos: REAL; // Z轴断电前位置(mm) // 3. 计数/产量数据 Total_Count: INT; // 累计产量 Current_Count: INT; // 当前批次计数 // 4. 变频器参数 VFD_Freq: REAL; // 断电前变频器频率(Hz) VFD_Run: BOOL; // 断电前变频器是否运行 END_VAR
三、第三步:核心程序编写(分 3 个组织块)
PLC 的启动逻辑靠「组织块」实现,核心是OB100(上电启动块) + OB1(主循环) + OB82/OB122(故障块,可选)。
1. OB100(上电启动组织块):恢复断电前状态
OB100 只在 PLC 上电 / 重启时执行一次,用于初始化 + 恢复状态:
plaintext
// OB100 上电启动程序 VAR First_PowerOn: BOOL; // 首次上电标记(M0.0,掉电保持) END_VAR // 第一步:判断是「首次上电」还是「断电重启」 IF First_PowerOn = FALSE THEN // 首次上电:初始化所有参数(避免乱码) DB1.Run_Status := FALSE; DB1.Current_Step := 1; DB1.X_Pos := 0.0; DB1.Y_Pos := 0.0; DB1.Z_Pos := 0.0; DB1.Total_Count := 0; DB1.Current_Count := 0; DB1.VFD_Freq := 0.0; DB1.VFD_Run := FALSE; First_PowerOn := TRUE; // 标记为已首次上电 ELSE // 断电重启:恢复断电前状态 // ① 恢复轴位置(三轴机回断电前位置) "MC_MoveAbsolute_X".Position := DB1.X_Pos; // X轴绝对定位指令 "MC_MoveAbsolute_Y".Position := DB1.Y_Pos; "MC_MoveAbsolute_Z".Position := DB1.Z_Pos; "MC_MoveAbsolute_X".Execute := TRUE; // 执行定位(回断电前位置) "MC_MoveAbsolute_Y".Execute := TRUE; "MC_MoveAbsolute_Z".Execute := TRUE; // ② 恢复变频器状态 "VFD_Write_Freq".Value := DB1.VFD_Freq; // 写入断电前频率 IF DB1.VFD_Run = TRUE THEN "VFD_Run".Q := TRUE; // 重启变频器 END_IF; // ③ 恢复运行状态和工序 "Run_Flag".Q := DB1.Run_Status; // 恢复运行/停止状态 "Current_Step".MW := DB1.Current_Step; // 恢复当前工序/阵列点 END_IF;
2. OB1(主循环组织块):实时保存关键数据
运行中持续更新DB1 的保持变量,确保断电前最后状态被保存:
plaintext
// OB1 主循环程序 VAR Save_Trigger: BOOL; // 保存触发(每秒1次,避免频繁写) END_VAR // 每秒触发一次保存(用定时器,如T0,1s脉冲) TON_1s(IN:=TRUE, PT:=T#1S, Q=>Save_Trigger); IF Save_Trigger = TRUE THEN // 1. 保存运行状态 DB1.Run_Status := "Run_Flag".I; // 实时保存当前运行状态 DB1.Current_Step := "Current_Step".MW; // 保存当前工序/阵列点 // 2. 保存轴实时位置(读取伺服反馈) DB1.X_Pos := "MC_ReadActualPosition_X".ActualPosition; DB1.Y_Pos := "MC_ReadActualPosition_Y".ActualPosition; DB1.Z_Pos := "MC_ReadActualPosition_Z".ActualPosition; // 3. 保存计数数据 DB1.Total_Count := "Total_Count".MW; DB1.Current_Count := "Current_Count".MW; // 4. 保存变频器参数 DB1.VFD_Freq := "VFD_Read_Freq".MW; // 读取当前频率 DB1.VFD_Run := "VFD_Run".I; // 保存变频器运行状态 END_IF;
3. 可选:OB82(故障组织块):异常断电保护
若 PLC 因故障(如欠压、过载)断电,提前保存关键数据:
plaintext
// OB82 故障处理程序 // 故障发生时,强制保存最后状态 DB1.Run_Status := "Run_Flag".I; DB1.X_Pos := "MC_ReadActualPosition_X".ActualPosition; DB1.Y_Pos := "MC_ReadActualPosition_Y".ActualPosition; DB1.Z_Pos := "MC_ReadActualPosition_Z".ActualPosition; DB1.Total_Count := "Total_Count".MW;
四、关键控制逻辑(避免重启后出错)
轴回位优先:上电后先让三轴回断电前位置,再继续运行,避免撞机;
手动复位选项:增加「重启复位按钮」,可手动清除保存的状态,从头执行;
数据校验:上电后检查保存的位置 / 步数是否合法(如≤100 个阵列点),非法则初始化;
plaintext
// 数据校验示例(OB100中) IF DB1.Current_Step > 100 OR DB1.Current_Step < 1 THEN DB1.Current_Step := 1; // 非法步数,重置为第一步 END_IF;
五、其他品牌 PLC 适配(核心逻辑不变)
表格
| PLC 品牌 | 掉电保持设置 | 上电启动块 | 核心差异 |
|---|---|---|---|
| 三菱 FX | 特殊寄存器 D 区(如 D2000-D2999)默认保持 | 初始化程序放在 M8002(上电脉冲) | 用 MOV 指令保存数据,M8002 替代 OB100 |
| 台达 DVP | 「系统寄存器」设置掉电保持区 | 上电脉冲 M1000 | 逻辑与三菱一致 |
| 欧姆龙 CP | DM 区默认保持 | 上电脉冲 A200.00 | 用 MOV 指令保存数据 |
总结
断电重启程序核心:掉电保持区保存关键数据 + 上电启动块恢复状态 + 运行中实时更新;
关键细节:上电先校验数据合法性,轴先回位再运行,避免撞机 / 定位偏差;
适配场景:三轴机、变频器控制电机等频繁启停 / 需要定位的设备,均可直接套用这套逻辑。

