『7x24小时有问必答』

结构化编程与状态机设计
──────────────────────────────────────────────────
一、引言:从"面条代码"到结构化编程
某工程师接手一条产线的PLC程序,打开后发现:
·3000+  行代码全部写在OB1(主循环组织块)
·没有FC/FB,全部是network 1~network 50
·变量名全是I0.0/Q0.0/DB1.DBB0,没有符号表
·逻辑跳转(JMP)满天飞,完全看不懂执行顺序
这就是典型的"面条代码"——所有逻辑搅在一起,维护难度堪比"解乱麻"
本文将从结构化编程和状态机设计两个维度,带你写出"可读、可维护、可复用"PLC程序。
──────────────────────────────────────────────────
二、结构化编程基础:FC/FB/DB的合理使用
2.1 FC vs FB:什么时候用哪个?
FCFunction)和FBFunction Block)是PLC结构化编程的核心,但很多人分不清"什么时候用FC,什么时候用FB"
FC vs FB  选择决策树】
问题1:是否需要记忆状态?(是  → FB;否  → FC
问题2:是否需要多次实例化?(是  → FB;否  → FC
问题3:逻辑是否复杂?(是  → FB/FC +  多个Network;否  →  直接写在OB1
通用规则:
- FC:用于"无状态"的逻辑(如计算、转换、简单控制)
- FB:用于"有状态"的逻辑(如电机控制、阀门控制、PID调节)
- OB1:只写"调用逻辑",不写"实现逻辑"
2.2 FC编程实战:电机启动逻辑
# FC1:  电机启动逻辑(无状态)
#输入:Start_Button (BOOL), Stop_Button (BOOL), Fault (BOOL)
#输出:Motor_Run (BOOL)
Network 1:  启动逻辑
START: Start_Button AND NOT Stop_Button AND NOT Fault
Motor_Run: = START OR (Motor_Run AND NOT Stop_Button AND NOT Fault)
#调用方式(在OB1中)
CALL FC1 (Start_Button := I0.0, Stop_Button := I0.1, Fault := I0.2, Motor_Run := Q0.0)
2.3 FB编程实战:电机控制块(有状态)
# FB1:  电机控制块(有状态,需要记忆运行时间)
#输入:Start (BOOL), Stop (BOOL), Fault (BOOL)
#输出:Run (BOOL), Run_Time (TIME)
#静态变量(存储在Instance DB中)
# Static: Run_Start_Time (TIME)
Network 1:  启动逻辑
Start AND NOT Stop AND NOT Fault -> Run
Network 2:  运行时间累计
IF Run THEN Run_Time := Run_Time + (NOW() - Run_Start_Time); Run_Start_Time := NOW(); END_IF
#调用方式(需要分配Instance DB
CALL FB1, DB10 (Start := I0.0, Stop := I0.1, Fault := I0.2, Run := Q0.0, Run_Time := MD0)
2.4 DB的合理使用:全局DB vs  实例DB
·全局DBGlobal DB):用于存储"FC/FB"共享的数据(如工艺参数、系统状态)
·实例DBInstance DB):每个FB调用时自动生成,存储该FB"私有数据"
·推荐规则:
·工艺参数  →  全局DB(方便HMI/SCADA访问)
·设备状态  →  实例DB(每个设备独立)
·临时变量  → FC/FBTEMP区(不存储)
──────────────────────────────────────────────────
三、状态机设计:让程序从"面条"变成"流程图"
3.1  为什么需要状态机?
传统PLC编程的常见问题:
·逻辑分散:设备的"启动运行停止故障"逻辑散落在OB1的各个network
·状态不清:不知道设备当前处于哪个状态,调试时""
·扩展困难:新增状态(如"暂停""清洗")需要大改代码
状态机(State Machine)的核心思想:将设备的所有状态"枚举"出来,然后用"状态转移条件"控制流转。
3.2  状态机设计四步法
·步骤1:枚举所有状态(如:Idle/Running/Fault/Pause
·步骤2:定义状态转移条件(如:Idle → Running,条件=Start_Button
·步骤3:为每个状态编写"进入动作""退出动作"
·步骤4:在主循环中调用状态机(CASE语句)
3.3  实战案例:电机状态机(SCL语言)
# FB10:  电机状态机(SCL语言,推荐用于复杂逻辑)
#状态枚举
TYPE Motor_State : (Idle, Running, Fault, Pause);
#静态变量
Static Current_State : Motor_State := Idle;
Static Fault_Code : INT := 0;
#状态机主逻辑(在OB1中调用)
CASE Current_State OF
  Idle:
  IF Start_Button AND NOT Fault THEN Current_State := Running; END_IF;
  IF Fault THEN Current_State := Fault; END_IF;
  Running:
  Motor_Run := TRUE;
  IF Stop_Button THEN Current_State := Idle; Motor_Run := FALSE; END_IF;
  IF Pause_Button THEN Current_State := Pause; END_IF;
  IF Fault THEN Current_State := Fault; Motor_Run := FALSE; END_IF;
  
  Pause:
  Motor_Run := FALSE;
  IF Start_Button THEN Current_State := Running; END_IF;
  IF Fault THEN Current_State := Fault; END_IF;
  
  Fault:
  Motor_Run := FALSE;
  IF Reset_Button AND NOT Fault THEN Current_State := Idle; END_IF;
END_CASE;
【状态机设计要点】
每个状态的责任要"单一":不要在一个状态里做多件事
状态转移条件要"互斥":避免同时触发多个转移
故障状态要"独立"Fault状态只负责"安全停机+报警",不负责"故障处理"
调试技巧:在HMI上显示Current_State,让操作员"看到"设备状态
──────────────────────────────────────────────────
四、代码复用:建立自己的PLC代码库
很多工程师每次新项目都"从零开始"PLC程序——这是巨大的浪费。
建立代码库的核心价值:
·开发效率提升:新项目直接"拿来就用",开发周期缩短40%
·质量可控:经过多个项目验证的代码,bug率远低于"现场手写"
·知识沉淀:团队经验固化成代码,避免"老师傅离职,经验带走"
4.1  代码库的组织结构
# PLC代码库目录结构(推荐)
PLC_Library/
├── FC/  #  通用FC(无状态)
  ├── FC1_Start_Stop.scl       #  启停逻辑
  ├── FC2_TON.scl                 #  延时接通
  └── FC3_Counter.scl          #  计数器
├── FB/  #  通用FB(有状态)
  ├── FB1_Motor.scl             #  电机控制
  ├── FB2_Valve.scl             #  阀门控制
  └── FB3_PID.scl                # PID调节
├── DB/  #  全局DB模板
  ├── DB1_System.scl           #  系统参数
  └── DB2_Recipe.scl           #  配方数据
└── Project_Template/  #  项目模板(含硬件配置+符号表)
  └── Template.ap18             # TIA Portal模板文件
4.2  代码复用三原则
·原则1:接口标准化——所有FB/FC的输入输出命名要统一(如:Start/Stop/Fault/Run
·原则2:参数可配置——不要写死参数(如延时时间),用Input参数传入
·原则3:注释完整——每个FC/FB都要有"功能说明+调用示例+修改记录"
4.3  实战案例:建立电机控制FB
# FB1_Motor (V1.0) -  电机控制块
#功能:启停控制  +  运行时间累计  +  故障诊断
#输入:Start (BOOL), Stop (BOOL), Fault (BOOL), Reset (BOOL)
#输出:Run (BOOL), Run_Time (TIME), Fault_Code (INT)
#调用示例:
# CALL FB1_Motor, DB10 (Start := I0.0, Stop := I0.1, Fault := I0.2, Reset := I0.3, Run := Q0.0, Run_Time := MD0, Fault_Code := MW10)
#修改记录:
# V1.0 (2025-01-15):  初始版本
# V1.1 (2025-03-20):  增加"Pause"功能
# V1.2 (2025-06-10):  修复"复位后Run_Time清零"bug
──────────────────────────────────────────────────
五、三个真实案例复盘
案例1:状态机让调试时间从3天降至3小时
某包装产线,原有程序是"面条代码",调试时需要"一步步跟踪"才能找到问题,平均调试时间3天。
·问题根因:逻辑分散,状态不清晰,调试时"盲人摸象"
·解决方案:用状态机重构程序(枚举所有状态+CASE语句)
·量化结果:调试时间从3天降至3小时,效率提升80%
·经验公式:调试效率  = 1 /  状态清晰度  ×  代码可读性
案例2:结构化编程让程序可读性提升80%
某水处理项目,原有程序3000+行全部写在OB1,新员工需要2周才能"看懂"程序。
·问题根因:没有结构化,所有逻辑搅在一起
·解决方案:用FC/FB重构,OB1只写"调用逻辑",每个FC/FB不超过50
·量化结果:新员工"看懂"程序的时间从2周降至3天,可读性提升80%
·经验公式:代码可读性  =  结构化程度  ×  注释完整度  ×  命名规范性
案例3:代码复用让新项目开发周期缩短40%
某设备制造商,每个新项目都"从零开始"PLC程序,开发周期平均6周。
·问题根因:没有代码库,重复"造轮子"
·解决方案:建立PLC代码库(电机/阀门/PID/通信等通用模块)
·量化结果:新项目开发周期从6周降至3.5周,缩短40%
·经验公式:开发效率提升  =  代码复用率  ×  代码质量  ×  团队熟练度
──────────────────────────────────────────────────
六、PLC高级编程最佳实践总结
#公式1PLC程序质量
Q_plc =  结构化程度  ×  状态机清晰度  ×  代码复用率  ×  注释完整度
#公式2:调试效率
E_debug = 1 / (状态清晰度  ×  代码可读性)
#公式3:开发效率
E_dev =  代码复用率  × 0.4 +  结构化程度  × 0.3 +  经验积累  × 0.3
#公式4:代码库ROI
ROI_library = (节省的工时  ×  工时单价  -  代码库建设成本) /  代码库建设成本
#经验值:代码库建设投入50万元,第一年回报约150万元(按节省500工时计算)
PLC编程  checklist
结构化:OB1只写调用逻辑,实现逻辑放在FC/FB
状态机:复杂设备用状态机设计,枚举所有状态+转移条件
命名规范:变量名用"动词+名词"(如Start_ButtonMotor_Run
注释完整:每个FC/FB都要有功能说明+调用示例+修改记录
代码复用:建立自己的PLC代码库,新项目直接"拿来就用"
版本管理:用Git管理PLC代码(TIA Portal支持导出源码)
──────────────────────────────────────────────────
七、一句话总结
PLC高级编程  =  结构化  +  状态机  +  代码复用
核心原则:写PLC程序不是为了"能跑",而是为了"能维护、能复用、能传承"
──────────────────────────────────────────────────
八、全文公式总结
#公式1PLC程序质量
Q_plc =  结构化程度  ×  状态机清晰度  ×  代码复用率  ×  注释完整度
#公式2:调试效率
E_debug = 1 / (状态清晰度  ×  代码可读性)
#公式3:开发效率
E_dev =  代码复用率  × 0.4 +  结构化程度  × 0.3 +  经验积累  × 0.3
#公式4:代码库ROI
ROI_library = (节省的工时  ×  工时单价  -  代码库建设成本) /  代码库建设成本
#公式5PLC编程终极目标
目标  =  让新成员在3天内"看懂"你的程序,让10年后的人还能"维护"你的程序
──────────────────────────────────────────────────
——  瓦特与算法

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

上一主题上一主题         下一主题下一主题
QQ手机版小黑屋粤ICP备17165530号

关于我们·投诉举报· 用户帮助· 联系我们 · 本站服务 · 版权声明· 隐私政策 · 投搞指南

法律保护:PLC技术网,plcjs.com,plcjs.net等字样
Copyright 2010-2030. All rights reserved. 


微信公众号二维码 抖音二维码 百家号二维码 今日头条二维码哔哩哔哩二维码