4. PLCopen与IEC 61131-3在ctrlX中的编程实践

在柔性产线中,控制程序往往需要同时应对多种产品变型、频繁的工位切换以及不断新增的执行机构。如果每个工位都从头编写电机启停和气缸动作逻辑,程序会迅速膨胀,维护成本也会急剧上升。ctrlX AUTOMATION 的 ctrlX PLC 应用完整支持 IEC 61131-3 标准,并在此基础上遵循 PLCopen 规范,为程序组织单元(POU)、任务配置和功能块复用提供了工程化基础。本节围绕标准编程语言、POU 结构、任务配置以及可复用功能块的设计展开,最终落到电机启停与气缸控制两个典型功能块的实现。

标准编程语言与 POU 类型

IEC 61131-3 定义了五种标准编程语言:梯形图(LD)、功能块图(FBD)、顺序功能图(SFC)、结构化文本(ST)和指令表(IL)。在 ctrlX PLC 的工程环境中,LD 和 FBD 适合表达布尔联锁和电气逻辑,SFC 适合描述工位步序,ST 则适合编写带条件判断、算术运算和状态机的功能块。柔性产线中,设备级逻辑推荐用 ST 编写功能块,产线级步序用 SFC 组织,这样既保证可读性,也便于复用。

POU 分为三类:功能(FUN)、功能块(FB)和程序(PRG)。功能没有内部状态,相同输入必得相同输出,例如限幅、换算;功能块拥有内部状态,适合封装“启动—运行—停止”这类带记忆的过程;程序则作为任务调度的入口。柔性产线中,电机和气缸的控制逻辑天然带状态,因此应封装为功能块,而不是功能。

任务配置与执行关系

ctrlX PLC 采用任务驱动模型。一个应用可包含多个任务,每个任务绑定一组程序,并设定周期或事件触发方式。常见做法是:高速任务(如 1 ms)处理急停、安全联锁和编码器采样;中速任务(如 10 ms)处理电机启停与气缸动作;低速任务(如 100 ms)处理状态汇总、HMI 通信和诊断。任务之间通过全局变量或共享数据区交换数据,但必须注意数据一致性——高速任务写入、低速任务读取时,应使用双缓冲或原子标志位,避免读到半更新数据。

任务配置还决定了功能块的调用周期。一个电机功能块若在 10 ms 任务中调用,其内部计时器分辨率即为 10 ms;若同一功能块被放到 1 ms 任务中,计时精度提高,但 CPU 负载也上升。因此,功能块设计时应把时间参数化,而不是在内部写死。

ctrlX PLC 任务配置与可复用功能块调用关系 高速任务 Task_Fast 周期 1 ms 急停 / 安全联锁 / 编码器 中速任务 Task_Mid 周期 10 ms 电机启停 / 气缸动作 低速任务 Task_Slow 周期 100 ms 状态汇总 / HMI / 诊断 FB_SafetyMonitor 急停链 / 安全门状态 输出:Enable / Fault FB_MotorCtrl 输入:Start/Stop/Enable/Fault 输出:Run/Ready/Error FB_CylinderCtrl 输入:Extend/Retract/Sensor 输出:ValveOut/Pos/Timeout Enable Run 功能块实例化与复用 Motor_Conveyor1 FB_MotorCtrl 输送带电机 Motor_Indexer FB_MotorCtrl 分度盘电机 Cyl_Clamp1 FB_CylinderCtrl 夹具气缸 同一功能块可多次实例化,各自维护独立状态,实现柔性产线设备复用

电机启停功能块设计

柔性产线中的电机通常需要满足以下要求:具备启动、停止、急停复位三种命令;运行时输出“运行”状态;故障时输出“错误”并保持停止;启动前需确认安全使能有效。下面给出一个基于 ST 的功能块接口定义与核心逻辑示例。

FUNCTION_BLOCK FB_MotorCtrl
VAR_INPUT
    Start    : BOOL;   // 启动按钮(上升沿有效)
    Stop     : BOOL;   // 停止按钮(常闭,FALSE 表示停止)
    Enable   : BOOL;   // 安全使能,来自安全任务
    Fault    : BOOL;   // 外部故障(热继、驱动器报警)
    T_Start  : TIME := T#500MS;  // 启动确认时间
END_VAR
VAR_OUTPUT
    Run      : BOOL;   // 电机运行输出
    Ready    : BOOL;   // 就绪,可启动
    Error    : BOOL;   // 故障输出
END_VAR
VAR
    R_Start  : R_TRIG; // 启动上升沿
    TON_Chk  : TON;    // 启动确认定时器
    State    : INT := 0; // 0=停止 1=启动中 2=运行 3=故障
END_VAR

R_Start(CLK := Start);
Ready := Enable AND NOT Fault AND (State = 0);

