ST上升沿下降沿检测:R_TRIG与F_TRIG功能块在ST中的使用

发布于 2026-03-18 12:13:29 · 浏览 4 次 · 评论 0 条

在结构化文本(ST)编程中,准确捕捉信号的瞬时变化是实现可靠逻辑控制的基础。上升沿(Rising Edge)和下降沿(Falling Edge)检测用于识别布尔变量从 FALSETRUE 或从 TRUEFALSE单次跳变,避免因信号抖动、扫描周期延迟或持续电平导致的重复触发。IEC 61131-3 标准定义了两个标准功能块:R_TRIG(上升沿触发器)和 F_TRIG(下降沿触发器),它们不依赖于具体硬件平台,可在任意支持 ST 的 PLC 编程环境(如 TIA Portal、CODESYS、Unity Pro)中直接调用。


一、R_TRIG 与 F_TRIG 的本质:状态记忆 + 边沿判别

这两个功能块的核心机制完全一致,仅判别条件相反:

  • 它们都内部保存上一个扫描周期的输入值(即 CLK 引脚前一周期的布尔状态);
  • 每次执行时,将当前 CLK 值与缓存的旧值比较;
  • 若满足边沿条件,则将输出 Q 置为 TRUE(仅维持一个扫描周期),同时更新缓存值为当前 CLK

因此,R_TRIGF_TRIG 不是“电平保持型”元件,而是“脉冲生成器”——输出 Q 是宽度等于 PLC 扫描周期的单周期脉冲,必须在后续逻辑中及时捕获(例如驱动置位、计数、启动定时器等),否则下一周期即消失。


二、功能块接口定义与语义说明

两个功能块均采用统一接口规范(符合 IEC 61131-3):

引脚 数据类型 方向 说明
CLK BOOL 输入 待检测边沿的布尔信号源(如按钮、传感器、内部变量)
Q BOOL 输出 边沿发生时为 TRUE,仅持续一个扫描周期
CLKO BOOL 输出 (可选)CLK 的同步缓存副本(部分平台提供,非标准必需)

⚠️ 注意:Q 不是锁存输出,也不具备延时或滤波能力。若需抗抖动,必须在 CLK 输入端前置硬件消抖或软件滤波逻辑(例如用 TON 定时器延时确认稳定电平后再接入 R_TRIG)。


三、ST 中的标准调用语法(无实例化声明)

在 ST 中,功能块调用分为两种方式:匿名调用(推荐)具名实例化。绝大多数场景使用匿名调用,简洁且不易出错。

3.1 匿名调用(最常用)

直接在表达式中调用,无需提前声明变量:

// 检测 StartButton 上升沿,驱动启动脉冲
StartPulse := R_TRIG(CLK := StartButton);

// 检测 StopButton 下降沿(即松开瞬间),触发急停动作
StopRelease := F_TRIG(CLK := StopButton);

✅ 优点:代码紧凑、作用域清晰、无命名冲突风险。
❌ 限制:无法复用同一功能块多次检测不同信号(每次调用均为独立实例)。

3.2 具名实例化(需显式声明)

当需多次复用、或需调试中间状态(如查看缓存值)时使用:

// 在 VAR 块中声明
rStart: R_TRIG;
fStop: F_TRIG;

// 在程序体中调用
rStart(CLK := StartButton);
StartPulse := rStart.Q;

fStop(CLK := StopButton);
StopRelease := fStop.Q;

⚠️ 关键细节:rStartfStop功能块实例变量,其生命周期与所在组织块(OB)一致;每次调用 rStart(...) 会更新其内部状态,因此必须每周期都调用,否则状态不同步。


四、典型应用场景与完整 ST 代码示例

场景 1:单按钮启停控制(节省硬件触点)

用一个常开按钮实现“按一下启动,再按一下停止”的逻辑。核心在于区分两次按下的边沿类型:

// 变量声明(位于 VAR 块)
Button: BOOL;          // 按钮物理输入(已硬件消抖)
MotorOn: BOOL;         // 电机运行状态(线圈/输出)
StartPulse: BOOL;      // 启动脉冲(上升沿)
StopPulse: BOOL;       // 停止脉冲(下降沿)

// 程序体(ST 代码段)
// 检测按钮按下(上升沿)→ 启动电机
StartPulse := R_TRIG(CLK := Button);
// 检测按钮释放(下降沿)→ 停止电机
StopPulse := F_TRIG(CLK := Button);

// 用 SR 触发器实现启停锁存(Q 置位由 StartPulse 驱动,R 复位由 StopPulse 驱动)
MotorOn := (MotorOn AND NOT StopPulse) OR StartPulse;

🔍 解析:

  • Button 为常开按钮,未按时为 FALSE,按下时变为 TRUE(产生上升沿),松开时变回 FALSE(产生下降沿);
  • StartPulse 在按下瞬间为 TRUE(仅 1 扫描周期),触发 MotorOn 置位;
  • StopPulse 在松开瞬间为 TRUE(仅 1 扫描周期),触发 MotorOn 复位;
  • MotorOn 作为自锁变量,维持运行状态直至收到停止脉冲。

场景 2:脉冲计数防重复累加

检测编码器 A 相脉冲,要求每个上升沿只计数一次,不受扫描周期波动影响:

EncoderA: BOOL;    // 编码器 A 相输入
Count: UINT;       // 计数值
EdgePulse: BOOL;   // 上升沿脉冲

