Skip to main content

条件编译指示

重要

您可以在 ST POU 的实现中使用条件编译指示。 CODESYS 当您在声明部分使用条件编译指示时,不会对其进行求值。

例外是条件编译指示 {project_define (<global define>)} 运算符,可用于 POU 的实现部分和声明部分(参见 project_defined (<global define>))。

条件编译指示的目的是影响代码在预编译或编译过程中的生成方式。 ST 实现语言支持这些 pragma。

使用条件编译指示,您可以影响编译时是否考虑实现代码。例如,您可以根据是否声明了特定变量、是否存在特定 POU 等来设置它。

编译指示

描述

{define <identifier> <string>}

该值可以被查询和比较 hasvalue 稍后的。

{undefine <identifier>}

{define} 标识符的声明 <identifier> 被删除,并且标识符从现在开始再次“未定义”。当指定的标识符根本没有定义时,编译指示将被忽略。

{IF <expr>}...

{ELSIF <expr>}...

{ELSE}...

END_IF}

这些是条件编译的编译指示。

指定的表达式 <expr> 必须在编译时保持不变。它们按照它们在此处出现的顺序进行评估,直到其中一个表达式具有非零值。链接到该语句的文本被编译。其他行被忽略。段的顺序是固定的。这 ELSIFELSE 段是可选的。这 ELSIF 段可以出现任意次数。您可以在常量中使用多个条件编译运算符 <expr>.

<expr>

您可以使用一个或多个 运营商 在常量表达式内 <expr> 在条件编译编译指示内 {IF} 或者 {ELSIF} .

提示

您可以指定表达式和 define 定义为 编译器定义建造 POU 属性对话框中的选项卡。如果您指定 define 属性对话框中的定义,那么您必须省略该术语 {define},与实现代码中的定义相反。此外,您可以指定多个逗号分隔 define 属性对话框中的定义。

运营商

defined (variable: <variable name> )

运算符使表达式被赋予值 TRUE 当变量 <variable name> 在当前范围内声明。否则 FALSE 被退回。

要求:两个应用程序 App1App2 存在。变量 g_bTest 被声明在 App1,但不在 App2.

{IF defined (variable: g_bTest)}
    (* the following code is only processed in App2*)
    g_bTest := x > 300;
{END_IF}

defined (<identifier>)

运算符使表达式被赋予值 TRUE.要求是标识符 <identifier> 已经通过定义 {define} 声明并且之后没有未定义 {undefine} 陈述。否则 FALSE 被退回。

要求:应用程序 App1App2 存在。这 pdef1 变量由 a 定义 {define} 中的声明 App1,但不在 App2.

{IF defined (pdef1)}
(* This code is processed in App1 *)
{info 'pdef1 defined'}
    hugo := hugo + SINT#1;
{ELSE}
(* the following code is only processed in App2 *)
{info 'pdef1 not defined'}
    hugo := hugo - SINT#1;
{END_IF}

这还包括一个消息杂注的示例:仅消息 pdef1 defined 编译应用程序时显示在消息视图中,因为 pdef1 实际上是定义的。讯息 pdef1 not defined 时显示 pdef1 没有定义。

defined (type: <identifier> )

运算符使表达式被赋予值 TRUE 当使用标识符声明数据类型时 <identifier>.否则 FALSE 被退回。

要求:两个应用程序 App1App2 存在。数据类型 DUT 被声明在 App1,但不在 App2.

{IF defined (type: DUT)}
    (* the following code is only processed in App1*)
    bDutDefined := TRUE;
{END_IF}

defined (pou: <pou name>)

运算符使表达式被赋予值 TRUE 当以下具有名称的对象之一 <pou-name> 存在:

  • 功能块

  • 功能

  • 程序

  • 行动

  • 方法

  • 界面

否则 FALSE 被退回。

要求:两个应用程序 App1App2 存在。 POU CheckBounds 存在于 App1,但不在 App2.

{IF defined (pou: CheckBounds)}
    (* the following code is only processed in App1 *)
    arrTest[CheckBounds(0,i,10)] := arrTest[CheckBounds(0,i,10)] + 1;
{ELSE}
    (* the following code is only processed in App2 *)
    arrTest[i] := arrTest[i]+1;
{END_IF}

