PLC模块化编程实战:把工业流水线控制逻辑拆分为可复用功能块
工业流水线越做越长,供料、传送、加工、检测、分拣各工位如果都写进主程序,后期改一个点就牵一发动全身。正确做法是按IEC 61131-3分三层:设备级FB封装电机/气缸/阀门,单元级FB封装单工位状态机,主程序只做编排和互锁。这样新线复制实例即可,调试、移植、查故障都省事。
一、设备级:电机FB参数化
每台电机不重复写起保停,输入启动、停止、运行反馈、故障复位,输出运行状态和故障码;定时器放静态区,保证多实例互不干扰。
FUNCTION_BLOCK FB_Motor
VAR_INPUT StartCmd:BOOL; StopCmd:BOOL; RunFb:BOOL; Ack:BOOL; ConfirmT:TIME:=T#4S; END_VAR
VAR_OUTPUT Run:BOOL; Fault:BOOL; FaultCode:INT; END_VAR
VAR Latch:BOOL; Ton:TON; END_VAR
IF StartCmd AND NOT StopCmd AND NOT Fault THEN Latch:=TRUE; END_IF;
IF StopCmd THEN Latch:=FALSE; END_IF;
Ton(IN:=Latch AND NOT RunFb, PT:=ConfirmT);
IF Ton.Q THEN Fault:=TRUE; FaultCode:=2; Latch:=FALSE; END_IF;
IF Ack AND NOT Ton.Q THEN Fault:=FALSE; FaultCode:=0; END_IF;
Run:=Latch AND NOT Fault;
运行反馈超时、过载、急停都可在调用层并入StopCmd/Fault,统一走一个FB。
二、设备级:气缸FB带双位与超时
气缸用原位/工作位磁开、急停、自动命令、超时时间做接口,避免双线圈同时输出,不到位自动报警。
FUNCTION_BLOCK FB_Cylinder
VAR_INPUT Estop:BOOL; Auto:BOOL; ToWork:BOOL; ToHome:BOOL;
SnWork:BOOL; SnHome:BOOL; ToutWork:TIME:=T#3S; ToutHome:TIME:=T#3S; END_VAR
VAR_OUTPUT OutWork:BOOL; OutHome:BOOL; Alarm:BOOL; AtWork:BOOL; AtHome:BOOL; END_VAR
VAR Tw:TON; Th:TON; END_VAR
OutWork:=0; OutHome:=0;
IF Estop AND Auto THEN
IF ToWork THEN OutWork:=1; END_IF;
IF ToHome THEN OutHome:=1; END_IF;
END_IF;
Tw(IN:=OutWork AND NOT SnWork, PT:=ToutWork);
Th(IN:=OutHome AND NOT SnHome, PT:=ToutHome);
AtWork:=SnWork; AtHome:=SnHome;
Alarm:=Tw.Q OR Th.Q;
IF OutWork AND OutHome THEN OutWork:=0; OutHome:=0; Alarm:=1; END_IF;
三、单元级:工位状态机
单工位用枚举+CASE,空闲、等料、夹紧、加工、放行各自独立,避免梯形图互锁写成“面条”。
TYPE E_Station:(IDLE,WAIT_PART,CLAMP,WORK,RELEASE,FAULT); END_TYPE
FUNCTION_BLOCK FB_Station
VAR_INPUT Start:BOOL; Estop:BOOL; PartIn:BOOL; Done:BOOL; Ack:BOOL; WorkT:TIME:=T#5S; END_VAR
VAR_OUTPUT Clamp:BOOL; Process:BOOL; Busy:BOOL; Alarm:BOOL; END_VAR
VAR Stat:E_Station:=IDLE; Tw:TON; END_VAR
CASE Stat OF
IDLE: IF Start AND Estop THEN Stat:=WAIT_PART; END_IF;
WAIT_PART: IF PartIn THEN Stat:=CLAMP; END_IF;
CLAMP: Clamp:=1; Stat:=WORK;
WORK: Process:=1; Tw(IN:=1,PT:=WorkT);
IF Tw.Q AND Done THEN Stat:=RELEASE; END_IF;
IF NOT Estop THEN Stat:=FAULT; END_IF;
RELEASE: Clamp:=0; Process:=0; Busy:=0; Stat:=IDLE;
FAULT: Alarm:=1; Clamp:=0; Process:=0;
IF Ack AND Estop THEN Stat:=IDLE; END_IF;
END_CASE;
Busy:=(Stat<>IDLE) AND (Stat<>FAULT);
四、主程序编排与多实例
把各工位声明为同FB实例,主OB只做模式、急停、连锁和产量统计;同类型多台用数组批量调用。
VAR
St:ARRAY[1..6] OF FB_Station;
Mtr:ARRAY[1..6] OF FB_Motor;
i:INT;
END_VAR
FOR i:=1 TO 6 DO
St[i](Start:=Auto AND NOT EMG, Estop:=NOT EMG, PartIn:=Photo[i], Done:=AxDone[i]);
Mtr[i](StartCmd:=St[i].Busy, StopCmd:=EMG, RunFb:=MtrFb[i], Ack:=Reset);
END_FOR;
新增第7工位只扩数组和IO映射,不改控制逻辑;HMI读各实例状态字、故障码即可。
五、落地规范
点表用UDT统一定义地址、量程、单位、报警上下限,FB只认UDT不认绝对地址;
定时器、计数器、累计值全放FB静态/实例DB,禁止放TEMP,否则跨扫描丢状态;
急停在FB外再硬切一次输出,软件互锁只作补充;
气缸、伺服、变频器各自独立FB,工位FB只调用不写底层脉冲;
标准块入库管版本,接口变更升版本号,主程序按实例升级,不整包重写。
按“设备FB—工位状态机—主程序编排”三层拆,产线从3工位扩到20工位,核心代码增加的主要是新实例和点表,而不是新逻辑,维护效率明显高于单程序平铺。





