You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Codesys 2.3中ST调用Throttle_Timer报错4051:非函数问题求助

解决CODESYS错误4051:"'Throttle_Timer' is no function"

核心问题

你把**函数块(FUNCTION_BLOCK)**当成普通函数(FUNCTION)调用了,这是CODESYS里的典型新手误区:

  • 函数块是带内部状态的"对象",必须先声明实例才能调用;
  • 普通函数是无状态的,可以直接用函数名(参数)的方式调用。

第一步:修复Throttle_Timer函数块的逻辑问题

原FB的逻辑有两处硬伤:TON调用不规范,且没有输出信号无法判断延时完成。优化后的代码:

FUNCTION_BLOCK Throttle_Timer
VAR_INPUT
    Trigger: BOOL;       // 触发延时的上升沿信号
    DelayTimeMs: TIME;   // 设定延时时间
END_VAR
VAR_OUTPUT
    Done: BOOL;          // 延时完成标志位
END_VAR
VAR
    Delay: TON;
    TriggerEdge: R_TRIG; // 捕捉触发信号的上升沿
END_VAR

// 捕捉Trigger的上升沿,防止重复触发
TriggerEdge(CLK := Trigger);

// 上升沿到来时启动定时器
IF TriggerEdge.Q THEN
    Delay(IN := TRUE, PT := DelayTimeMs);
END_IF

// 延时完成后输出Done,并重置定时器
IF Delay.Q THEN
    Done := TRUE;
    Delay(IN := FALSE);
ELSE
    Done := FALSE;
END_IF

第二步:正确调用函数块

在PLC_PRG里,先声明Throttle_Timer的实例,再通过实例调用。另外注意:PLC程序里禁止用WHILE循环,会阻塞整个扫描周期,改用IF+状态标志实现分步逻辑:

PROGRAM PLC_PRG
VAR
    Throttle: REAL := 0.0;       // 油门初始值
    speedUp: BOOL;               // 加速按钮输入
    ThrottleDelay: Throttle_Timer; // 声明FB实例
    CanUpdateThrottle: BOOL := TRUE; // 允许更新油门的标志
END_VAR

// 加速逻辑:按钮按下、油门未到上限、且允许更新时,提升油门
IF speedUp AND Throttle < 99.51 AND CanUpdateThrottle THEN
    Throttle := Throttle + 0.5;
    CanUpdateThrottle := FALSE;
    // 触发延时,500ms后允许再次更新
    ThrottleDelay(Trigger := TRUE, DelayTimeMs := T#500ms);
END_IF

// 延时完成后,恢复油门更新权限
IF ThrottleDelay.Done THEN
    CanUpdateThrottle := TRUE;
    ThrottleDelay(Trigger := FALSE); // 重置触发信号
END_IF

关键知识点

  • FB vs FC:FB有内部状态(比如定时器的当前值),必须实例化;FC是纯计算,无状态,直接调用。
  • PLC扫描周期:程序是循环扫描执行的,WHILE会占用整个扫描周期,导致其他IO或逻辑无法响应,必须用状态标志实现"分步执行"。

内容的提问来源于stack exchange,提问作者TheNewGuy9419

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 18:36:25