三菱Q00UJCPU PLC结构化文本交替输出问题及与Codesys差异咨询
在三菱GX Works2中实现ST交替输出失败的问题排查及Codesys与GX Works2的ST差异
问题背景
你尝试在三菱Melsec Q00UJCPU PLC上用结构化文本(ST)实现out1和out2的交替输出,触发条件是输入IN1为真。你的代码在Codesys中能正常运行,但在GX Works2里完全失效,代码如下:
IF IN1=TRUE THEN; timer1(IN:= TRUE, PT:=T#0s , Q:=timer1.Q); END_IF; IF timer1.Q THEN; out1:=FALSE; out2:=TRUE; timer1(IN:=FALSE, PT:=T#1s); timer2(IN:= TRUE, PT:=T#500ms , Q:=timer2.Q); END_IF; IF timer2.Q THEN; out2:=FALSE; out1:=TRUE; timer2(IN:=FALSE, PT:=T#1s); timer1(IN:=TRUE , PT:=T#500ms , Q:=timer1.Q); END_IF;
问题根源:GX Works2与Codesys的ST定时器调用逻辑完全不同
Codesys的ST实现更贴近IEC 61131-3的函数式调用风格,但三菱GX Works2的ST有自己的语法规范,最大的问题出在定时器的调用方式上:
- 在Codesys中,你可以直接像调用函数一样给定时器的
IN/PT/Q传参,比如timer1(IN:= TRUE, PT:=T#0s , Q:=timer1.Q); - 但在三菱GX Works2中,定时器(比如TON)是作为结构体类型存在的,你需要通过给结构体成员赋值的方式操作,而不是函数调用。而且
Q是定时器的输出状态,属于只读属性,不能通过赋值修改。
另外,你的代码里还存在逻辑问题:比如给PT赋值T#0s没有实际意义,三菱的定时器触发需要有效的时间设定值。
GX Works2中的正确实现代码
首先,你需要在变量表中声明两个TON类型的定时器实例(比如timer1和timer2),然后用以下ST代码实现交替输出:
// 当IN1触发时,启动第一个定时器 IF IN1 THEN timer1.IN := TRUE; timer1.PT := T#500ms; // 设置500ms延时 ELSE timer1.IN := FALSE; END_IF; // 定时器1触发后,切换输出并启动定时器2 IF timer1.Q THEN out1 := FALSE; out2 := TRUE; timer1.IN := FALSE; // 复位定时器1 timer2.IN := TRUE; timer2.PT := T#500ms; END_IF; // 定时器2触发后,切换输出并启动定时器1 IF timer2.Q THEN out2 := FALSE; out1 := TRUE; timer2.IN := FALSE; // 复位定时器2 timer1.IN := TRUE; timer1.PT := T#500ms; END_IF;
注意:如果你的Q系列PLC不支持T#500ms这种时间格式,可以改用数值格式(比如500ms对应K500,因为Q系列TON定时器默认单位是1ms)。
Codesys与GX Works2的ST主要差异
虽然两者都遵循IEC 61131-3标准,但细节上有不少区别:
- 定时器/计数器操作:Codesys支持函数式调用(
timer(IN:=...)),三菱GX Works2只能通过结构体成员赋值(timer.IN := ...) - 语法糖支持:Codesys允许更灵活的写法(比如省略分号、简化条件判断),GX Works2对语法的要求更严格,比如必须正确使用分号,部分简化写法不支持
- 数据类型细节:比如时间常量的解析,三菱部分机型可能需要适配特定格式;变量声明的规则也更严谨,必须提前在变量表中声明所有使用的实例(包括定时器)
- 标准兼容性:Codesys对IEC 61131-3的支持更全面,而三菱的ST是在标准基础上做了自家的扩展和限制,部分标准语法无法直接使用
内容的提问来源于stack exchange,提问作者Roman Selin




