4. ctrlX PLC编程基础

ctrlX PLC 的编程体系建立在 IEC 61131-3 标准之上,而实际开发入口是 ctrlX WORKS 中集成的 CODESYS 环境。理解这三者之间的关系,是后续所有编程、调试和工程组织工作的前提。IEC 61131-3 规定了编程语言、数据类型、程序组织单元和变量声明方式;CODESYS 把这些标准落地为可操作的工程界面;ctrlX PLC 则通过运行时和 I/O 映射,让程序真正控制设备。本节围绕“标准—环境—任务—变量—指令—POU”这条主线展开,重点说明实际工程中如何组织一个可运行、可扩展的 PLC 项目。

IEC 61131-3 与 CODESYS 的对应关系

IEC 61131-3 定义了五种编程语言:梯形图(LD)、功能块图(FBD)、顺序功能图(SFC)、指令表(IL)和结构化文本(ST)。在 ctrlX PLC 的 CODESYS 工程中,最常用的是 ST 和 LD:ST 适合表达复杂运算、状态判断和循环逻辑;LD 适合表达继电器逻辑和现场维护人员容易阅读的联锁关系。标准还规定了标准数据类型,如 BOOL、BYTE、WORD、DWORD、INT、DINT、REAL、TIME、STRING 等,以及用户自定义数据类型(DUT)和数组、结构体。CODESYS 在标准基础上扩展了 LREAL、LTIME、WSTRING 等类型,并提供库函数和系统功能块。

程序组织单元(POU)是 IEC 61131-3 的核心概念,包括程序(PROGRAM)、功能块(FUNCTION_BLOCK)和函数(FUNCTION)。程序是任务调用的顶层单元,拥有静态变量;功能块可以带内部状态,多次实例化后各自保持数据;函数没有内部状态,相同输入必得相同输出。ctrlX PLC 项目中,通常用一个主程序组织设备状态机,用多个功能块封装轴控制、气缸动作、报警处理等可复用逻辑,用函数完成单位换算、数据校验等纯计算任务。

ctrlX PLC 编程体系:标准、环境、任务与 POU 的关系 IEC 61131-3 标准层 编程语言 LD/ST/FBD/SFC 标准数据类型 POU:PRG/FB/FC 变量声明与作用域 任务与执行模型 CODESYS 开发环境层(ctrlX WORKS 内) 设备树与 PLC 节点 ctrlX PLC 设备描述 应用与库管理 Application / Library 任务配置 Task / 周期 / 优先级 I/O 映射 输入/输出变量绑定 在线调试 监视/强制 任务执行与程序组织单元(POU) 任务配置 MainTask(循环) 周期:10 ms 优先级:1 看门狗:使能 调用 PRG_Main 程序组织单元(POU) PRG_Main(程序) 状态机 / 调用 FB FB_AxisCtrl(功能块) 带状态,可多实例 FC_Scale(函数) 无状态,纯计算 VAR_GLOBAL 全局变量 g_bStart, g_rSpeed VAR_INPUT / VAR_OUTPUT 接口变量 VAR / VAR_TEMP 静态 / 临时变量

任务配置:决定程序何时执行

在 CODESYS 中,任务(Task)决定 POU 的调用时机和频率。ctrlX PLC 工程通常至少配置一个循环任务,例如 MainTask,周期设为 10 ms,优先级为 1。周期越短,控制响应越快,但 CPU 负载也越高。对于慢速温度采集或数据记录,可以另建一个 100 ms 或 1 s 的循环任务,避免占用高速任务的时间片。对于需要与外部事件同步的逻辑,可以使用外部事件任务或自由运行任务。

任务配置中需要关注三个参数:周期、优先级和看门狗。优先级数值越小,优先级越高;当高优先级任务就绪时,会抢占低优先级任务。看门狗用于检测任务是否超时,若任务执行时间超过设定值,PLC 会报错并可能进入安全状态。实际工程中,建议先估算程序扫描时间,再留出 30% 以上余量。例如 MainTask 周期 10 ms,实际扫描时间应控制在 7 ms 以内。可以通过 CODESYS 的“任务监视”查看各任务的实际执行时间和负载。

变量声明:作用域与数据类型

