GX Works2中ST语言实现FX3S-PLC脉冲定时器遇C9009编译错误
解决GX Works2中FX3S PLC用ST实现脉冲定时器的C9009错误问题
错误原因
C9009错误本质是自动分配的定时器软元件点数不足:FX3S仅支持T0-T255共256个定时器资源(其中T246-T255为1ms分辨率,仅10个点位),若ST程序中调用的定时器实例数量超过了自动分配设置的点数,或写法错误导致额外占用资源,就会触发该报错。
正确实现方案
方案1:使用内置脉冲定时器FB(TON_TR)
这是最规范的官方实现方式,需确保资源分配正确:
- 调整自动分配设置
- 打开工程→
工程→参数→PLC参数→软元件自动分配设置 - 找到「定时器」项,将点数设置为实际需要的数量(最大可设256)
- 打开工程→
- 全局变量声明
VAR_GLOBAL // 声明脉冲定时器FB实例 PulseTimer: TON_TR; // 定时器触发信号(上升沿有效) Trigger: BOOL := FALSE; // 定时时长(需匹配FX3S定时器分辨率,如100ms定时器需设为100的倍数) TimeSet: TIME := T#1000ms; // 定时器输出信号 TimerOut: BOOL; END_VAR - ST程序调用
// 触发脉冲定时器:Trigger上升沿启动,TimeSet为定时时长,Q输出结果 PulseTimer(IN := Trigger, PT := TimeSet, Q => TimerOut);
方案2:手动用ST逻辑实现(不占用PLC定时器资源)
适合资源紧张的场景,完全通过变量逻辑实现,无需依赖PLC定时器软元件:
- 全局变量声明
VAR_GLOBAL // 外部触发信号 Trigger: BOOL := FALSE; // 用于捕捉上升沿的缓存变量 LastTrigger: BOOL := FALSE; // 定时器启动标记 TimerStart: BOOL; // 记录启动时间与当前时间(毫秒级) StartTime: DWORD; CurrentTime: DWORD; // 定时时长(单位:ms) TimeSet: DWORD := 1000; // 定时器输出信号 TimerOut: BOOL := FALSE; END_VAR - ST程序逻辑
注:// 捕捉Trigger的上升沿,生成单次启动信号 TimerStart := Trigger AND NOT LastTrigger; LastTrigger := Trigger; // 启动定时器时记录初始时间并置位输出 IF TimerStart THEN StartTime := GET_CURRENT_TIME(); TimerOut := TRUE; END_IF; // 达到定时时长后复位输出 IF (GET_CURRENT_TIME() - StartTime) >= TimeSet THEN TimerOut := FALSE; END_IF;GET_CURRENT_TIME()是GX Works2内置函数,用于获取PLC系统的毫秒级时间。
方案3:手动分配定时器编号(规避自动分配冲突)
若坚持使用内置TON指令,可手动指定定时器编号,避免占用自动分配额度:
- 全局变量声明
VAR_GLOBAL // 手动指定使用T10定时器(需确保该编号未被其他程序占用) MyTimer: TON := (TNO := 10); Trigger: BOOL; TimeSet: TIME := T#1000ms; TimerOut: BOOL; END_VAR - ST程序调用
MyTimer(IN := Trigger, PT := TimeSet, Q => TimerOut);
关键注意事项
- FX3S的1ms分辨率定时器(T246-T255)仅10个点位,使用时需注意分辨率匹配,避免浪费资源
- 若使用多个定时器FB实例,每个实例会占用一个独立的定时器软元件,需确保总数量不超过PLC支持上限
- 编译前务必检查PLC参数中的软元件自动分配设置,确认定时器点数不小于实际使用量
内容的提问来源于stack exchange,提问作者Daddedebad
相关产品推荐
相关产品推荐

