普通网友 2026-02-26 23:00 采纳率: 98.6%
浏览 1
已采纳

Codesys梯形图中如何实现上升沿触发且避免重复执行?

在Codesys梯形图编程中,常遇到“输入信号短暂抖动或扫描周期内持续为ON,导致上升沿(R_TRIG)触发后重复执行动作”的问题。例如,当按钮硬件消抖不良,或传感器信号存在毛刺时,单次按下可能被多个扫描周期识别为多次“上升沿”,造成电机误启、计数器多加、报警重复触发等严重逻辑错误。虽然标准R_TRIG功能块本身具备边沿记忆能力,但若其CLK输入在多个周期内持续为TRUE(如未加滤波的机械开关信号),则仅在首次由FALSE→TRUE跳变时触发Q输出;然而,若信号在未完全稳定前反复波动(如0→1→0→1),仍可能产生多次有效边沿。更隐蔽的问题是:当R_TRIG被放置在条件分支(如FB实例未始终使能)或受使能链影响时,其内部状态可能未被连续更新,导致边沿丢失或误判。如何在梯形图中稳健实现**单次、抗干扰、可复位**的上升沿检测,并确保动作仅执行一次?这是工业现场PLC逻辑可靠性的关键基础。
  • 写回答

1条回答 默认 最新

  • rememberzrr 2026-02-26 23:00
    关注
    ```html

    一、现象剖析:为什么标准 R_TRIG 在工业现场“不可靠”?

    在 Codesys 梯形图中,R_TRIG 功能块仅检测 CLK 输入的 单次 FALSE→TRUE 跳变,其内部使用静态布尔变量(如 MEM)锁存前一周期状态。但当输入信号存在硬件抖动(如机械按钮 5–20ms 毛刺)、EMI 干扰或长线反射时,原始信号波形可能呈现:

    周期0: FALSE → 周期1: TRUE → 周期2: FALSE → 周期3: TRUE → 周期4: TRUE

    此时,R_TRIG 将在周期1和周期3各触发一次 Q=TRUE——即两次误触发。更严重的是:若该 R_TRIG 被置于 IF 条件分支内(如 IF bEnable THEN R_TRIG(...); END_IF;),当 bEnable=FALSE 时,功能块不执行,其内部状态停滞,导致边沿丢失或状态不同步。

    二、根因分层诊断模型

    层级典型诱因Codesys 表现影响范围
    物理层按钮触点弹跳、NPN传感器漏电流、未加 RC 滤波输入映像区(%IX*)连续多周期跳变全系统基础信号链
    执行层FB 实例未全局使能、R_TRIG 置于 GOTO 跳转后、扫描周期波动 >10ms功能块静态变量未更新,MEM 状态失准逻辑分支可靠性坍塌
    设计层未区分“瞬态事件”与“稳态条件”,复位逻辑缺失或异步Q 输出持续为 TRUE 或无法清除,动作重复执行安全联锁、计数、报警等关键功能失效

    三、工业级抗抖动上升沿方案(梯形图原生实现)

    以下为可直接部署于 Codesys ST/LD 的零依赖、可复位、扫描周期鲁棒型上升沿检测结构(LD 描述):

    1. 对原始信号 IN 进行 软件滤波:使用移位寄存器(SR)或计数器实现 ≥3 周期一致确认(推荐 3~5 个扫描周期);
    2. 将滤波后信号 IN_Filtered 接入标准 R_TRIG 的 CLK;
    3. 引入独立复位信号 RESET(上升沿/下降沿/电平均可),通过 SRSET/RESET 触发器清零 R_TRIG 内部 MEM;
    4. R_TRIG.Q 输出与一个自锁 SR(置位由 Q 触发,复位由 RESET 控制)组合,确保动作仅执行一次且可人工干预复位。

    四、推荐实现:LD+ST 混合结构(含复位同步机制)

    // 自定义抗抖动上升沿 FB(ST 实现,供 LD 调用)
    FUNCTION_BLOCK F_R_TRIG_DEBOUNCE
    VAR_INPUT
      CLK     : BOOL;   // 原始输入(带抖动)
      RESET   : BOOL;   // 复位信号(建议用上升沿触发)
      TON_MS  : TIME := T#20ms; // 滤波时间基准(对应扫描周期倍数)
    END_VAR
    VAR_OUTPUT
      Q       : BOOL;
    END_VAR
    VAR
      fbTON   : TON;     // 定时器实现延时确认
      bLast   : BOOL;
      bStable : BOOL;
      rTrig   : R_TRIG;
    END_VAR
    
    // 1. 滤波:CLK 持续为 TRUE ≥ TON_MS 后才认定稳定
    fbTON(IN := CLK, PT := TON_MS);
    bStable := fbTON.Q;
    
    // 2. 上升沿检测(作用于稳定信号)
    rTrig(CLK := bStable);
    Q := rTrig.Q;
    
    // 3. 同步复位:RESET 上升沿清除 rTrig 内部状态
    IF RESET AND NOT bLast THEN
      rTrig.MEM := FALSE; // 强制重置记忆位(需 Codesys V3.5+ 支持显式访问)
    END_IF;
    bLast := RESET;
    

    五、可视化逻辑流(Mermaid 流程图)

    flowchart TD A[原始输入 CLK] --> B{是否持续 TRUE ≥ TON_MS?} B -- 否 --> C[保持 bStable = FALSE] B -- 是 --> D[bStable = TRUE] C & D --> E[R_TRIG CLK = bStable] E --> F{R_TRIG.Q 上升沿?} F -- 是 --> G[输出 Q = TRUE] F -- 否 --> H[Q = FALSE] I[RESET 上升沿] --> J[强制 rTrig.MEM := FALSE] J --> E G --> K[执行一次动作] K --> L[等待 RESET 复位]

    六、现场部署黄金法则

    • 滤波时间选择:机械按钮取 T#15ms~T#30ms;光电开关取 T#2ms~T#5ms;严禁使用固定 1 周期延迟(无法应对扫描波动);
    • 复位信号设计:必须为边沿触发(如 F_TRIG(RESET)),避免电平复位导致 Q 锁死;
    • 实例化约束:F_R_TRIG_DEBOUNCE 必须在主程序循环(如 CyclicTask)中无条件调用,禁止嵌套于 IF/FOR 中;
    • 诊断增强:为每个关键上升沿添加 TIME 类型的 LastTriggerTime 变量,用于 HMI 显示最近触发时刻,辅助定位抖动源。

    七、进阶验证:抖动注入测试模板

    在 Codesys Simulation 中构建如下测试环境:

    1. 创建虚拟输入 %IX0.0,绑定到 BOOL 类型的 TestSignal
    2. 编写测试 ST 代码,用 FOR i:=0 TO 9 DO TestSignal := (i MOD 2 = 0); Delay(1); END_FOR 模拟 0→1→0→1 抖动;
    3. 对比标准 R_TRIG 与 F_R_TRIG_DEBOUNCE 输出波形:前者 Q 出现 5 次脉冲,后者仅 1 次;
    4. 启用 Codesys Trace 功能,捕获 rTrig.MEMbStable 变量变化曲线,验证滤波有效性。
    ```
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 已采纳回答 2月27日
  • 创建了问题 2月26日