一、P1:SFC 原生「步激活上升沿脉冲」
P1 = Pulse(Rising Edge):该动作仅在本步刚激活(0→1)的那一个扫描周期执行一次,不需要自己写 ONS、不需要额外存储位,专门解决 “进入这一步瞬间执行一次” 的需求
N:默认,步激活期间每个扫描周期都执行
P1:进入步瞬间触发一次脉冲
P0:退出步瞬间触发一次
使用场景:进入该步时,只执行一次:复位计数器、写入参数、触发一次伺服启动、记录一次时间戳 ,不适合:外部传感器、按钮的上升沿(外部信号沿,不是步激活沿)
操作:在 Step 里面添加 Action → 限定符 Qualifier 选择 P1,动作内部写你要执行的逻辑(MOV、RES、MSG、G 指令等)
示例:Step_RecipeStart,动作 Recipe_Init,限定 P1;一旦切到 Step_RecipeStart,Recipe_Init 只跑一次,之后哪怕一直停在这一步,不会重复执行。
注意:P1 是步激活的边沿,不是你外部信号的边沿!很多人混淆这个。
二、外部信号的上升沿(传感器、按钮、到位信号):ONS / OSR
如果需求是:在当前步激活的前提下,等待某个外部信号从 0→1,触发一次动作(不是进步瞬间),用 ONS 或者 OSR
ONS(One Shot):梯级条件由假变真,输出一个扫描周期 ON;最常用,自带一个独立的 Storage Bit(存储位),每个 ONS 必须分配独立 BOOL 存储标签,不能共用
OSR(One Shot Rising):功能块风格上升沿,CLK 输入,Q 输出脉冲,同样需要背景存储位
典型梯形图写法
Step_Active AND Sensor_In → OSR(StorageBit, PulseTag)
逻辑含义:只有当前步是激活的前提下,Sensor_In 产生上升沿,才输出一次脉冲。
重点大坑
ONS/OSR 的存储位不能放在 SFC 局部临时变量,必须全局 / 程序级静态 TAG;SFC 步不激活时,程序不扫描这段逻辑,存储位状态不会刷新,等下次进步时,会出现上电误触发、漏触发、随机触发
不要把 ONS 放在 P1 动作里面叠加使用:P1 只跑一个周期,很容易错过外部信号的沿,沿捕捉失败
步循环跳转、回退、并行分支的时候,存储位状态不会自动清零,需要在合适位置 RES 复位存储位
OSR 结构化文本写法
OSR_1(CLK := Step_Active AND Sensor_In);
IF OSR_1.Q THEN
// 一次性动作:计数、触发输出
END_IF;
三、两种边沿场景一句话区分
进入这一步就执行一次 → 直接用 P1 限定符(步激活上升沿,SFC 原生)
停在这一步里面,等外部信号来了才触发一次 → N 动作 + ONS/OSR(外部信号上升沿)
四、高频故障现象与排查
每次进入 SFC 步,沿指令偶尔不触发原因:步激活时间很短,外部信号的上升沿刚好落在步未激活窗口;或者 ONS 存储位没有复位、共用存储位。 解决:独立存储位,退出步时 RES 复位存储 bit;优先 P1 如果只是进步动作。
停留在该步不动,外部信号反复通断,只触发一次,之后再也不触发原因:OSR 的存储位已经锁存状态,信号保持 ON 时不会再出沿;信号先 OFF 再 ON 才会再次产生上升沿,这是沿指令本身特性,不是 SFC 问题。
SFC 来回跳转、循环时,ONS 随机误触发原因:SFC 步不激活时该逻辑段不扫描,存储位状态停滞;再次激活时,能流条件已经为 TRUE,ONS 检测到 “从假变真” 误脉冲。 解决:退出该步的时候,RES 复位这个 ONS 对应的存储位。
并行分支 SFC 里面用 ONS并行多个 Step 同时激活,多个 ONS 一定要各自独立存储标签,严禁共用同一个 Storage Bit。
五、推荐规范
进步一次性初始化、赋值、复位 → P1 Action(首选,代码干净,无存储位管理)
步内等待外部信号触发 → N 型 Action + ONS,退出该步时 RES 对应存储位
转移条件(Transition)本身就是电平条件,转移条件自带 0→1 跳转;转移条件本身不需要再加 ONS;如果你需要跳转的瞬间附带执行动作,就在下一步用 P1
补充:Transition 只是负责跳转,Transition 条件上升沿 = 切换到下一步,下一步 P1 动作就是跳转后一次性执行逻辑
六、对比西门子 S7-1200 SFC 区别
西门子 SFC 没有 P1/P0 这种限定符,一般是在步里面直接用 R_TRIG;AB 是把这个 “步激活脉冲” 做成了 SFC 原生限定符 P1,优先用 P1,减少沿指令带来的状态陷阱。