变量声明决定了数据的可见范围和生命周期。在 POU 内部,VAR 声明静态变量,每次调用保持上次值;VAR_TEMP 声明临时变量,每次调用重新初始化;VAR_INPUT 和 VAR_OUTPUT 定义功能块或函数的接口;VAR_IN_OUT 用于传递引用,适合大型结构体。全局变量在 GVL(Global Variable List)中声明,使用 VAR_GLOBAL,并可通过“合格访问”方式在 POU 中引用。

数据类型选择直接影响内存占用和运算精度。BOOL 占 1 位,适合开关量;INT 占 16 位,范围 -32768~32767;DINT 占 32 位;REAL 为 32 位浮点数,适合模拟量;LREAL 为 64 位浮点数,适合高精度计算。对于时间量,使用 TIME 或 LTIME,例如 T#10ms、T#1s500ms。数组和结构体可以组织相关数据,例如定义一个 ST_AxisData 结构体,包含位置、速度、状态字和错误码,再声明 ARRAY[1..4] OF ST_AxisData 表示四轴数据。

VAR_GLOBAL
    g_bStart      : BOOL := FALSE;      // 启动按钮
    g_rSpeedSet   : REAL := 1500.0;     // 速度设定,单位 rpm
    g_uiAlarmCode : UINT := 0;          // 报警代码
END_VAR

FUNCTION_BLOCK FB_AxisCtrl
VAR_INPUT
    bEnable   : BOOL;                   // 使能
    rSpeed    : REAL;                   // 速度给定
END_VAR
VAR_OUTPUT
    bReady    : BOOL;                   // 就绪
    rActSpeed : REAL;                   // 实际速度
END_VAR
VAR
    tonStart  : TON;                    // 启动延时
    nState    : INT := 0;               // 内部状态
END_VAR

基本指令与程序组织单元的实际组织

ST 语言的基本指令包括赋值(:=)、比较(=、<>、<、>)、逻辑运算(AND、OR、NOT、XOR)、算术运算(+、-、*、/、MOD)以及条件语句 IF、CASE 和循环语句 FOR、WHILE、REPEAT。实际编程中,CASE 语句非常适合实现设备状态机。例如,用 nState 表示“空闲、启动中、运行、停止中、故障”五个状态,每个状态内处理对应输出和转移条件,结构清晰,便于后期增加状态。

程序组织单元的组织方式建议遵循“主程序调度、功能块封装、函数计算”的原则。PRG_Main 负责调用各功能块并处理全局状态;FB_AxisCtrl 封装单轴使能、速度给定、就绪判断和报警复位;FC_Scale 完成模拟量原始值到工程量的线性换算。功能块实例应声明在 PRG_Main 的 VAR 区,例如 axis1 : FB_AxisCtrl; axis2 : FB_AxisCtrl;,这样每个实例拥有独立的状态变量,互不干扰。

在 ctrlX PLC 中,I/O 变量通常通过“设备树—PLC 节点—I/O 映射”自动生成,命名规则类似“Inputs.bStart”或“Outputs.bLamp”。建议在 GVL 中再定义一层工程变量,把 I/O 变量映射到 g_bStart、g_bLamp 等语义化名称,这样程序逻辑与硬件地址解耦,更换模块时只需修改映射,不必改动 POU 内部代码。

一个可运行的最小示例

假设 ctrlX PLC 控制一台输送电机:启动按钮接 DI0,停止按钮接 DI1,电机接触器接 DO0,速度给定来自 AI0(0~10 V 对应 0~3000 rpm)。在 CODESYS 中新建 Application,添加 MainTask(10 ms),创建 PRG_Main 并声明全局变量和功能块实例。程序逻辑如下:按下启动按钮且无故障时,进入运行状态,DO0 输出 TRUE,速度给定通过 FC_Scale 换算后写入模拟量输出;按下停止按钮或检测到故障时,进入停止状态,DO0 输出 FALSE。通过在线监视可以看到 nState 在 0、1、2 之间切换,rActSpeed 跟随给定变化。若电机未启动,先检查 DO0 是否强制、任务是否运行、I/O 映射是否正确,再检查看门狗是否触发。

掌握以上内容后,就可以在 ctrlX PLC 中建立结构清晰、可维护的 CODESYS 工程。后续的轴控制、通信和诊断功能,都会以任务、变量和 POU 为基础逐步展开。