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
相关产品推荐
相关产品推荐