defined (resource: <identifier>)

重要

尚未实施

运算符使表达式被赋予值 TRUE 如果一个资源对象名为 <identifier> 为申请而存在;否则 FALSE 被退回。

要求:两个应用程序 App1App2 存在。资源对象 glob_var1 的全局变量列表存在于 App1, 但不是为了 App2.

{IF defined (resource:glob_var1)}
    (* the following code is only processed in App1 *)
    gvar_x := gvar_x + ivar;
{ELSE}
    (* the following code is only processed in App2 *)
    x := x + ivar;
{END_IF}

defined (task: <task name> )

运算符使表达式被赋予值 TRUE 当使用名称定义任务时 <task name>.否则 FALSE 被退回。

句法

{ IF defined (task: <task name> }
{ ELSIF defined (task: <task name> }
293. 例子

{IF defined (task: Task_D)}



294. 例子

要求:两个应用程序 App1App2 存在。任务 PLC_PRG_Task 定义在 App1,但不在 App2.

{IF defined (task: PLC_PRG_Task)}
    (* the following code is only processed in App1 *)
    erg := plc_prg.x;
{ELSE}
    (* the following code is only processed in App2 *)
    erg := prog.x;
{END_IF}


defined (IsLittleEndian)

运算符使表达式被赋予值 FALSE 当 CPU 内存以 Big Endian(摩托罗拉字节顺序)组织时。

defined (IsSimulationMode)

运算符使表达式被赋予值 TRUE 当应用程序在模拟设备上运行时(在模拟模式下)。

有关更多信息,请参阅: 在模拟模式下测试

defined (IsFPUSupported)

如果表达式返回值 TRUE,然后代码生成器在计算时生成一个 FPU 代码(用于浮点单元处理器) REAL 价值观。否则会模拟 FPU 操作,这要慢得多。

hasattribute (pou: <pou name>, ' <attribute name> ')

运算符使表达式被赋予值 TRUE 当属性 <attribute> 在功能块声明部分的第一行指定 <pou name>.否则 FALSE 被退回。

295. 例子

要求:两个应用程序 App1App2 存在。功能 fun1 被声明在 App1App2.然而,在 App1 它还提供了 pragma {attribute 'vision'}.

App1

{attribute 'vision'}
FUNCTION fun1 : INT
VAR_INPUT
    i : INT;
END_VAR
VAR
END_VAR

App2

FUNCTION fun1 : INT
VAR_INPUT
    i : INT;
END_VAR
VAR
END_VAR

Pragma 声明:

{IF hasattribute (pou: fun1, 'vision')}
    (* the following code is only processed in App1 *)
    ergvar := fun1(ivar);
{END_IF}


hasattribute (variable: <variable name> , ' <attribute name> ')

运算符使表达式被赋予值 TRUE 当编译指示 {attribute '<attribute>'} 在变量声明之前的行中分配给变量。否则 FALSE 被退回。

296. 例子

要求:两个应用程序 App1App2 存在。变量 g_globalInt 用于 App1App2, 但在 App1 属性 'DoCount' 也分配给它。

宣言 g_GlobalIntApp1

VAR_GLOBAL
    {attribute 'DoCount'}
    g_globalInt : INT;
    g_multiType : STRING;
END_VAR

宣言 g_GlobalIntApp2

VAR_GLOBAL
    g_globalInt : INT;
    g_multiType : STRING;
END_VAR

Pragma 声明:

{IF hasattribute (variable: g_globalInt, 'DoCount')}
    (* the following code is only processed in App1 *)
    g_globalInt := g_globalInt + 1;
{END_IF}


hasconstanttype( <constant name> , <boolean literal> )

操作员检查常量是否用 <constant name>, 已被替换。第二个参数(布尔值)控制检查的内容:

  • TRUE: 检查常量是否被替换

  • FALSE: 检查常量是否未被替换

当相应的情况发生时,运算符返回 TRUE.

句法

{ IF hasconstanttype( <constant namne> , <boolean literal> ) }
{ ELSIF hasconstanttype( <constant namne> , <boolean literal> ) }
297. 例子

{IF hasconstanttype(PLC_PRG.aConst, TRUE)}



. 常量的自动替换原则上取决于以下几点:
  • 编译选项 替换常量

  • 常量类型(例如, STRING 类型永远不会被替换。)

  • 属性的使用 {attribute 'const_non_replaced'}

  • 属性的使用 {attribute 'const_replaced'}

298. 例子
VAR
    iCntMAXIsReplaced: INT;
    xErrorOccured : BOOL;
END_VAR
VAR CONSTANT
    c_iMAX: INT := 99;
END_VAR

{IF hasconstanttype(c_iMAX, TRUE)}
    iCntMAXIsReplaced := iCntMAXIsReplaced + 1;
{ELSE}
    xErrorOccured := FALSE;
{END_IF}


hasconstantvalue( <constant name> , <variable name> , <comparison operator> )

运算符比较常量的值,该常量用 <constant name>,与第二个参数的值。第二个参数可以指定为文字 <literal> 或作为变量 <variable name>.

. 比较运算符 <comparison operator>
  • 比...更棒 (>)

  • 大于或等于 (>=)

  • 等于 (=)

  • 不等于 (<>)

  • 小于或等于 (<=)

  • 少于 (<)

句法

{ IF hasconstantvalue( <constant name> , <variable name> , <comparison operator> )
{ IF hasconstantvalue( <constant name> , <literal> , <comparison operator> )
{ ELSIF hasconstantvalue( <constant name> , <variable name> , <comparison operator> )
{ ELSIF hasconstantvalue( <constant name> , <literal> , <comparison operator> )
299. 例子

{IF hasconstantvalue(PLC_PRG.aConst, 99, >)}

{ELSIF hasconstantvalue(PLC_PRG.aConst, GVL.intconst99, =)}



300. 例子
PROGRAM PRG_ConditionConstantValue
VAR
    iCntMAX: INT;
    iCntGlobalMAX : INT;
    iCntABC: INT;
    iCntGlobalABC : INT;
    xErrorOccured : BOOL;
END_VAR
VAR CONSTANT
    c_iMAX: INT := 999;
    c_sABC: STRING := 'ABC';
    {attribute 'const_non_replaced'}
    c_iNonReplaceable: INT := 888;
END_VAR

{IF hasconstantvalue(c_iMAX, 999, =)}
    iCntMAX := iCntMAX + 1;
{ELSE}
    xErrorOccured := FALSE;
{END_IF}

{IF hasconstantvalue(c_iMAX, GVL.gc_iMAX, =)}
    iCntGlobalMAX := iCntGlobalMAX + 1;
{ELSE}
    xErrorOccured := FALSE;
{END_IF}

{IF hasconstantvalue(c_sABC, 'ABC', =)}
    iCntABC := iCntMAX + 1;
{ELSE}
    xErrorOccured := FALSE;
{END_IF}
{IF hasconstantvalue(c_sABC, GVL.gc_sABC, =)}
    iCntGlobalABC := iCntMAX + 1;
{ELSE}
    xErrorOccured := FALSE;
{END_IF}


hastype (variable: <variable name>, <data type> )

运算符使表达式被赋予值 TRUE 当变量 <variable> 属于数据类型 <type-spec>.否则 FALSE 被退回。

可能的数据类型:

BOOL | BYTE | DATE | DATE_AND_TIME | DT | DINT | DWORD | INT | LDATE | LDATE_AND_TIME | LDT | LINT | LREAL | LTIME | LTIME_OF_DAY | LTOD | LWORD | REAL | SINT | STRING | TIME | TIME_OF_DAY | TOD | ULINT | UDINT | UINT | USINT | WORD | WSTRING

301. 例子

要求:两个应用程序 App1App2 存在。变量 g_multitype 被声明在 App1 有数据类型 LREAL, 在 App2 有数据类型 STRING.

{IF (hastype (variable: g_multitype, LREAL))}
    (*  the following code is only processed in App1 *)
    g_multitype := (0.9 + g_multitype) * 1.1;
{ELSIF (hastype (variable: g_multitype, STRING))}
    (* the following code is only processed in App2 *)
    g_multitype := 'this is a multitalent';
{END_IF}


hasvalue (PackMode, ' <pack mode value> ')

检查的包模式取决于设备描述,而不是可以为单个 DUT 指定的编译指示。

hasvalue (RegisterSize, ' <register size> ')

<register size>: CPU 寄存器的大小(以位为单位)

运算符使表达式返回值 TRUE 当 CPU 寄存器的大小等于 <register size>.

可能的值 <register size>

  • 16 对于 C16x,

  • 64 适用于 X86-64 位

  • 32 适用于 X86-32 位

hasvalue (<define-ident>, ' <character string> ')

运算符使表达式被赋予值 TRUE 当使用标识符定义变量时 <define-ident> 并且有价值 <char-string>.否则 FALSE 被退回。

要求:两个应用程序 App1App2 存在。变量 test 在应用程序中使用 App1App2.在 App1, 它被赋予值 1.在 App2, 它被赋予值 2.

{IF hasvalue(test,'1')}
    (*  the following code is only processed in App1 *)
    x := x + 1;
{ELSIF hasvalue(test,'2')}
    (*  the following code is only processed in App2 *)
        x := x + 2;
{END_IF}

project_defined (<global define>)

此运算符自起可用 CODESYS V3.5 SP20。

运算符使表达式接收值 TRUE 如果全局定义 <global define> 包含在全局定义列表中 编译选项 项目设置。

运算符被指定为条件 IF 语句,可用于 ST POU 和库的实现部分和声明部分。它们可以通过以下方式与其他定义组合 ANDOR 运算符(如果相应位置允许)。

在 POU 的声明部分, IF 与操作员的声明 project_defined (<global define>) 可以包含以下结构:

  • 变量声明

    例子:

    {If project_defined(define1)}
        x : DINT;
    {END_IF}
  • 评论

  • 属性声明

  • 杂注语句

以下构造是 不是 可能的:

  • 完整的变量声明

    例子

    {If project_defined(define1)}
    VAR
        x : DINT;
    END_VAR
    {END_IF}
  • POU 的完整声明

    例子:

    {If project_defined(define1)}
    FUNCTION POU : BOOL
    VAR_INPUT
        x : INT;
    END_VAR
    {END_IF}
  • 适用范围: VAR_INPUT, VAR_OUTPUT, VAR_IN_OUT

NOT <operator>

表达式被赋予值 TRUE 当反向值 <operator> 返回值 TRUE. <operator> 可以是本章中描述的运算符之一。

302. 例子

要求:两个应用程序 App1App2 存在。 PLC_PRG1 存在于 App1App2, 和 POU CheckBounds 只存在于 App1.

{IF defined (pou: PLC_PRG1) AND NOT (defined (pou: CheckBounds))}
    (* the following code is only processed in App2 *)
    bANDNotTest := TRUE;
{END_IF}


<operator> AND <operator>

表达式被赋予值 TRUE 当两个指定的运算符返回时 TRUE. <operator> 可以是本章中描述的运算符之一。

要求:应用程序 App1App2 存在。 PLC_PRG1 存在于 App1App2, 和 POU CheckBounds 只存在于 App1.

{IF defined (pou: PLC_PRG1) AND (defined (pou: CheckBounds))}
    (* the following code is only processed in App1 *)
    bANDTest := TRUE;
{END_IF}

<operator> OR <operator>

表达式返回 TRUE 当两个指定的运算符之一返回时 TRUE. <operator> 可以是此处描述的运算符之一。

303. 例子

要求:两个应用程序 App1App2 存在。 POU PLC_PRG1 存在于 App1App2, 和 POU CheckBounds 只存在于 App1.

{IF defined (pou: PLC_PRG1) OR (defined (pou: CheckBounds))}
    (* the following code is only processed in App1 and in App2 *)
    bORTest := TRUE;
{END_IF}


(<operator>)

() 括号中的运算符。