4.3 程序控制指令
本节将介绍PLC的程序流程控制指令
学习目标
- 掌握程序控制指令的类型
- 理解跳转和循环的实现
- 能够优化程序结构
1. 程序控制概述
1.1 什么是程序控制
程序控制指令用于改变程序的执行顺序,实现条件执行、循环、跳转等功能。
PLC程序执行方式:
正常执行: 有程序控制:
┌───────┐ ┌───────┐
│Network1│ │Network1│
├───────┤ ├───────┤
│Network2│ │Network2│──┐ 跳转
├───────┤ ├───────┤ │
│Network3│ │Network3│←─┤
├───────┤ ├───────┤ │
│Network4│ │Network4│──┘
├───────┤ ├───────┤
│ END │ │ END │
└───────┘ └───────┘
顺序执行 可跳过某些程序段1.2 程序控制指令分类
程序控制指令类型:
┌─────────────────────────────────────────────────────┐
│ 程序控制指令 │
├────────────┬────────────┬────────────┬──────────────┤
│ 跳转类 │ 循环类 │ 条件类 │ 结束类 │
├────────────┼────────────┼────────────┼──────────────┤
│ · JMP跳转 │ · FOR循环 │ · IF-ELSE │ · END结束 │
│ · LBL标号 │ · WHILE │ · CASE选择 │ · RET返回 │
│ · CJ条件跳 │ · REPEAT │ · MC/MCR │ · STOP停止 │
└────────────┴────────────┴────────────┴──────────────┘1.3 程序控制指令通用格式
| 功能 | 通用指令 | 说明 |
|---|---|---|
| 跳转 | JMP/CJ | 无条件/条件跳转 |
| 标号 | LABEL/P | 跳转目标位置 |
| FOR循环 | FOR/NEXT | 已知次数循环 |
| 条件执行 | IF/ELSE | 分支执行 |
| 主控 | MC/MCR | 控制程序段执行 |
2. 跳转指令(JMP/CJ)
2.1 跳转原理
跳转指令工作原理:
条件成立?
│
▼
┌─────────────┐
│ JMP 跳转 │──────────┐
└─────────────┘ │
│ │
▼ │
┌─────────────┐ │
│ 被跳过的 │ │ 跳转
│ 程序段 │ │
└─────────────┘ │
│ │
▼ │
┌─────────────┐ │
│ 标号(目标)│←─────────┘
└─────────────┘
跳转发生时,中间程序不执行2.2 跳转指令梯形图
【梯形图】
┌──────────┐
条件 ─────┤ JMP │
│ │
│ 标号1 │
└──────────┘
... (被跳过的程序段)
LABEL: 标号1
... (跳转目标)
【逻辑表达】
IF 条件 THEN
GOTO 标号1;
END_IF;
// 程序段...
标号1:
// 继续执行2.3 条件跳转示例
【梯形图】
跳转条件
───┤├───────[CJ 标号10]─── // 条件跳转到标号10
// 中间程序(条件=ON时跳过)
输入1
───┤├───────( 输出0 )───
输入2
───┤├───────( 输出1 )───
[标号10] // 标号10
输入3
───┤├───────( 输出2 )───
【说明】
· 跳转条件=ON时,跳转到标号10,跳过中间程序
· 跳转条件=OFF时,正常执行所有程序
· 可用于条件性地禁用某段程序2.4 跳转注意事项
跳转使用注意事项:
【1. 输出状态保持】
被跳过的程序中的输出保持原状态
不会自动变为OFF
【2. 定时器/计数器】
被跳过时定时器停止计时
计数器保持当前值
【3. 不能向前跳转】
X0
───┤├───────[CJ P5]───
[P10]
...
[P5] // 必须在CJ之后
【4. 不能跳入FOR循环内部】
禁止从循环外部跳转到循环内部3. 条件执行(MC/MCR)
3.1 主控指令概念
主控指令(Master Control)可以使一段程序在条件满足时执行,条件不满足时跳过。
主控指令原理:
X0
───┤├───────[MC N0 M100]─── // 开启主控
X1 // 受主控影响
───┤├───────( Y0 )───
X2 // 受主控影响
───┤├───────( Y1 )───
────────────[MCR N0]─── // 关闭主控
X0=ON时:正常执行Y0、Y1程序
X0=OFF时:Y0、Y1强制OFF3.2 主控指令梯形图
【梯形图】
主控条件
───┤├───────[MC N0 主控继]─── // 主控开始
输入1
───┤├───────( 输出0 )───
输入2
───┤├───────( 输出1 )───
[MCR N0]─── // 主控结束
【参数说明】
· N0:嵌套层号(N0-N7)
· 主控继:主控继电器
【嵌套使用】
外层条件
───┤├───────[MC N0 主控0]───
内层条件
───┤├───────[MC N1 主控1]─── // 嵌套
输入
───┤├───────( 输出 )───
[MCR N1]─── // 关闭N1
[MCR N0]─── // 关闭N03.3 条件执行逻辑表达
条件执行逻辑表达:
【IF语句】
IF 条件 THEN
// 条件为真时执行
输出0 := TRUE;
ELSIF 其他条件 THEN
// 其他条件
输出1 := TRUE;
ELSE
// 否则
输出0 := FALSE;
输出1 := FALSE;
END_IF;
【CASE语句】
CASE 选择值 OF
1: 输出0 := TRUE;
2: 输出1 := TRUE;
3: 输出2 := TRUE;
ELSE
// 默认
输出7 := TRUE;
END_CASE;4. FOR循环
4.1 FOR循环原理
FOR循环执行流程:
┌──────────────────────┐
│ 初始化循环变量 │
│ i = 起始值 │
└──────────────────────┘
│
▼
┌──────────────────────┐
│ i ≤ 结束值? │──否──→ 退出循环
└──────────────────────┘
│是
▼
┌──────────────────────┐
│ 执行循环体 │
└──────────────────────┘
│
▼
┌──────────────────────┐
│ i = i + 步长 │
└──────────────────────┘
│
└─────────→ 返回判断4.2 FOR循环逻辑表达
【逻辑表达】
FOR i := 1 TO 10 DO
// 循环体
数据[i] := i × 2;
END_FOR;
【带步长】
FOR i := 0 TO 100 BY 10 DO
// i = 0, 10, 20, ... 100
处理(i);
END_FOR;
【倒序循环】
FOR i := 10 TO 1 BY -1 DO
// i = 10, 9, 8, ... 1
数据[i] := 0;
END_FOR;4.3 FOR循环梯形图
【梯形图】
条件
───┤├───────[FOR 10]─── // 循环10次
// 循环体
始终
───┤├───────[ADD 数据 1 数据]── // 数据累加
[NEXT]─── // 循环结束
【说明】
· FOR 10:循环10次
· NEXT:返回for
· 循环变量自动管理
【嵌套循环】
条件
───┤├───────[FOR 5]─── // 外层循环5次
[FOR 10]─── // 内层循环10次
// 循环体(执行5×10=50次)
[NEXT]─── // 内层结束
[NEXT]─── // 外层结束4.4 数组操作示例
示例:数组求和
【逻辑表达】
累加和 := 0;
FOR i := 0 TO 9 DO
累加和 := 累加和 + 数据数组[i];
END_FOR;
平均值 := 累加和 / 10;
【梯形图】
// 初始化
条件
───┤├───────[MOV 0 累加和]─── // 清零和
[MOV 0 索引]─── // 清零变址
// 循环求和
始终
───┤├───────[FOR 10]───
[ADD 数据[索引] 累加和 累加和]── // 累加
[INC 索引]─── // 变址+1
[NEXT]───
// 求平均
始终
───┤├───────[DIV 累加和 10 平均值]──5. WHILE循环
5.1 WHILE循环原理
WHILE循环执行流程:
┌──────────────────────┐
│ 条件为真? │──否──→ 退出循环
└──────────────────────┘
│是
▼
┌──────────────────────┐
│ 执行循环体 │
└──────────────────────┘
│
└─────────→ 返回判断
特点:先判断,后执行
可能一次都不执行5.2 WHILE循环逻辑表达
【逻辑表达】
// 查找第一个非零元素
i := 0;
WHILE (i < 10) AND (数据[i] = 0) DO
i := i + 1;
END_WHILE;
// 此时i为第一个非零元素的索引
// 或i=10表示全为零
【注意事项】
· 必须确保循环能够结束
· 避免死循环
· 设置最大循环次数保护5.3 REPEAT循环
REPEAT循环(后判断):
REPEAT
// 循环体
i := i + 1;
UNTIL i >= 10; // 直到条件为真退出
END_REPEAT;
特点:先执行,后判断
至少执行一次6. 程序结束指令
6.1 END指令
END指令:结束程序扫描
【梯形图】
始终
───┤├───────[END]─── // 程序结束
【条件END】
条件
───┤├───────[FEND]─── // 条件结束
FEND后的程序不执行(用于子程序等)6.2 STOP指令
STOP指令:停止PLC运行
【梯形图】
紧急停止 // 紧急停止按钮
───┤├───────[STOP]───
【注意】
· 使PLC进入STOP模式
· 需要手动重新启动
· 用于严重故障处理6.3 看门狗刷新
看门狗(WDT)刷新:
用于长循环时防止看门狗超时
【梯形图】
始终
───┤├───────[FOR 1000]───
[WDT]─── // 刷新看门狗
// 长时间处理
[NEXT]───
【应用场景】
· 大量数据处理
· 复杂计算循环
· 通信等待7. 应用实例
7.1 状态机实现
使用CASE实现状态机:
变量定义:
当前状态 : 整数 := 0;
CASE 当前状态 OF
0: // 初始状态
IF 启动按钮 THEN
当前状态 := 1;
END_IF;
1: // 运行状态
电机 := TRUE;
IF 传感器到达 THEN
当前状态 := 2;
END_IF;
2: // 完成状态
电机 := FALSE;
IF 复位按钮 THEN
当前状态 := 0;
END_IF;
ELSE
当前状态 := 0; // 异常恢复
END_CASE;7.2 查表程序
根据输入值查找对应输出:
【梯形图】
// 表格数据在表格区[0..9]
// 输入为查找值,输出为查找结果
始终
───┤├───────[MOV 0 索引]─── // 索引清零
始终
───┤├───────[FOR 10]───
[查找值==表格区[索引]]
──────┤├──────[MOV 索引 查找结果]── // 找到,存索引
[BREAK]─── // 退出循环
[INC 索引]───
[NEXT]───7.3 模式切换
根据选择开关切换工作模式:
手动选择
───┤├───────[CJ 手动模式]─── // 手动模式
自动选择
───┤├───────[CJ 自动模式]─── // 自动模式
回原点选择
───┤├───────[CJ 回原点]─── // 回原点
[手动模式] // 手动模式程序
手动前进
───┤├───────( 电机前进 )───
手动后退
───┤├───────( 电机后退 )───
[CJ 结束点]─── // 跳到结束
[自动模式] // 自动模式程序
// 自动控制逻辑
[CJ 结束点]───
[回原点] // 回原点程序
// 回原点逻辑
[结束点] // 程序结束点本节小结
程序控制指令要点:
┌────────────────────────────────────────────────────┐
│ 跳转指令 │
│ · JMP/CJ:条件跳转到指定标号 │
│ · 被跳过的输出保持原状态 │
│ · 不能向前跳转、不能跳入循环 │
├────────────────────────────────────────────────────┤
│ 主控指令 │
│ · MC/MCR:控制程序段执行 │
│ · 可嵌套使用 │
│ · 便于条件控制大段程序 │
├────────────────────────────────────────────────────┤
│ 循环指令 │
│ · FOR:已知循环次数 │
│ · WHILE:条件循环 │
│ · 注意避免死循环和看门狗超时 │
├────────────────────────────────────────────────────┤
│ 结束指令 │
│ · END/FEND:程序结束 │
│ · STOP:停止PLC运行 │
│ · WDT:看门狗刷新 │
└────────────────────────────────────────────────────┘练习题
- 说明CJ跳转指令对被跳过程序段的影响。
- 编写FOR循环实现D0-D9清零。
- 使用MC/MCR实现运行模式选择控制。
- 设计一个3状态的状态机程序。