FUNCTION_BLOCK "FB_PickProductionDemo" { S7_Optimized_Access := 'TRUE' } VERSION : 1.0 VAR_INPUT StartPB : Bool; // 启动按钮(上升沿有效) StopPB : Bool; // 停止按钮 ResetPB : Bool; // 故障复位(上升沿有效) EStopOK : Bool; // 急停安全回路正常=TRUE AutoMode : Bool; // 自动模式=TRUE PartAtLoad : Bool; // 上料位有毛坯 LoadDone : Bool; // 下料/加热完成 ForgeDone : Bool; // 热锻完成 AnnealDone : Bool; // 退火完成 MachineDone : Bool; // 数控加工完成 HeatTreatDone : Bool; // 淬火+回火完成 BlastDone : Bool; // 抛丸完成 BrazeDone : Bool; // 钎焊完成 InspectOK : Bool; // 终检合格 UnloadDone : Bool; // 成品下线完成 StepTimeout : Time := T#30s; // 演示用统一工位超时 END_VAR VAR_OUTPUT SystemRun : Bool; SystemReady : Bool; CycleComplete : Bool; Alarm : Bool; AlarmCode : UInt; // 1=急停,100+步骤号=该步骤超时 StepNo : Int; CmdLoad : Bool; CmdForge : Bool; CmdAnneal : Bool; CmdMachine : Bool; CmdHeatTreat : Bool; CmdBlast : Bool; CmdBraze : Bool; CmdInspect : Bool; CmdUnload : Bool; END_VAR VAR StartEdge : R_TRIG; ResetEdge : R_TRIG; StepTimer : TON; RunLatch : Bool; FaultLatch : Bool; InternalStep : Int := 0; TimerStep : Int := -1; TimerEnable : Bool; END_VAR BEGIN // 按钮沿检测 #StartEdge(CLK := #StartPB); #ResetEdge(CLK := #ResetPB); // 默认关闭全部工位命令,后续按步骤单独置位 #CmdLoad := FALSE; #CmdForge := FALSE; #CmdAnneal := FALSE; #CmdMachine := FALSE; #CmdHeatTreat := FALSE; #CmdBlast := FALSE; #CmdBraze := FALSE; #CmdInspect := FALSE; #CmdUnload := FALSE; #CycleComplete := FALSE; #TimerEnable := FALSE; // 急停状态锁存。注意:真实急停必须使用安全硬件切断能量。 IF NOT #EStopOK THEN #RunLatch := FALSE; #FaultLatch := TRUE; #AlarmCode := 1; #InternalStep := 0; END_IF; // 故障复位仅在急停回路恢复后允许 IF #ResetEdge.Q AND #EStopOK THEN #FaultLatch := FALSE; #AlarmCode := 0; #RunLatch := FALSE; #InternalStep := 0; END_IF; // 正常停止:停止当前循环并回待机 IF #StopPB OR NOT #AutoMode THEN #RunLatch := FALSE; #InternalStep := 0; END_IF; // 自动启动条件:安全正常、无故障、自动模式、上料位有工件 IF #StartEdge.Q AND #EStopOK AND NOT #FaultLatch AND #AutoMode AND #PartAtLoad AND (#InternalStep = 0) THEN #RunLatch := TRUE; #InternalStep := 10; END_IF; // 顺序状态机 IF #RunLatch AND NOT #FaultLatch THEN CASE #InternalStep OF 10: // 下料与感应加热 #CmdLoad := TRUE; #TimerEnable := TRUE; IF #LoadDone THEN #InternalStep := 20; END_IF; 20: // 热锻成型 #CmdForge := TRUE; #TimerEnable := TRUE; IF #ForgeDone THEN #InternalStep := 30; END_IF; 30: // 锻后退火 #CmdAnneal := TRUE; #TimerEnable := TRUE; IF #AnnealDone THEN #InternalStep := 40; END_IF; 40: // CNC粗车/精车 #CmdMachine := TRUE; #TimerEnable := TRUE; IF #MachineDone THEN #InternalStep := 50; END_IF; 50: // 淬火与回火 #CmdHeatTreat := TRUE; #TimerEnable := TRUE; IF #HeatTreatDone THEN #InternalStep := 60; END_IF; 60: // 抛丸/喷砂 #CmdBlast := TRUE; #TimerEnable := TRUE; IF #BlastDone THEN #InternalStep := 70; END_IF; 70: // 高频感应钎焊 #CmdBraze := TRUE; #TimerEnable := TRUE; IF #BrazeDone THEN #InternalStep := 80; END_IF; 80: // 尺寸、硬度、焊合质量检查 #CmdInspect := TRUE; #TimerEnable := TRUE; IF #InspectOK THEN #InternalStep := 90; END_IF; 90: // 合格品下线 #CmdUnload := TRUE; #TimerEnable := TRUE; IF #UnloadDone THEN #CycleComplete := TRUE; #RunLatch := FALSE; #InternalStep := 0; END_IF; ELSE #RunLatch := FALSE; #InternalStep := 0; END_CASE; END_IF; // 每次步骤变化先复位计时器,确保超时按单个工位分别计算 IF #InternalStep <> #TimerStep THEN #StepTimer(IN := FALSE, PT := #StepTimeout); #TimerStep := #InternalStep; ELSE #StepTimer(IN := #TimerEnable, PT := #StepTimeout); END_IF; // 统一步骤超时监控 IF #StepTimer.Q AND #RunLatch THEN #FaultLatch := TRUE; #RunLatch := FALSE; #AlarmCode := INT_TO_UINT(100 + #InternalStep); #InternalStep := 0; END_IF; #SystemRun := #RunLatch; #SystemReady := #EStopOK AND #AutoMode AND NOT #FaultLatch; #Alarm := #FaultLatch; #StepNo := #InternalStep; END_FUNCTION_BLOCK