4、PLC程序架构设计:主程序、子程序、中断程序的组织与规划
做PLC项目这么多年,我见过太多“一锅粥”式的程序了。所有逻辑全塞在一个循环里,看着就头疼。今天咱们聊聊程序架构,说白了就是怎么把代码安排得明明白白。
4.1 为什么需要分层架构?
你想想看,一个自动化产线少说几百个点位。如果全写在一个程序块里,调试时找个电机启停都得翻半天。我个人习惯把程序分成三层:
- 主程序:负责整体调度,像个指挥官
- 子程序:处理具体功能,比如电机控制、阀门逻辑
- 中断程序:处理紧急事件,比如急停、故障捕获
我在项目中遇到过最惨的一次,就是接手一个老工程师的程序。整个程序就一个OB1,上万行梯形图。改一个定时器参数,得全局搜索半小时。嗯,从那以后我坚决要求分层。
4.2 主程序(OB1)的设计要点
主程序是PLC的“心脏”。它负责循环扫描,调用各个子程序。但这里有个坑——很多人把主程序当垃圾桶,什么逻辑都往里塞。
- 初始化调用(上电时执行一次)
- 子程序轮询(按顺序调用各个功能块)
- 故障汇总(集中处理报警信息)
我曾经见过一个项目,主程序里写了200多个网络。结果扫描周期从5ms飙到50ms,设备动作肉眼可见的卡顿。后来我把90%的逻辑拆到子程序里,扫描周期直接降到8ms。
4.3 子程序的组织策略
子程序怎么分?我有个“三不原则”:
- 不混搭:一个子程序只做一类事。电机控制就别掺和气缸逻辑
- 不超长:单个子程序别超过50个网络。超过就拆
- 不重复:同样的逻辑只写一次,用多重背景调用
举个例子,一个包装产线我会这样分:
| 子程序名称 | 功能描述 | 调用频率 |
|---|---|---|
| FC_MotorCtrl | 所有电机启停、正反转、过载保护 | 每个扫描周期 |
| FC_ValveCtrl | 气缸、电磁阀的时序控制 | 每个扫描周期 |
| FC_SensorRead | 传感器信号采集与滤波 | 每5个周期 |
| FC_AlarmHandle | 故障诊断与报警输出 | 每个扫描周期 |
这里要注意,FC_SensorRead我故意降低了调用频率。为什么?因为传感器信号变化没那么快,没必要每个周期都读。这样可以节省CPU资源。
4.4 中断程序的正确用法
中断程序是PLC的“特种部队”。平时不干活,一有紧急情况立刻响应。但很多人滥用中断,结果系统稳定性反而下降。
中断程序的典型应用场景:
- 急停信号处理(必须立即停止所有输出)
- 高速计数器中断(比如编码器脉冲计数)
- 定时中断(比如PID调节的固定周期采样)
- 通讯中断(比如PROFINET数据接收)
我曾经犯过一个错误:把温度超限报警也写进了中断程序。结果温度探头一抖动,中断程序频繁触发,主程序反而被“饿死”了。后来我改成在主程序里做滤波处理,中断只留给真正的紧急事件。
我的经验:中断程序里别写复杂逻辑。就做三件事:
- 读取触发信号
- 设置标志位
- 输出紧急动作
其他处理交给主程序去判断。中断程序越短越好,最好控制在10个网络以内。
4.5 程序架构的避坑指南
做架构设计这么多年,我总结了几条血泪教训:
- 别用全局变量满天飞:子程序之间用接口参数传递数据,别图省事用M点。否则后期维护就是噩梦。
- 注意调用顺序:先读输入,再处理逻辑,最后写输出。这个顺序别搞反了。
- 预留扩展接口:设计时留几个空的子程序调用位置。项目后期加功能时你会感谢自己的。
- 命名要规范:子程序名用英文缩写+功能描述。比如
FC_ConvBelt比FC1好一万倍。
我记得有个项目,客户要求三天内完成程序修改。因为前期架构清晰,我直接在预留接口里加了两个子程序,半天搞定。要是当初乱写,估计得重写整个程序。
4.6 一个完整的架构示例
最后,给你看一个我常用的程序框架。这是西门子博途环境下的结构:
// 主程序 OB1
Network 1: 系统初始化
CALL "FC_Init" (FirstScan := TRUE)
Network 2: 读取输入信号
CALL "FC_InputRead" (CycleCount := #CycleCount)
Network 3: 核心控制逻辑
CALL "FC_MotorCtrl"
CALL "FC_ValveCtrl"
CALL "FC_ConvBelt"
Network 4: 故障处理
CALL "FC_AlarmCheck"
Network 5: 输出刷新
CALL "FC_OutputWrite"
// 中断程序 OB40(硬件中断)
Network 1: 急停处理
#EmergencyStop := TRUE
CALL "FC_StopAllOutputs"
这个结构我用了快十年,从西门子S7-300到1200/1500,基本没大改过。你拿去用,根据项目规模调整子程序数量就行。
嗯,程序架构这事,说白了就是“先想清楚再动手”。别急着写代码,花半小时画个结构图,后面能省你三天调试时间。这个道理,我是吃了不少亏才明白的。