与数据的外部表示相反,变量提供能够改变其内容的识别数据对象的方法。例如,可改变与PLC输入、输出或存储器有关的数据。变量与数据类型结合,从而在存储空间规定对应的存储位置。这是与传统编程语言的重大区别。传统编程语言规定存储空间的类型与对应的继电器类型一致。因此,存储空间的分配不合理。例如,某类继电器类型用完,则其他类型的继电器存储空间不能用于该类型继电器的使用,造成存储资源的浪费。
与数据外部表示的文字相反,变量能够随时改变它们的值。
1.变量段和变量的声明
在POU的函数、功能块、程序和附加的方法的声明中,都有零个或多个特定的段落,用于对在该POU内使用的变量进行声明。这些段落称为变量段(Variable section)。
不同类型的POU,因其功能不同,有不同的变量段。
(1)变量的属性
一个变量可以是以下类型:
1)一个单元素变量,即变量的数据类型:
①可以是一个基本数据类型。
②也可以是用户定义的枚举数据类型或子范围数据类型。
③或其父系,递归定义的,可溯源到基本、枚举或子范围的用户定义的数据类型。
2)多元素变量,即用ARRAY或STRUCT表示的数组或结构变量。
3)一个引用,即引用到另一个变量或功能块实例的变量。
IEC 61131-3标准对变量定义了属性。通过设置变量属性将它们的有关性能赋予变量。表1-16是变量的类型和属性表。除了上述变量类型外,IEC 61131-3还对变量提供变量的附加属性(限定),见表1-17。
表1-16 变量类型和属性
表1-17 变量的附加属性
(2)变量的声明
变量声明用于声明变量的类型(包括附加属性)、变量名、变量的数据类型、变量的初始值。
变量声明时注意下列事项:
1)变量声明的格式:
变量类型关键字
变量名列表:变量的数据类型(:=用户定义的初始值);
//在相同的变量类型内,不同变量名的变量声明部分可重复
END_VAR
表1-18是变量声明的示例。
表1-18 变量声明的示例
2)变量类型关键字见表1-16。如果变量有附加属性(即对变量的限定属性),则在变量类型关键字后,列出该变量附加属性关键字,两者之间应有空格分隔。
3)变量名应符合标识符的规定,不允许用关键字作为变量名。
4)变量的数据类型是变量的重要性能,它表示该变量的存储空间大小,是系统分配该变量存储空间位置的重要依据。数据类型见1.4.3节。
5)圆括号的内容是可选的,如果设置用户定义的变量数据类型的初始值,需要将圆括号去除。如果不设置用户定义的变量数据类型的初始值,则将圆括号的整个内容去除,采用该变量数据类型的系统默认初始值。
6)引用变量的系统默认初始值是NULL。基本数据类型的默认初始值见表1-13。
7)用户定义的初始值可以是直接表示的数值,也可以是常数表达式表示的数值,可在变量声明段用赋值符号“:=”规定。
8)VAR_EXTERNAL变量声明段声明的外部变量是外部提供的变量,因此,不能赋初始值。
9)初始值也可以用VAR_CONFIG…END_VAR结构提供的用实例规定的初始化性能来确定。实例规定的初始值通常覆盖类型规定的初始值。
【例1-16】初始值的赋值。
VARCONSTANT
Pi:REAL:=3.141593; /*圆周率作为常量变量Pi,初始值用直接表示的数值*/
TwoPi:REAL:=2.0*Pi; /*圆周率的两倍,用表达式表示,作为常数变量TwoPi的初始值*/
END_VAR
变量类型和附加属性声明时应注意下列事项:
1)在VAR…END_VAR变量声明段声明的内部变量在程序和功能块实例从一次调用到下一次调用时其变量的值是保留不变的。但函数和方法在一次调用到下一次调用时,该内部变量的值不被保留。
2)对函数和方法,在VAR…END_VAR变量声明段声明的内部变量和在VAR_TEMP…END_VAR变量声明段声明的暂存变量,其效果相同,即VAR_TEMP…END_VAR变量声明段声明的暂存变量只在这一次调用时才有效,在两次调用之间该变量的值不被保留。
3)在VAR_INPUT、VAR_OUTPUT和VAR_IN_OUT变量声明段内声明的变量是函数、功能块类型、程序和方法的形式参数。
4)在VAR_GLOBAL…END_VAR变量声明段声明的全局变量只在声明的配置或资源中是全局变量,即在配置中声明的全局变量可在该配置中被读写,在资源中声明的全局变量只可在该资源中被读写。在配置和资源中要读写全局变量时要采用VAR_EXTERNAL…END_VAR变量声明段声明的外部变量。需注意,全局变量的数据类型应与外部变量的数据类型一致。表1-19是全局变量和外部变量的用法。
表1-19 全局变量和外部变量的用法
注:在包含元素的VAR_EXTERNAL段的用法会导致意想不到的行为,例如,一个外部变量被另一个包含元素修改在同样的包含元素内。
5)被声明是全局变量的变量只能经VAR_EXTERNAL变量声明段声明来存取。在VAR_EXTERNAL变量声明段内声明的一个变量允许在相应程序、配置或资源的VAR_GLOBAL块声明其数据类型。
6)在VAR_ACCESS…END_VAR变量声明段声明的存取路径变量可用声明中规定的存取路径进行存取。
7)在VAR_CONFIG…END_VAR变量声明段声明的配置变量可赋值给实例的特定位置,用星号“*”表示变量或赋值给实例特定的初始值来符号化表示变量,或两者兼而有之。
8)在VAR、VAR_INPUT、VAR_OUTPUT和VAR_GLOBAL变量声明段内声明的变量允许使用附加属性RETAIN和NON_RETAIN。不允许在VAR_IN_OUT段声明使用附加属性RETAIN和NON_RETAIN。
9)当功能块类型、类和程序实例的声明段使用附加属性RETAIN和NON_RETAIN时,所有实例的成员都被处理为具有RETAIN和NON_RETAIN的属性。除非成员本身是功能块或类,或在功能块类型或程序类型的声明中明确声明被作为RETAIN和NON_RETAIN使用。
10)RETAIN或NON_RETAIN限定符可在静态VAR、VAR_INPUT、VAR_OUTPUT和VAR_GLOBAL的变量段声明变量,但不能在VAR_IN_OUT段声明。
11)功能块、类和程序实例的声明段,允许使用RETAIN或NON_RETAIN,其影响是在该实例中的所有变量都被处理为RETAIN或NON_RETAIN,除了下列情况:
①该变量被显式声明是功能块、类或程序类型定义的RETAIN或NON_RETAIN。
②变量本身是一个功能块类型或类,这时,被使用的功能块或类的保持属性的声明被使用。
12)结构数据类型实例的RETAIN或NON_RETAIN保持属性的使用是允许的。其影响是所有结构元素,包括它们的嵌套结构,都被处理为RETAIN或NON_RETAIN。
13)在VAR_CONFIG变量声明段允许使用附加属性RETAIN和NON_RETAIN。这时,所有该结构内变量的成员,包括嵌套结构的成员都具有相应的附加属性。
14)CONSTANT附加属性声明该变量是不允许改变其值的特殊变量(常量)。因此,没有必要同时对某个变量附加CONSTANT和RETAIN属性,只需要设置CONSTANT的附加属性。因掉电后的热启动时,该变量仍可保持该常量值。
15)上升沿和下降沿边沿检测属性只对输入变量有效。读写和只读属性只对存取路径变量有效。
16)附加属性的关键字紧跟在变量关键字后,例如“VAR CONSTANT;”“VAR_OUTPUT RETAIN;”等,但上升沿、下降沿边沿检测属性及读写、只读属性的关键字是在变量数据类型后,例如“VARR1:REAL R_EDGE;”“VAR RW: REAL READ_WRITE;”。
2.直接表示变量(www.xing528.com)
直接表示变量是直接规定存储器输入或输出的可寻址物理或逻辑地址之间相应关系的变量。它被用于函数、功能块、程序、方法、配置和资源中。符号%是直接表示变量关键字。直接表示变量的存储位置和存储空间的大小,用位置前缀和大小前缀表示。
直接表示变量的分级寻址用附加的英文句号“.”分隔。表1-20是直接表示变量的性能。
表1-20 直接表示变量的性能
①国家标准化组织可发布这些前缀的翻译表。
②“*”的使用需要VAR_CONFIG的性能,反之亦然。
简单的分级寻址只有1层。其后是用英文句号“.”分隔的其他各层。因此,分级寻址中最左的域是分级的最高层,最右的域是分级的最低层。例如,寻址地址%IW2.5.7.1表示变量存储在PLC系统的第2条I/O总线的第5个机架的第7个模块的第一通道(字)。分级寻址的地址是该变量的开始地址。
由于存储空间的地址分配是重叠的,因此,编程时应注意这点。图1-11是存储空间的地址分布。可以看到,字节B0和字节B1组成字W0,字节B1和字节B2组成字W1等,而字W0和字W2组成双字DW0等,其余类推。
图1-11 存储空间的地址分配
直接表示变量不能设置用户初始值。直接表示变量声明格式如下:
(变量名)AT直接表示变量的关键字,位置前缀和大小前缀,分级寻址的地址:数据类型(:=初始值);
分级的物理或逻辑地址中,其最左的域表示分级的最高层,而连接着的最低层出现在右面。
IEC 61131-3第三版定义直接表示变量可采用用户定义的变量名。
IEC 61131-3第三版扩展了直接表示变量,一个数组的变量能够用AT来赋值一个绝对存储位置。用户定义的数据类型也可用于直接表示变量。变量位置定义存储器位置的开始地址,它不需要等于或大于给出的直接表示,即允许空的存储或重叠。
【例1-17】用户定义的数据类型与直接表示变量。
3.使用星号“*”的部分待定存储地址的直接表示变量
在程序和功能块内部,星号“*”能够用于待定地址的赋值,声明该直接表示变量的存储地址是待定的。实际应用时,需用实参代入使用。
【例1-18】待定存储地址的输出变量。
VAR
C2 AT %Q*:BYTE; //输出C2是直接表示变量,其大小是字节,但位置待定
END_VAR
在内部变量VAR的声明段,直接表示变量用于表示位置是输入I、输出Q或存储M的变量时,可用星号“*”紧跟位置前缀,表示该变量是位置待定的直接表示变量。
使用待定存储地址的直接表示变量时,应注意下列事项:
1)待定存储地址的直接表示变量不能用于VAR_INPUT和VAR_IN_OUT的声明段。
2)在VAR_CONFIG…END_VAR的变量声明段,应采用实参说明其实际存储地址。如果没有声明其实际存储地址,则出错。
3)内部变量VAR的声明段,才可采用待定存储地址的直接表示变量。
4.可变长度的数组变量
下列情况可采用可变长度的数组变量:
1)作为函数和方法的输入变量、输出变量或输入-输出变量。
2)作为功能块的输入-输出变量。
使用可变长度的数组变量时注意下列事项:
1)数组的实参和形参的维数应相同。
2)应提供可变长度的数组变量的上下限范围。表1-21是可变长度数组变量的用法。
3)可变长度的数组变量为函数、功能块、方法和程序提供使用不同索引范围的数组的方法。它们定义星号“*”作为一个未定义的子范围用于索引范围。
表1-21 可变长度数组变量的用法
【例1-19】可变长度数组变量的示例。
假设数组A1和A2的变量声明如下:
对于数组A1,程序运行结果为:SUM(A1)的内容为10。
因为,LOWER_BOUND(A1,1)=1;UPPER_BOUND(A1,1)=10;A1(1)=A1(2)=…=A1(10)=1;因此,10个1的累加结果是10。
对于数组A2,程序运行结果为:SUM(A2[2])的内容为5。
因为,LOWER_BOUND(A2,2)=-2;UPPER_BOUND(A2,2)=2;A2[1,-2]=A2[1,-1]=…=A2[1,2]=1;因此,5个1的累加结果是5。
为计算两个2×2维矩阵相乘结果,编写下列用户的函数(没有返回值的函数):
5.变量的初始化
变量在系统启动时进行初始化(Initialization)。初始化后变量的值根据下列准则确定。
1)具有RETAIN掉电保持属性的变量,在掉电后再启动时,变量初始值是掉电前的保持值。
2)用户定义初始值的变量,在变量初始化时,其初始值是用户定义的初始值。
3)没有用户定义初始值的非保持变量,在变量初始化时,其初始值是系统的默认初始值。
电源掉电后的再启动,称为系统的暖启动(Warm Restart)。这时,变量的值应根据是否有附加属性RETAIN来确定。如果具有该属性,则变量恢复到掉电前的值。如果没有该属性,则称为系统的冷启动(Cold Restart)。这时,变量初始值由用户定义的初始值或变量对应的数据类型的默认初始值(当没有用户定义的初始值时)确定。
变量初始值取值有优先级。准则表明,RETAIN提供最高优先级(即准则中的1)),系统默认初始值提供最低优先级(即准则中的3))。
变量初始化时的注意事项如下:
1)用户定义的初始值可以是文字(例如,-123,1.55,"abc")或常量表达式(例如,12*24)。IEC61131-3第三版增强了赋初始值的功能,因此,常量表达式可作为初始值。
2)对引用变量,其初始值是NULL。
3)变量的初始值可以是在类型化数据类型时,通过赋值符号“:=”提供,也可以在变量声明段用赋值符号“:=”提供。在VAR_CONFIG…END_VAR变量声明段,可用实例规定的初始化性能提供变量的初始值,它将覆盖数据类型规定的初始值。
4)用户不能定义从外部输入变量的初始值。因此,VAR_EXTERNAL、VAR_INPUT变量声明段声明的变量不能赋予初始值。
表1-22是变量初始化示例。
表1-22 变量初始化示例
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。