2. PLC编程基础回顾

在进入PLC程序的CI持续集成之前,有必要把PLC编程的基础知识重新梳理一遍。CI流水线最终要编译、检查、测试和部署的是PLC程序本身,如果对PLC的扫描机制、语言形态、程序组织方式和数据类型缺乏清晰认识,后续的自动化构建、静态检查和仿真测试就无从谈起。本节从工作原理出发,串联编程语言、程序结构与变量类型四条主线,为后续的工程化实践打底。

一、PLC工作原理:循环扫描与输入输出映像

PLC最核心的运行特征是循环扫描。CPU并不像通用计算机那样按事件随机执行,而是周期性地重复三个阶段:输入采样、程序执行、输出刷新。在输入采样阶段,PLC把所有物理输入点的状态一次性读入输入映像区;在程序执行阶段,CPU按用户程序的顺序逐条运算,读写的是映像区而不是直接访问物理端口;在输出刷新阶段,再把输出映像区的结果统一送到物理输出模块。

这种机制带来两个重要结论:其一,程序执行期间输入状态是"冻结"的,即使外部信号变化,也要等下一个扫描周期才能被读到;其二,输出不会在每条指令执行后立即改变,而是周期末统一刷新。扫描周期通常在毫秒级,但对于高速脉冲、精确定时等场景,必须考虑扫描周期带来的响应延迟。

理解扫描机制是理解PLC程序行为的钥匙。CI中的仿真测试之所以能复现问题,正是因为仿真器严格按扫描周期执行程序,与真实PLC保持一致的时序语义。

二、常用编程语言:LD、FBD、ST、SFC

IEC 61131-3标准定义了五种编程语言,工程中最常用的是梯形图(LD)、功能块图(FBD)、结构化文本(ST)和顺序功能图(SFC)。它们并非互斥,同一个项目中往往混合使用:用SFC描述工艺流程,用LD或FBD实现联锁逻辑,用ST处理复杂计算和通信。

语言全称典型形态适用场景
LD梯形图触点、线圈、并联串联继电器逻辑、联锁、启停控制
FBD功能块图方框与连线模拟量处理、PID、信号流
ST结构化文本类Pascal语句算法、循环、数组、通信
SFC顺序功能图步与转换条件顺序流程、状态机、配方切换

以ST为例,一段简单的启停逻辑可以写成如下形式,便于版本管理和代码审查:

IF Start AND NOT Stop THEN
    Motor := TRUE;
ELSIF Fault OR NOT Start THEN
    Motor := FALSE;
END_IF;

IF Motor THEN
    RunTime := RunTime + CycleTime;
END_IF;

LD和FBD直观易读,适合现场调试;ST表达能力强,适合复杂逻辑和批量处理;SFC把流程拆成"步"和"转换",天然适合描述设备的工作阶段。CI流水线需要能解析这些不同语言的源文件,因此项目通常采用标准化的导出格式(如PLCopen XML)作为构建输入。

三、程序结构:从任务到功能块

PLC程序并非一堆散乱的指令,而是有清晰的组织层级。典型结构自顶向下为:任务(Task)→ 程序(Program)→ 功能块(FB/FC)→ 变量。任务是调度的单位,决定程序以何种周期或事件触发;程序是任务的执行体;功能块是可复用的逻辑单元,其中FB带背景数据、有状态,FC无状态、纯函数。

合理的程序结构应遵循"高内聚、低耦合":把电机控制封装成一个FB,把报警处理封装成另一个FB,主程序只负责调用和协调。这样在CI中,单个FB可以独立编译和单元测试,变更影响范围可控,回归测试也更有针对性。

建议为每个功能块定义清晰的接口(输入、输出、输入输出参数),接口一旦稳定,内部实现的重构就不会影响调用方,这正是持续集成能够频繁合并的前提。

四、变量与数据类型:CI检查的第一道关口

变量是程序的血液。按作用域可分为全局变量和局部变量;按性质可分为输入、输出、输入输出和静态变量。数据类型则决定了变量的取值范围和运算方式,常用类型包括:

  • BOOL:布尔量,用于开关、状态标志;
  • INT / DINT:整数,用于计数、索引;
  • REAL / LREAL:浮点数,用于模拟量、PID;
  • TIME:时间量,用于延时和超时判断;
  • STRING:字符串,用于配方名、日志;
  • ARRAY / STRUCT:数组和结构体,用于批量数据和复合对象。

类型不匹配是PLC程序中最常见的隐性缺陷之一。例如把INT直接赋给REAL、把TIME与INT相加、数组越界访问,在传统手动调试中往往要等到运行时才暴露。而在CI中,编译器与静态检查工具可以在提交阶段就捕获这些错误,把问题拦截在合并之前。

五、案例与复盘:一个启停控制的CI视角

假设有一个电机启停控制功能块,输入为Start、Stop、Fault,输出为Motor。手动开发时,工程师在IDE里写完LD,下载到PLC,现场点动验证。这种方式在单人、单设备时可行,但当项目有几十个FB、多人协作、频繁变更时,问题就会累积。

引入CI后,同样的FB会经历:提交代码 → 自动编译 → 静态检查(类型、未使用变量、命名规范)→ 单元测试(给定输入序列,断言输出)→ 生成可部署包。若某次提交把Stop误写成常闭触点,单元测试会立即失败,流水线阻断合并,避免缺陷流入现场。

常见误区:认为"PLC程序能下载运行就没问题"。实际上,能运行不等于逻辑正确,更不等于可维护。CI的价值在于把"能运行"提升为"可验证、可追溯、可回归"。

综上,PLC工作原理决定了程序的时序语义,编程语言决定了表达方式,程序结构决定了可复用性,变量与数据类型决定了正确性边界。这四点共同构成了PLC程序CI持续集成的技术底座。只有把这些基础打牢,后续的自动化构建、测试与部署才有稳固的立足点。

PLC程序CI持续集成的技术底座 循环扫描 输入采样 程序执行 输出刷新 周期 编程语言 LD 梯形图 FBD 功能块图 ST 结构化文本 SFC 顺序功能图 程序结构 Task 任务 Program 程序 FB / FC 功能块 变量与类型 BOOL / INT REAL / TIME STRING ARRAY / STRUCT PLC程序 CI 持续集成 提交代码 自动编译 静态检查 单元测试 生成部署包 扫描机制决定时序语义 · 语言决定表达方式 · 结构决定复用性 · 类型决定正确性边界