// 生成单周期脉冲
EdgePulse := R_TRIG(CLK := EncoderA);

// 在脉冲有效时累加(确保每边沿仅执行一次)
IF EdgePulse THEN
    Count := Count + 1;
END_IF;

✅ 此写法严格规避了“因 EncoderA = TRUE 持续多个周期而导致 Count 多次增加”的错误。

场景 3:多条件联动的边沿协同

要求:仅当 Enable = TRUETriggerSignal 出现上升沿时,才允许输出 ValidPulse

Enable: BOOL;
TriggerSignal: BOOL;
ValidPulse: BOOL;

// 先检测边沿,再与使能条件“与”运算
ValidPulse := R_TRIG(CLK := TriggerSignal) AND Enable;

💡 原理:R_TRIG(...) 输出单周期 TRUEAND Enable 仅在 Enable 当前为 TRUE 时通过该脉冲。若 Enable 在边沿发生后才变 TRUE,则本次脉冲被屏蔽,不会误触发。


五、常见错误与规避方法

错误现象 根本原因 修正方法
Q 输出持续多个周期 R_TRIG 输出直接赋给保持型变量(如 Flag := R_TRIG(...) 后未清零) Q 本身已是单周期脉冲,应直接用于条件判断或触发动作,勿赋值给需保持的变量;若需保持,用 SRSET/RESET 逻辑
边沿丢失 CLK 信号宽度小于 PLC 扫描周期(如机械抖动、高速脉冲) CLK 前加硬件 RC 滤波,或在 ST 中用 TON 延时确认稳定电平(例:Stable := TON(IN := RawIn, PT := T#20ms).Q; 再将 Stable 接入 R_TRIG
同一信号混用 R_TRIGF_TRIG 导致逻辑冲突 对同一 CLK 同时调用两者,但未考虑二者输出时间错位(上升沿与下降沿必然不重叠,但易引发理解混乱) 明确分工:上升沿事件用 R_TRIG,下降沿事件用 F_TRIG;避免对同一信号既检测上升又检测下降来驱动互斥动作(应改用 IF...ELSIF... 结构)
IF 条件中重复调用 R_TRIG IF R_TRIG(CLK := X).Q THEN ... END_IF; IF R_TRIG(CLK := X).Q THEN ... END_IF; → 两次调用创建两个独立实例,第二次读取的是第一次更新后的状态,逻辑失效 每个信号只调用一次 R_TRIG,结果存入临时变量复用:<br>tmp := R_TRIG(CLK := X);<br>IF tmp.Q THEN ... END_IF;<br>IF tmp.Q THEN ... END_IF;

六、与其它边沿检测方法的对比

方法 实现方式 优点 缺点 适用场景
R_TRIG / F_TRIG 标准功能块,自动管理历史值 符合标准、可移植性强、无需手动维护变量、抗扫描周期变化 依赖 PLC 支持(极少数老平台需自定义) 通用首选,95% 以上项目
手动存储法 Prev := CLK; Q := CLK AND NOT Prev; Prev := CLK; 完全可控、无功能块依赖 易写错(如顺序颠倒)、占用额外变量、不可读性高 仅限无标准功能块的嵌入式裸机开发
定时器辅助法 TON 检测信号稳定后触发 兼具消抖与边沿识别 占用定时器资源、响应延迟固定、逻辑冗余 对抖动敏感且无硬件消抖时的备选

七、高级技巧:组合边沿生成复杂事件

利用布尔代数,可从基础边沿构建复合事件:

  • 双沿检测(上升沿或下降沿)
    AnyEdge := R_TRIG(CLK := Signal).Q OR F_TRIG(CLK := Signal).Q;

  • 脉冲宽度测量(粗略)

    Rising := R_TRIG(CLK := PulseIn).Q;
    Falling := F_TRIG(CLK := PulseIn).Q;
    // 用计数器在 Rising 启动,在 Falling 停止(需配合定时器或高速计数器)
  • 防误触发的“确认式”上升沿(需连续 N 个周期稳定为 TRUE 才认定):

    // 使用 TON 配合 R_TRIG
    StableTON(IN := Signal, PT := T#50ms); // 50ms 稳定即确认
    ConfirmedRise := R_TRIG(CLK := StableTON.Q).Q;

八、调试建议:快速定位边沿逻辑问题

  1. 监控关键变量:在调试界面同时观察 CLKR_TRIG(...).QF_TRIG(...).Q 三者波形,确认 Q 是否严格对应 CLK 跳变且仅单周期;
  2. 插入测试脉冲:用 T#1s 定时器生成 1Hz 方波模拟 CLK,验证功能块响应是否准时;
  3. 检查扫描周期:若 Q 脉冲不可见,确认 PLC 扫描周期是否过长(>100ms),导致单周期脉冲在 HMI 刷新中被跳过;
  4. 禁用优化:部分编译器对恒定 FALSE 输入做优化,导致 R_TRIG 不执行;调试时确保 CLK 信号真实变化。

R_TRIGF_TRIG 是 ST 编程中最小却最关键的基石。掌握其“单周期脉冲”本质、严格遵循调用时序、规避常见误用模式,即可构建出响应精准、抗干扰强、易于维护的自动化逻辑。

评论 (0)

暂无评论,快来抢沙发吧!

扫一扫,手机查看

扫描上方二维码,在手机上查看本文