plc循环程序怎么写-PLC 循环程序编写方法详解
从基础原理到实战技巧,全面解析PLC循环程序的核心逻辑结构、扫描周期机制、条件判断设计、延时控制策略与调试优化方法,助您快速掌握工业自动化编程关键技能,编写稳定、高效、可维护的PLC程序。
plc循环程序怎么写?先弄清基本概念
要真正掌握“plc循环程序怎么写”,首先要理解PLC(可编程逻辑控制器)的工作机制。PLC不是像PC那样按顺序执行整段代码,而是通过“扫描周期”(Scan Cycle)循环执行——即依次完成输入采样、程序执行、输出刷新三个阶段,周而复始。
如果在程序中错误地使用“死循环”(如 While/WEND、FOR/NEXT 或未加退出条件的跳转),会导致PLC卡在某个逻辑块中,无法完成完整的扫描周期,从而引发输入信号丢失、输出响应延迟甚至系统死机。
▶ PLC运行三要素
- 输入采样:读取所有I/O点状态到输入映像区
- 程序执行:按顺序扫描用户程序(从上到下,从左到右)
- 输出刷新:将输出映像区内容写入物理输出端口
▶ 循环 ≠ 死循环
“循环程序”指逻辑结构上可重复执行某段功能块(如PID、数据采集),但必须确保每个扫描周期内能退出并继续后续扫描——这是编写合格循环程序的黄金法则。
▶ 避免常见误区
- ❌ 在主程序中使用无限循环指令
- ❌ 在中断程序中嵌套长延时
- ❌ 忽略变量初始化导致上电异常
循环程序 ≠ 死循环!它应是结构化、模块化、有退出条件的功能块封装,确保每个扫描周期内能完整执行并及时响应外部信号。
扫描周期是核心:PLC不会“同时”做两件事
想象PLC就像一个勤快但节奏固定的搬运工——它每秒钟只“心跳”几十到几百次(取决于型号和负载),每次心跳中,它只做三件事:采样输入 → 执行程序 → 刷新输出。
如果程序中某个逻辑块卡住(如等待某个永远不满足的条件),PLC就无法完成后续步骤,造成输入信号“被忽略”,输出动作延迟甚至错误触发。
✅ 正常扫描周期(每周期约5~50ms)
PLC将所有输入点(X0~X15)当前电压状态读入内存映像区,后续程序操作的是这份“快照”,而非实时硬件信号。
从首行开始逐行扫描用户程序(如梯形图),根据输入映像区状态计算中间变量与输出条件。
将输出映像区(Y0~Y15)的计算结果写入物理继电器/晶体管模块,驱动外部设备。
整个周期循环往复,PLC始终处于“边读边算边写”的节奏中。
⚠️ 卡顿场景分析(程序卡死导致)
WHILE X1 = ON
OUT Y0
END_WHILE
OUT Y1
问题:当X1为ON时,程序进入无限循环,始终不执行OUT Y1,导致Y1无法响应;同时输入X0状态未被更新(因未完成完整扫描),系统“失聪”。
解决方案:用“状态机”代替死循环——将条件判断与动作分离,利用标志位触发单次动作,避免阻塞扫描流程。
? 循环结构优化建议
- 用事件驱动代替轮询:如用上升沿检测(P_X0)触发动作,而非持续判断X0状态
- 分时调度:将不同功能模块分配到不同扫描周期执行(如用计数器每10周期执行一次数据采集)
- 模块化编程:将循环逻辑封装为子程序(SUB),主程序仅调用并传参,提升可维护性
OUT M0 // 置位标志位
LD M0 // 标志位为ON时执行动作
OUT Y0 // 启动泵
LD T0 // 定时器超时后复位
RST M0
条件逻辑设计:别让代码变成“天书”
很多新手喜欢用层层嵌套的IF-THEN逻辑,比如:
IF (T<0 AND H>80) THEN START_DEHUMIDIFIER
问题在于:一旦条件复杂化(如加入“压力>0.5MPa且电机电流<10A且无故障报警”),代码会迅速膨胀为难以维护的“意大利面式逻辑”。PLC虽能执行,但调试时如坠五里雾中。
拆解复杂条件
将复合条件拆分为多个中间变量(M寄存器),每一步逻辑清晰可查:
LT T0, 0
ST M10 // M10=1 表示温度<0℃
LD H0
GT H0, 80
ST M11 // M11=1 表示湿度>80%
LD M10
AND M11
OUT Y2 // 同时满足时启动除湿机
善用逻辑块(Function Block)
现代PLC支持结构化文本(ST)或功能块编程。将常用逻辑封装为FB(如“水位控制FB”),主程序仅调用并传入参数(水位设定值、当前值、输出口),大幅提升复用性与可读性。
避免“伪循环”陷阱
例如:用定时器模拟延时循环——错误写法是“每100ms清零计数器重计”,正确做法是使用“脉冲累积型定时器”或“计数器+复位逻辑”,避免循环重置导致时间漂移。
需求:水位低于L1时启动泵,高于L2时停止,中间区间保持原状态。
❌ 错误写法(持续输出导致抖动):
IF 水位 < L1 THEN 启动泵(持续ON)
✅ 正确写法(带记忆的单次触发):
LD 水位 < L1
AND NOT 泵运行中
OUT 泵启动信号
LD 泵运行中
AND 水位 > L2
RST 泵启动信号
关键:用“启动信号”作为触发条件,而非持续输出,避免PLC反复执行无效动作,节省CPU资源。
定时器与延时控制:别让PLC“喘不过气”
延时是PLC编程中的高频需求,但实现方式直接影响程序健壮性。许多初学者习惯用“计数器累加扫描周期”来模拟延时,却忽略了扫描周期不稳定的现实——当程序复杂时,周期可能从5ms跳到20ms,导致延时严重偏差。
主流PLC定时器类型
| 类型 | 特点 | 适用场景 |
|---|---|---|
| TON(接通延时) | 输入ON后开始计时,超时后输出ON | 启动延时、停机延时 |
| TOF(断开延时) | 输入OFF后开始计时,超时后输出OFF | 电机停机缓停 |
| TP(脉冲) | 输入ON时输出固定时长脉冲 | 单次触发、报警提示 |
延时控制实用技巧
- 优先使用硬件定时器:如三菱FX系列的T0~T245,欧姆龙CP1的TIM,它们独立于CPU运行,精度高(±0.1%),不受程序扫描影响
- 避免嵌套定时器:定时器内部再嵌套定时器,易导致计时漂移
- 用“延时复位”代替“延时置位”:例如停机时,用TOF让电机缓停5秒;若用TON延时启动,易因误触发导致重启
需求:按下启动按钮后,电机延时2秒启动;按下停止按钮后,电机延时5秒停机。
LD START_BTN
TON T1, 2000 // 2秒延时
LD T1
OUT MOTOR_RUN
// 停机延时(TOF)
LD STOP_BTN
TOF T2, 5000 // 5秒延时
LD T2
RST MOTOR_RUN
若变量未初始化(如计数器CNT未清零),上电瞬间可能残留上次运行的值,导致逻辑误判。务必在程序开头加入初始化段:
LD M8002 // 仅首次扫描ON
RST C0 // 复位所有计数器
RST T0 // 复位定时器
RST M100 // 复位中间标志位
程序可读性优化:让同事接手时不再骂娘
再完美的程序,如果无法被他人理解,终将沦为“遗产代码”。PLC编程虽是技术活,但更是沟通艺术——你的注释和命名,就是给未来自己的说明书。
命名规范
- 用有意义的名称:如
WATER_PUMP_START代替M0 - 避免缩写歧义:如“ST”可能是“Start”或“Status”,建议用全称
PUMP_STATE - 模块化命名:子程序名与功能一致,如
SUB_PID_CONTROL
注释黄金法则
注释应解释“为什么”,而非“是什么”:
// 因停机时若立即断电,电机惯性可能引发水锤
// 延时5秒让水流平稳停止,保护管道
TOF T2, 5000
分段与注释块
用分隔注释块划分逻辑模块:
// 模块1:水位采集与滤波
// 模块2:泵启停控制逻辑
// 模块3:故障检测与报警
// =================================
原程序:所有逻辑写在MAIN中,变量名全为M1~M50,无注释。
优化后:拆分为SENSOR_READ、SEALING_CTRL、ERROR_LOG三个子程序,变量名带前缀(如S_表示传感器状态,C_表示控制信号),关键步骤添加中文注释。
结果:故障排查时间从2小时缩短至15分钟,新员工培训周期从1周降至2天。
测试与调试:别急着上机!先在软件里跑一遍
%的PLC现场故障,源于未充分测试。务必在编程软件中完成以下步骤:
用软件的“语法检查”功能排除拼写错误、指令冲突;检查所有输出是否被驱动(如Y0未被任何条件置ON)。
强制输入信号(如强制X0=ON),观察中间变量与输出是否按预期变化;用“监视表”实时跟踪关键变量(如M10、T0值)。
测试极端条件:如输入信号抖动、电源波动、同时多个信号变化——确保程序不崩溃、不误动作。
断电后重新上电,检查初始化逻辑是否正确执行(如计数器清零、输出默认状态)。
- 输出不动作?→ 检查输出端子电压、PLC输出模块指示灯、程序中是否被RST复位
- 信号延迟?→ 检查扫描周期是否过长(程序优化)、输入滤波时间是否过长
- 随机故障?→ 检查接地是否良好、抗干扰措施(如继电器线圈加续流二极管)
- 上电误动作?→ 检查变量初始化段、默认输出状态设置