可以向变量类型的声明中添加下列属性关键字以指定范围:
RETAIN:请参阅保留变量
PERSISTENT:请参阅持久变量
CONSTANT:请参阅 常量 — CONSTANT,类型化文字
VAR_GENERIC CONSTANT:请参阅 常量 — VAR_GENERIC CONSTANT
RETAIN、PERSISTENT
剩余变量可以在常规的程序运行期内保留其值。将其声明为保留变量,甚至声明为更严格的持久变量。
该声明确定在控制器进行复位、下载或重新启动的情况下,其余变量的持久程度。在应用程序中,主要是使用这两种剩余标志的组合(参阅持久变量)。
VAR PERSISTENT 声明的解释方式与 VAR PERSISTENT RETAIN 或 VAR RETAIN PERSISTENT 相同。
持久性通过以下步骤实现:
确定访问变量的循环任务。
在第一个循环任务结束时(在每个循环中),将变量复制到持久全局变量列表。
在控制器重启时,将持久变量的值复制到普通变量。
由于在声明和实例路径处都分配了内存,因此这个持久变量在每个循环中都要求双重内存分配。这可能引起处理时间延长,尤其是在处理大的结构化值时。
声明为保留变量的变量将存储在非易失性存储器区域中。为了声明该类变量,可在 POU 的声明部分或全局变量列表中使用关键字 RETAIN。
示例
VAR RETAIN
iRem1 : INT; (* 1. Retain variable*)
END_VAR
保留变量将一直保持其值,即使是在控制器意外关闭之后以及在控制器正常重置电源后(或者当执行命令时)。在程序重新启动时,将进一步处理保留的值。其他(非保留)变量以新方式初始化:要么使用其初始化值,要么使用其默认初始化值(如果未声明任何初始化值)。
例如,在以下情况下,您可能希望使用保留值:某个操作(如,生产机器中的数量统计)在断电后应继续运行。
但是,当执行命令时,保留变量会重新初始化,与持久变量不同,持久变量是在执行命令时或者在应用程序下载期间进行重新初始化。
VAR RETAIN 的特定变量才存储在非易失性存储器中。但是,在函数中定义为 VAR RETAIN 的本地变量不会存储在非易失性存储器中。在功能中以本地方式定义 VAR RETAIN 没有任何效果。
在保留程序段 (VAR_RETAIN) 中使用系统配置库中的接口或功能块将导致系统异常,可能使控制器不可操作,从而需要重启。
| 警告 | |
|---|---|
RETAIN,则会将功能块实例及其变量存储在剩余内存中。并非所有控制器都支持该功能。,请参阅控制器的相应编程指南 了解详细信息。
通过关键字 PERSISTENT (VAR_GLOBAL PERSISTENT) 标识持久变量。仅当执行命令时,才会重新初始化持久变量。与保留变量相比,持久变量的值在下载后保持不变。
VAR PERSISTENT 一起使用 AT 声明。
应用示例:
运行时间计数器,即使在电源中断或下载之后也应继续统计。请参阅剩余变量行为一览表。
只能在对象类型持久变量的特殊全局变量列表中声明持久变量,这一列表将被分配给某个应用程序。只能向应用程序中添加一个此类列表。
VAR_GLOBAL PERSISTENT 的声明与包含 VAR_GLOBAL PERSISTENT RETAIN 或 VAR_GLOBAL RETAIN PERSISTENT 的声明效果相同。
与保留变量相同,持久变量也存储在单独的存储器区域中。
示例
VAR_GLOBAL PERSISTENT RETAIN
iVarPers1 : DINT; (* 1. Persistent+Retain Variable App1 *)
bVarPers : BOOL; (* 2. Persistent+Retain Variable App1 *)
END_VAR
在每次重新加载应用程序时,都将比对项目的持久变量列表来检查控制器上的持久变量列表。控制器上的列表由应用程序来识别。如果发现不一致,将提示您重新初始化应用程序的所有持久变量。不一致性可能是由于重命名或删除了列表中的现有声明,或者对其进行了其他修改。
只能在列表的结尾添加新声明。在下载期间,这些声明将被检测为新声明,并且不需要重新初始化完整列表。如果您修改某一变量的名称或数据类型,这会被当成新的声明进行处理并会在下一次在线修改或下载时引起变量的重新初始化。
PERSISTENT,则会将功能块实例及其变量存储在剩余内存中,但仅这个变量被视为持久变量。
CONSTANT
常量由关键字 CONSTANT 来标识。您可以对它们进行本地声明(编程对象单元)或全局声明(全局变量列表)。在 POU 的实现部分中,常量变量为只读。
语法
<scope> CONSTANT <identifier>:<type> := <initialization>;
END_VAR
使用 <scope> : VAR | VAR_INPUT | VAR_STAT | VAR_GLOBAL
声明常量变量时,务必指定初始化值。
示例
VAR CONSTANT
c_iCon1:INT:=12; (* 1. Constant*)
END_VAR
有关可能常量的列表,请参阅操作数一章。
VAR_GENERIC CONSTANT
通用常量是功能块 VAR_GENERIC CONSTANT 声明区中的变量,在分配功能块实例之前,该变量不会被分配初始化值。
语法:功能块说明:
FUNCTION_BLOCK <function block name>
VAR_GENERIC CONSTANT
<generic constant name> : <integer data type> := <initial value>; //Initial value will be overwritten
END_VAR
;
例如,您可以在功能块中使用通用常量(整数数据类型)来表示数组大小或字符串长度。仅在编译检查时需要初始值 <initial value>。在运行时,值被覆盖。
语法:功能块实例说明:
PROGRAM PLC_PRG
VAR
<fb instance name> : <function block name> < <literal> >;
<fb instance name> : <function block name> <( <expression> )>;
END_VAR
;
在声明功能块实例时,将为常量分配一个仅对此实例有效的特定值。为此,值 <literal> 在尖括号中,添加到功能块 <function block name> 作为数据类型。
作为替代方法,可添加表达式 <expression>。将它括在括号中,以便在表达式中使用 < 或 > 等符号,并帮助您保持代码的唯一性。
示例:具有可参数化数组变量的通用功能块:
下列代码示例演示了如何定义可以处理任意长度数组的功能块。功能块具有通用但长度恒定的数组。此上下文中,术语“常量”意味着,尽管每个功能块实例的数组长度不同,但在对象的生存期内保持不变。
这在库编程中是有用的,例如,用于实现通用库 POU。
FUNCTION_BLOCK FB_MyString
VAR_GENERIC CONSTANT
maxlen : UDINT := 1;
END_VAR
VAR
test : ARRAY[0..maxlen-1] OF BYTE;
END_VAR
;
PROGRAM PLC_PRG
VAR CONSTANT
cconst: DINT := 1000;
END_VAR
VAR
fbMyString1 : FB_MyString<100>;
fbMyString2 : FB_MyString<(2 * cconst)>;
arrMyString : ARRAY [0..5] OF FB_MyString<100>;
END_VAR
;
继承
具有一般常量的功能块还可以使用继承构造 EXTENDS 和 IMPLEMENTS。
EXTENDS 和 IMPLEMENTS ,因为通用常量也可以与基础类一起使用。
继承示例:
INTERFACE IString
METHOD Append : BOOL
VAR_INPUT
strAppend : IString;
END_VAR
METHOD Assign : BOOL
VAR_INPUT
stringIn: String;
END_VAR
METHOD ToString : STRING
VAR_INPUT
END_VAR
PROPERTY Length : DINT
FUNCTION_BLOCK MyString
VAR_GENERIC CONSTANT
maxlen : UDINT;
END_VAR
IMPLEMENTS IString
FUNCTION_BLOCK LongString EXTENDS MyString<1000>
FUNCTION_BLOCK MySpecialString
VAR_GENERIC CONSTANT
maxlen2 : UDINT:= 1;
END_VAR
EXTENDS MyString<maxlen2>
METHOD ToLatin1: STRING
PROGRAM PLC_PRG
VAR CONSTANT
cconst: DINT := 1000;
END_VAR
VAR
string1 : MyString<100>;
string2 : MyString<(2 * cconst)>;
derived1 : LongString;
derived2 : MySpecialString<100>;
END_VAR
string1.Assign ('Welt');
string2.Assign ('Hallo ');
string2.Append(string1);
derived2.ToLatin1('Hello World');
基本上,在使用 IEC 常量中,将使用最小可用的数据类型。如果必须使用其他数据类型,则可以通过类型化文字来实现,而不必显式声明常量。因此,将为常量提供一个用于确定类型的前缀。
语法
<类型>#<文字>;
|
<类型> |
指定所需的数据类型 可用的条目:BOOL, SINT, USINT, BYTE, INT, UINT, WORD, DINT, UDINT, DWORD, REAL, LREAL 请以大写字母书写类型。 |
|
<文字> |
指定常量 输入属于 <类型> 下指定的数据类型的数据。 |
示例
iVar1:=DINT#34;
如果常量无法转换在不丢失数据的情况下转换为目标类型,则会发出一条消息。
只要能够使用正常常量的场合中,都可以使用类型化文字。