CASE State OF
    0:  // 停止
        Run := FALSE;
        Error := FALSE;
        IF R_Start.Q AND Ready THEN
            State := 1;
        END_IF;
    1:  // 启动中,等待 T_Start 确认
        TON_Chk(IN := TRUE, PT := T_Start);
        IF TON_Chk.Q THEN
            State := 2;
            TON_Chk(IN := FALSE);
        END_IF;
        IF Fault OR NOT Enable THEN
            State := 3;
        END_IF;
    2:  // 运行
        Run := TRUE;
        IF NOT Stop OR Fault OR NOT Enable THEN
            State := 0;
            Run := FALSE;
        END_IF;
    3:  // 故障
        Run := FALSE;
        Error := TRUE;
        IF NOT Fault AND Enable THEN
            State := 0;
            Error := FALSE;
        END_IF;
END_CASE;

该功能块的关键点在于:启动采用上升沿触发,避免按钮长按导致重复启动;启动确认时间 T_Start 用于等待驱动器就绪,若超时未进入运行则视为异常;停止使用常闭信号,断线时自动停止,符合失效安全原则。在 ctrlX PLC 中,将该功能块分别实例化为 Motor_Conveyor1、Motor_Indexer 等,每个实例拥有独立的 State 和定时器,互不干扰。

气缸控制功能块设计

气缸控制比电机多了一层位置反馈。典型双作用气缸带两个磁性开关:伸出到位传感器和缩回到位传感器。功能块需要输出电磁阀控制信号,并监测动作是否在设定时间内完成,超时则报警。以下为接口与核心逻辑示例。

FUNCTION_BLOCK FB_CylinderCtrl
VAR_INPUT
    Extend      : BOOL;  // 伸出命令
    Retract     : BOOL;  // 缩回命令
    SensorExt   : BOOL;  // 伸出到位传感器
    SensorRet   : BOOL;  // 缩回到位传感器
    T_Timeout   : TIME := T#2S;  // 动作超时
END_VAR
VAR_OUTPUT
    ValveExt    : BOOL;  // 伸出电磁阀
    ValveRet    : BOOL;  // 缩回电磁阀
    PosExtended : BOOL;  // 已伸出
    PosRetracted: BOOL;  // 已缩回
    Timeout     : BOOL;  // 动作超时
END_VAR
VAR
    TON_Act     : TON;
    Cmd         : INT := 0; // 0=无 1=伸出 2=缩回
END_VAR

PosExtended  := SensorExt;
PosRetracted := SensorRet;
Timeout := FALSE;

IF Extend AND NOT Retract THEN
    Cmd := 1;
ELSIF Retract AND NOT Extend THEN
    Cmd := 2;
END_IF;

CASE Cmd OF
    1:
        ValveExt := TRUE;  ValveRet := FALSE;
        TON_Act(IN := NOT SensorExt, PT := T_Timeout);
        IF TON_Act.Q THEN Timeout := TRUE; Cmd := 0; END_IF;
        IF SensorExt THEN Cmd := 0; TON_Act(IN := FALSE); END_IF;
    2:
        ValveRet := TRUE;  ValveExt := FALSE;
        TON_Act(IN := NOT SensorRet, PT := T_Timeout);
        IF TON_Act.Q THEN Timeout := TRUE; Cmd := 0; END_IF;
        IF SensorRet THEN Cmd := 0; TON_Act(IN := FALSE); END_IF;
    0:
        ValveExt := FALSE; ValveRet := FALSE;
END_CASE;

该功能块中,Extend 与 Retract 同时为 TRUE 时不做任何动作,避免阀岛双线圈同时得电。超时判断以“命令发出后传感器未到位”为条件,超时后关闭电磁阀并置位 Timeout,由上层程序决定是否重试或停机。在柔性产线中,同一气缸功能块可实例化为 Cyl_Clamp1、Cyl_Ejector 等,只需修改 T_Timeout 即可适配不同行程和气压条件。

任务调用与数据一致性

将上述功能块放入中速任务 Task_Mid 中调用,安全使能 Enable 由高速任务 Task_Fast 中的 FB_SafetyMonitor 输出。由于两个任务周期不同,Enable 的写入和读取存在时间差。工程上通常采用“高速任务写、中速任务读”的单向数据流,并保证 Enable 为 BOOL 类型,读写本身是原子的,不会出现中间值。若传递的是结构体或数组,则需使用双缓冲或信号量保护。

在 ctrlX PLC 中,功能块的实例名建议采用“设备类型_设备编号”的命名方式,如 Motor_Conveyor1、Cyl_Clamp1,便于在变量表中快速定位和批量替换。

可复用性检查要点

  • 功能块内部不直接引用具体物理地址,所有 I/O 通过输入输出引脚传入,便于在不同工位复用。
  • 时间参数、超时阈值作为输入变量,不写死在逻辑中,方便按设备调整。
  • 状态机使用 INT 或枚举,避免多个 BOOL 标志互相冲突。
  • 每个实例独立维护状态,同一功能块多次调用不会互相干扰。
  • 故障输出与安全使能分离,安全逻辑由独立任务处理,功能块只做设备级控制。

通过以上方式,柔性产线中的电机和气缸控制逻辑可以封装为少量功能块,再通过多次实例化覆盖整线设备。当产线增加新工位时,只需新增实例并绑定对应 I/O,无需重写控制逻辑,这正是 IEC 61131-3 与 PLCopen 在 ctrlX 中带来的工程化收益。