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




注意

如果在声明部分使用这些条件pragmas,CODESYS 不会对其进行评估。
使用条件pragmas可以影响编译时是否考虑执行代码。例如,您可以使其取决于是否声明了某个变量、是否存在某个功能块等。
Pragma |
说明 |
---|---|
|
以后可通过 |
|
|
|
这些是条件编译的pragmas。
|
|
您可以在常量表达式 |
您可以在 POU 属性对话框的“Build” 选项卡中输入表达式和define
定义,作为“编译器定义”。如果在属性对话框中输入define
定义,则必须省略{define}
这一术语,这与执行代码中的定义相反。此外,您还可以在属性对话框中指定多个define
定义,中间用逗号隔开。
操作符 defined (<identifier>)
该运算符会使表达式的值为TRUE
。要求是,标识符<identifier>
是在{define}
指令的帮助下定义的,并且在之后的{undefine}
指令中没有再次未定义;否则将返回FALSE
。
示例
要求:应用程序App1
和App2
。App1
中的 {define}
语句定义了变量pdef1
,但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}
其中还包含一个信息 pragma 的示例:在编译应用程序时,只有消息pdef1 defined
才会显示在消息视图中,因为pdef1
是实际定义的。如果未定义pdef1
,则显示信息pdef1 not defined
。
操作符 defined (variable: <variable_name>)
如果在当前作用域内声明了变量<variable_name>
,该操作符会使表达式的值为 TRUE
;否则返回FALSE
。
示例
要求:有两个应用程序App1
和App2
。变量g_bTest
在App1
中声明,但在App2
中没有声明。
{IF defined (variable: g_bTest)} (* the following code is only processed in App2*) g_bTest := x > 300; {END_IF}
操作符 defined (type: <identifier>)
如果使用标识符 <identifier>
; 声明了数据类型,操作符会使表达式的值为 TRUE
;否则返回FALSE
。
示例
要求:有两个应用程序App1
和App2
。App1
中声明了数据类型DUT
,但App2
中没有。
{IF defined (type: DUT)} (* the following code is only processed in App1*) bDutDefined := TRUE; {END_IF}
操作符 defined (pou: <pou name>)
如果存在名称为<pou-name>
的功能块或操作,运算符会使表达式的值为TRUE
,否则返回FALSE
。
示例
要求:有两个应用程序App1
和App2
。功能块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 (task: <task_name>)
尚未实施!
如果已定义了名称为<task_name>
的任务,操作符会使表达式的值为TRUE
;否则返回FALSE
。
语法
{ IF | ELSIF defined (task: <task name> }
示例
{IF defined (task: Task_D)}
示例
要求:有两个应用程序App1
和App2
。任务PLC_PRG_Task
已在App1
中定义,但未在App2
中定义。
{END_IF} {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 (resource: <identifier>)
尚未实施!
如果应用程序中存在名称为<identifier>
的资源对象,操作符将使表达式的值为TRUE
;否则,将返回FALSE
。
示例
要求:有两个应用程序App1
和App2
。全局变量列表的资源对象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 (IsLittleEndian)
如果 CPU 内存是按大字节(摩托罗拉字节序)组织的,则运算符会使表达式的值为FALSE
。
操作符 defined (IsFPUSupported)
如果表达式返回值为TRUE
,则代码生成器在使用REAL
值进行计算时会生成 FPU 代码(浮点单元处理器)。否则,CODESYS 模拟 FPU 操作,速度会慢得多。
操作符 hasattribute (pou: <pou name>, '<attribute>')
如果在函数块<pou name>
声明部分的第一行中指定了属性<attribute>
,则该操作符会使表达式的值为TRUE
;否则会返回FALSE
。
示例
要求:有两个应用程序App1
和App2
。函数fun1
在App1
和App2
中声明。不过,在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>, '<attribute>')
如果在变量声明之前的行中已将 pragma {attribute '<attribute>'}
赋值给变量,则该操作符会使表达式的值为TRUE
;否则返回FALSE
。
示例
要求:有两个应用程序App1
和App2
。在App1
和 App2
中使用了变量 g_globalInt
,但在App1
中又为其分配了属性'DoCount'
。
g_GlobalInt
声明 App1
VAR_GLOBAL {attribute 'DoCount'} g_globalInt : INT; g_multiType : STRING; END_VAR
声明g_GlobalInt
inApp2
:
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)
运算符检查用 < 常量名称> 标识的常量是否已被替换。第二个参数(布尔值)控制检查的内容:
-
正确:检查常量是否已被替换
-
错:检查常量是否未被替换 当出现相应情况时,运算符返回 TRUE。
语法
{ IF hasconstanttype( <constant namne> , <boolean literal> ) } { ELSIF hasconstanttype( <constant namne> , <boolean literal> ) }
示例
{IF hasconstanttype(PLC_PRG.aConst, TRUE)}
常数的自动替换原则上取决于以下几点:
-
编译选项
-
替换常数
-
常量类型(例如,STRING 类型永远不会被替换。)
-
属性{属性 "const_non_replaced"}的用法
-
属性{属性 "const_replaced"}的用法
示例
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)
运算符将常数(以 <常数名称> 标识)的值与第二个参数的值进行比较。第二个参数可以指定为字面 <literal> 或变量 <variable name>。
比较运算符 <比较运算符>:
-
大于 (>)
-
大于或等于 (>=)
-
等于 (=)
-
不等于 (<>)
-
小于或等于 (<=)
-
小于 (<)
语法
{ 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> )
示例
{IF hasconstantvalue(PLC_PRG.aConst, 99, >)} {ELSIF hasconstantvalue(PLC_PRG.aConst, GVL.intconst99, =)}
示例
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>, <type-spec>)
如果变量<variable>
的数据类型为<type-spec>
,则该操作符会使表达式的值为 TRUE
;否则会返回FALSE
。
<type-spec>
的可能数据类型:
-
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
示例
要求:有两个应用程序App1
和App2
。变量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 指定的pragma。
操作符 hasvalue (RegisterSize, '<register size>')
<寄存器大小>:CPU 寄存器的大小(位) 当 CPU 寄存器的大小等于 < 寄存器大小> 时,操作符将使表达式返回 TRUE 值。
< 寄存器大小> 的可能值
-
16 表示 C16x
-
64 用于 X86-64 位
-
32 用于 X86-32 位
操作符 hasvalue (<define-ident>, '<char-string>')
如果使用标识符<define-ident>
定义了一个变量,且该变量的值为<char-string>
,则该操作符会使表达式的值为TRUE
;否则会返回FALSE
。
示例
要求:有两个应用程序App1
和App2
。在应用程序App1
和 App2
中使用了变量test
;在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}
操作符 NOT <operator>
如果<operator>
的反向值返回值为TRUE
,则表达式的值为TRUE
。<operator>
可以是本章描述的运算符之一。
示例
要求:App1
App2
PLC_PRG1
存在于 和 中,而 POU 只存在于 中。App1
App2
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>
可以是本章描述的运算符之一。
示例
要求:App1
App2
PLC_PRG1
存在于 和 中,POU 仅存在于 中。App1
App2
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>
可以是本章描述的运算符之一。
示例
要求:有两个应用程序App1
和App2
。POUPLC_PRG1
存在于App1
和App2
中,而 POUCheckBounds
仅存在于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>)
()
为运算符加上括号。
另见