表格
用途 | 检测单个信号 | 检测逻辑运算结果 |
上升沿 | P触点 | P_TRIG |
下降沿 | N触点 | N_TRIG |
记忆口诀:单信号用触点,复合逻辑用TRIG。P线圈和R_TRIG是"备选方案",需要时再查,不必一开始就全学。
(1)先看下面这段程序,为什么启动按钮启动后,后面的输出一个有输出,一个没有输出。
️ 沿指令最容易踩的坑:暂存位重复
同一个变量,在两个程序段里都要判断上升沿——你以为两次都能抓到跳变,实际第二次抓不到。
为什么?
沿指令判断"有没有跳变"的原理是:拿当前状态和上一扫描周期的状态做对比。上一周期的状态存在哪?暂存位。
问题出在这里:
根本原因: 程序段1执行完后,把当前状态写入了暂存位M0.0。等程序段2再执行时,暂存位已经是1了,和当前值一样,沿指令认为"没有变化",上升沿消失。
正确做法:每个沿指令用不同的暂存位
程序段1:UserDB.Start ──┤P├── 暂存位 M0.0 ← 各用各的
程序段2:UserDB.Start ──┤P├── 暂存位 M0.1 ← 各用各的
这样两个程序段各自记录各自的"上一周期状态",互不干扰,两次上升沿都能正确触发。
更省心的做法:用R_TRIG代替P触点
R_TRIG自动分配背景数据块来存储上一周期状态,不用你手动指定暂存位,从根本上杜绝重复问题:
程序段1:UserDB.Start ──→ R_TRIG(DB1)──→ 输出1
程序段2:UserDB.Start ──→ R_TRIG(DB2)──→ 输出2
每个实例自动管理各自的暂存状态,不会冲突
规则很简单:一个沿指令,一个独立的暂存位。嫌手动分配麻烦,就用R_TRIG让系统帮你管,省心不出错。
(2)RLO上升沿——几个条件组合后的"一瞬间"
前面讲的P触点检测的是单个变量的跳变,但很多时候你需要判断的是几个条件组合之后的结果——
比如:手动模式 AND 物料到达 AND 设备未故障 → 这三个条件同时满足的那一下,触发一次动作。
如果用P触点,你得先把三个条件的运算结果存到一个中间变量,再对这个变量做上升沿——多一步,多一个变量,多一个暂存位。
用RLO上升沿指令(-(P)- 线圈或 P_TRIG),直接在逻辑运算后面加一个沿检测,一步搞定:
三个条件串联的逻辑运算结果,从0变1的那一瞬间 → 导通1个扫描周期
对比两种写法:
表格
写法 | 步骤 | 需要中间变量 | 暂存位管理 |
P触点 | 逻辑运算→存中间变量→对中间变量做上升沿 | 需要 | 手动分配 |
RLO沿 | 逻辑运算后直接加-(P)- | 不需要 | 手动分配或自动管理 |
选型判断:单个信号跳变 → P触点,简单直接;多个条件组合后的跳变 → RLO沿,少绕一步。
(3)SCL中怎么用沿指令?
梯形图里沿指令是触点/线圈,拖上去就能用。但SCL是文本编程,没有触点和线圈——怎么检测沿?
答案是:用 R_TRIG / F_TRIG 功能块。
SCL上升沿写法
三行代码,拆开看:
表格
行 | 干的事 | 说明 |
声明FB实例 | 创建一个R_TRIG实例 | 系统自动生成背景数据块,帮你管理上一周期状态 |
调用FB | CLK接入要检测的变量 | 变量从0变1时触发 |
取Q输出 | Q就是上升沿信号 | 只通1个扫描周期,和梯形图中的P触点效果一样 |
SCL下降沿写法
和梯形图的对应关系
表格
梯形图 | SCL | 效果 |
| ┤P├ 触点 | R_TRIG | 上升沿,通1个扫描周期 |
| ┤N├ 触点 | F_TRIG | 下降沿,通1个扫描周期 |
SCL中只能用R_TRIG/F_TRIG,没有P触点、P线圈、P_TRIG这些写法。好消息是——R_TRIG/F_TRIG自动管理背景数据块,不存在暂存位重复的问题,反而比梯形图更省心。
手写沿检测——理解原理的最好方式
如果不想用R_TRIG/F_TRIG功能块,也可以根据沿指令的原理自己写——本质上就是本次状态和上次状态做对比。
上升沿手写逻辑
核心思路:本次=1 AND 上次=0 → 有上升沿
拆解执行过程:
表格
扫描周期 | 本次Start | 上次Start_Last | 本次=1 AND 上次=0 | 上升沿 |
N | 0 | 0 | 0 AND 1 = 否 | 无 |
N+1 | 1 | 0 | 1 AND 1 = 是 | 抓到了 |
N+2 | 1 | 1 | 1 AND 0 = 否 | 无(不会重复触发) |
N+3 | 0 | 1 | 0 AND 0 = 否 | 无 |
最后一行千万别忘了——把本次状态写入上次状态,否则下次对比用的还是旧数据,沿检测就废了。
下降沿手写逻辑
核心思路反过来:本次=0 AND 上次=1 → 有下降沿
两种写法对比
表格
对比项 | R_TRIG/F_TRIG | 手写沿检测 |
代码量 | 少,3行搞定 | 多,IF-ELSE+赋值 |
暂存位管理 | 自动(背景数据块) | 手动(自己定义_Last变量) |
暂存位冲突风险 | 无 | 有——同一变量多处检测时,_Last变量必须各用各的 |
可读性 | 一看就知道是沿检测 | 需要看逻辑才能理解 |
适合场景 | 日常编程,省心 | 学习理解原理,或功能块不可用的场合 |
实际项目中推荐用R_TRIG/F_TRIG,少出错、好维护。手写沿检测的价值在于理解原理——你把这段代码搞懂了,沿指令的"暂存位重复坑"也就彻底明白了,因为本质就是同一回事。
变量说明——数组方式管理多个沿检测
上面手写沿检测用的是单个变量,如果项目里有多个信号要检测,可以用数组统一管理,变量命名更有规律,不容易乱:
上升沿(数组索引[1])
表格
变量 | 类型 | 说明 |
| UserDB".Start_P[1] | Bool | 上升沿输出信号——检测到跳变时为TRUE,只通1个扫描周期 |
| UserDB".Start[1] | Bool | 本次状态——当前扫描周期信号的实际值 |
| UserDB".LastStatusBit[1] | Bool | 上次状态暂存——上一个扫描周期的信号值 |
下降沿(数组索引[2])
表格
变量 | 类型 | 说明 |
| UserDB".Start_N[2] | Bool | 下降沿输出信号——检测到跳变时为TRUE |
| UserDB".Start[2] | Bool | 本次状态——当前扫描周期信号的实际值 |
| UserDB".LastStatusBit[2] | Bool | 上次状态暂存——上一个扫描周期的信号值 |
三个变量的关系
数组索引[1]和[2]只是编号,不是固定的——你可以用[1]检测信号A,[2]检测信号B,[3]检测信号C……每组三个变量用同一个索引,管理起来不会乱。但注意:同一个索引的三组变量必须一一对应,别把[1]的本次状态和[2]的暂存位混搭,沿检测直接失效。
沿指令三句总结
① 选对指令:单信号用触点,复合逻辑用TRIG
表格
场景 | 梯形图 | SCL |
检测单个变量的沿 | P触点 / N触点 | R_TRIG / F_TRIG |
检测逻辑运算结果的沿 | -(P)- 线圈 / P_TRIG | R_TRIG(CLK接逻辑运算) |
不管是单个触点还是逻辑组合,R_TRIG/F_TRIG都能搞定——区别只是CLK端接的是单个变量还是逻辑表达式。但能选对更合适的那种,程序更简洁。
② 暂存位绝不重复——这是沿指令第一铁律
同一个变量,两个程序段都要检测沿?暂存位必须各用各的。重复了,后面的沿信号直接失效,查bug查到怀疑人生。
用R_TRIG/F_TRIG可以自动管理,从根本上避免这个问题。
③ SCL手写沿检测:理解原理的练手,日常用FB省心
手写IF-ELSE + _Last赋值,帮你真正搞懂沿指令的底层逻辑。但实际项目用R_TRIG/F_TRIG——代码少、不出错、好维护。
一句话记住沿指令:抓变化、只一瞬、暂存位不重复
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!