条件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 App2PLC_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 App2PLC_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>)
() 为运算符加上括号。
另见