0

编译器对以下程序给出错误。我解决不了。

这是用 ST 语言编写的 Codesys 系统。我想使用位操作来操作电磁阀。

CanRx := can_getDatabox (CAN_2, 10, ADR(CanRx_data), ADR(CanRxNumBytes));
Rx_test_1 := CanRx_data[1];
Rx_test_2 := CanRx_data[2];
Rx_test_3 := CanRx_data[3];
Rx_test_4 := CanRx_data[4];

IF(Rx_test_1 & 4 = 4)THEN
  out (OUT_1_POH_CL, 1500);
  ELSE IF(Rx_test_1 & 8 = 8)THEN
  out (OUT_1_POH_CL, 0);
END_IF

编译器错误:

 Error: 4011:Callback_MAIN_Task(XX): Type mismatch in parameter 1 of 'AND':Cannot convert 'INT' to 'ANY_BIT'  
 Error: 4024:Callback_MAIN_Task(XX): Expecting END_IF_before"
4

2 回答 2

1

ST 运算符的文档说比较和相等运算符<, >, <=, >=, =, 和<>具有比布尔逻辑运算符和按位逻辑运算符更高的优先级。

此外,在 ST 位逻辑运算符是ANDandOR而不是&and |。类似地,布尔逻辑运算符是AND_THENandOR_ELSE而不是&&and ||。(但请注意,布尔逻辑运算符已添加到 CODESYS 编译器V3.5 SP4中,如果您使用的是较旧的,它们将不可用。例如,SoMachine使用较旧的)

此外, for 的语法IF如下:

IF condition THEN
    statement1;
ELSEIF condition THEN
    statement2;
ELSE
    statement3;
END_IF;

但是你的代码有ELSE IF而不是ELSEIFEND_IF的缺少分号。(尽管如果我跳过它,我从来没有任何编译器抱怨过,而且他们自己经常在文档的示例中省略它们)

因此,您只需要在比较之前将按位运算括起来即可。(在 C 系列语言中也是同样的情况,这会导致带有太多括号的表达式不可读),用有效的 ST 运算符替换它们,并修复ELSE IF部分。

尝试合并这些更改,如下所示:

(注意,我还添加了空格以提高可读性。ST 不会对空格施加任何语义(与 Python、Haskell 等不同),因此您应该使用空格来最大限度地提高可读性和可维护性)。(我的个人风格是括号内有空格,而不是括号外 - 其他人强烈反对,YMMV)

IF ( ( Rx_test_1 AND 4 ) = 4 ) THEN

    out ( OUT_1_POH_CL, 1500 );

ELSEIF ( ( Rx_test_1 AND 8 ) = 8 ) THEN

    out ( OUT_1_POH_CL, 0 );

END_IF;
于 2020-11-20T07:34:14.213 回答
1

我能够自己解决它。我使用 AND 而不是 &,使用了 ELSEIF 的 ELSIF。这是正确的代码。

Rx_test_1 : BYTE;

IF ((Rx_test_1 AND 1) =1) THEN
   statement1;
ELSIF (( Rx_test_1 AND 2) =1) THEN
   statement2;
ELSIF (( Rx_test_1 AND 4) =1) THEN
   statement3;
ELSE
   statement4;
END_IF
于 2020-11-20T10:40:02.970 回答