数据类型是IEC 61131-3编程语言的重要内容。它定义文字和变量可能的值、可以进行的操作和存储其值的方法。
IEC 61131-3第三版增加用户定义的数据类型,包括枚举数据类型、带指定值的枚举数据类型、数组数据重复等。
1.基本数据类型
基本数据类型(Elementary data types)是在标准中预先定义的标准化数据类型。它有约定的数据允许范围及约定的初始值。基本数据类型名可以是数据类型名、时间类型名、位串类型名、STRING、WSTRING、CHAR、WCHAR、TIME、LTIME等。表1-13是基本数据类型的性能。
基本数据类型字符串包括STRING、WSTRING、CHAR、WCHAR。实施者规定STRING和WSTRING类型支持的最大长度。实际应用的最大长度由相关声明中括号内最大长度确定。
【例1-1】字符串长度的声明。
VAR
String1:STRING[10]:='ABCD'; //字符串String1的长度是10字符,初始值是“ABCD”
String2:STRING[10]:=''; //字符串String2的长度是10字符,初始值是空串
aWStrings:ARRAY[0..1]OFWSTRING:=[''1234'',''5678''];
//双字节字符串aWStrings是两维双字节字符串WSTRING,初始值是[''1234'',''5678'']
Char1:CHAR; //字符Char1是单字节字符,占8位,初始值是'$00'
WChar1:WCHAR; //字符WChar1是双字节字符,占16位,初始值是'$0000'
END_VAR
单字节字符(CHAR)和双字节字符(WCHAR)的数据类型只包含一个字符。而字符串可包含几个字符,例如,示例中String1可存储10个字符,初始字符是“ABCD”。因此,字符串需要附加的管理信息。采用CHAR和WCHAR可简化程序的操作。详见数据类型转换的有关内容。
基本数据类型的默认初始值是系统提供的初始值,见表1-13。
2.一般数据类型
一般数据类型(generic data type)也称为类属数据类型。它用前缀ANY标识。一般数据类型是编程系统使用的数据类型,它们被用在标准函数和功能块的输入和输出,规定它们的数据类型。
使用一般数据类型时的注意事项如下:
1)一般数据类型不能用于用户声明的POU。
2)与派生的基本数据类型一样,直接派生类型的一般数据类型与导出该基本数据类型的一般数据类型相同。
3)子范围数据类型的一般数据类型是ANY_INT。
4)图1-9是一般数据类型的分级结构。它定义了所有其他派生的一般数据类型是ANY_DERIVED。
图1-9 一般数据类型的分级结构
3.用户定义的数据类型
用户定义的数据类型(User-defined data type)被用于其他数据类型的声明和用于变量声明中,可以用于任何基本数据类型可被使用的地方。用户定义的数据类型是用户为应用需要而定义的数据类型。因此,用户定义的数据类型应便于建立数据模型。用户定义的数据类型也称为派生数据类型、衍生数据类型或导出数据类型。
派生数据类型所定义的变量是全局变量。它可用与基本数据类型所使用的相同方法对变量进行声明。
用户定义数据类型用TYPE…END_TYPE文本结构来声明,即用TYPE关键字开始,中间是用户定义数据类型声明,最后用END_TYPE关键字结束。
用户定义数据类型有枚举数据类型、子范围数据类型、数组数据类型、结构数据类型、直接派生数据类型等。用户定义的数据类型可用用户定义的初始值来初始化。该初始值的优先级高于系统默认的初始值。所用用户定义的值的数据类型可以是兼容类型的,即系统的数据类型或用隐式数据类型转换进行转换的数据类型。
用户定义的数据类型需要赋予初始值时,采用直接赋值符。其格式如下:
数据类型:=用户定义的初始值;
表1-14是用户定义的数据类型和初始化声明。
表1-14 用户定义的数据类型和初始化声明
(续)
(续)
注:数据类型的声明可以没有初始化(性能a)或有初始化(性能b)。如果只支持性能a,该数据类型初始化用默认的初始值。如果支持性能b,该数据类型可用用户给定的值初始化或如果没有给出初始值时,用系统默认的初始值。
①使用待定的“*”的部分直接表示元素的结构变量不能用于VAR_INPUT、VAR_IN_OUT或VAR_TEMP段
(1)枚举数据类型
枚举数据类型(Enumerated data type)的声明规定该数据类型的任何一个数据元素只能取在相应的枚举列表中给出的值,例如,表1-14的1a和1b中,ANALOG_SIGNAL_RANGE枚举数据类型有6种值可选,即模拟信号BIPOLAR_10V(±10V)、UNIPOLAR_10V(0~10V)、UNIPOLAR_1_5V(1~5V)、UNIPOLAR_0_5V(0~5V)、UNIPOLAR_4_20_MA(4~20mA)和UNIPOLAR_0_20_MA(0~20mA)。
使用枚举数据类型时的注意事项如下:
1)枚举列表是枚举值的有序集合,它开始于列表的第一个标识符,终止于列表的最后一个。
2)不同枚举数据类型的枚举值可使用相同的标识符。但在枚举文本中没有提供足够信号来明确地确定它的值时,则出错。为此,可用该枚举数据类型+“#”+枚举值表示,使其在系统中可唯一识别。
【例1-2】枚举数据类型的枚举值使用相同标识符,造成出错。
//但改为:IFMy_Traffic_light=Traffic_light#RedTHEN...stop..END_IF;就不出错
3)枚举数据类型的默认初始值是相应枚举列表的第一个标识符。例如,
Colors:DWORD(Red:=16#00FF0000,Green:=16#0000FF00,Blue:=16#000000FF,White:=Red OR Green OR Blue,Black:=Red AND Green AND Blue)的默认初始值是Red。
4)可采用带指定值的数据类型。例如,表1-14中的序号2a和2b。初始化不限于指定值,也可使用基本数据类型范围内的任何值。声明的指定值不限制这些数据类型的变量值的使用范围,即其他常数也能够被赋值,或能够通过计算生成。
5)用户定义的初始值比系统默认初始值具有更高优先级。即应用时,有上述两个初始值时,优先采用用户定义的初始值。
(2)子范围数据类型
子范围数据类型(Subrange data type)的数据元素值只能取规定子范围的上、下限之间(包括上、下限)的值。例如,表1-14中的序号3a和3b。示例中,INT数据类型的允许范围是-32768~32767,如果应用的数据范围在该数据类型允许的范围内部时,需要定义子范围数据类型。示例显示某类数据ANALOG只允许取值范围为-4095~4095,则需要定义子范围数据类型。
子范围数据类型的取值范围由子范围确定。用圆括号和内部的子范围表示,子范围用“下限值..上限值”表示。如果子范围数据值落在特定的取值范围之外则出错。子范围数据类型的默认初始值是该子范围中的第一个限值,即下限值。例如,示例的默认初始值是-4095,实际初始值采用用户定义的初始值0。
【例1-3】子范围数据类型的应用。
TYPE
MOTOR_VOLTS: REAL(-6.0..12.0);
END_TYPE
MOTOR_VOLTS变量被定义为子范围数据类型。即直流电动机的电压范围是-6.0~12.0V,从而保证当电压超出范围时,数据仍能在该范围内。
(3)数组数据类型
数组数据类型(Array data type)由多个相同数据类型的数据元素组成。数组数据类型用ARRAY表示,用方括号内的数据定义其范围,然后是OF和采用的相同数据类型名和可选的“:=”和用户定义的初始值,例如表1-14中序号4a和4b的示例。
使用数组数据类型时的注意事项如下:
1)数组数据类型用于定义具有相同数据类型的多个数据元素,如果数据元素的数据类型不同,则应采用结构数据类型。
2)数组数据类型的下标说明其大小,用方括号定义,对多维数组,用逗号分隔。每个维数范围用“1..维数值”表示。
【例1-4】多维数组的表示。
TYPE
AI5:ARRAY[1..5,1..8]OF ANALOG;
END_TYPE
示例声明AI5是一个5×8维的数组数据,它们的数据元素有相同数据类型ANALOG。
3)数组数据类型的取值根据该数据类型的单元素的数据类型取值的范围确定。例如,该元素的数据类型是INT,则取值范围是-32768~32767。可用“*”表示变长度的数组,例如,“ARRAY[*,*]OFINT;”。
4)如果用户没有定义的初始值,各数据元素的初始值根据该基本数据类型的默认初始值确定。
5)用户定义初始值时,可采用重复因子方法,对数组数据的各数据元素定义用户的初始值。
6)重复因子方法是对N个数据元素赋相同数据M的方法。当数组中有连续的若干数据类型都需要赋予相同初始值时,用圆括号前的值说明相同数据类型个数N,圆括号内的值是用户定义的初始值M。
【例1-5】数组数据类型的重复因子。
TYPE
AI:ARRAY[1..8]OF REAL:=7(4.0);
END_TYPE(www.xing528.com)
示例声明AI是数组数据类型,为一维的REAL数据类型,共有7个数据的初始值是4.0。最后一个数据初始值是0.0。它对应于实际应用的8通道AI模拟量输入板,7个输入电流初始值为4.0mA,最后一个输入通道短路连接。
IEC61131-3第三版增加了可用功能块类型和类作为数组元素的性能。表1-14中序号5a和5b的示例,将标准功能块TON作为数据元素的数据类型,并对相同的50个接通延迟定时器的计时设定值PT定义了用户的初始值T#100ms。
7)初始化一个数组类型时,用户初始值由初始化列表给出。如果初始化列表给出的数据个数超出数组实体的个数,则超过部分(最右面)的初始值被忽略。如果初始化列表的数据个数小于数据实体的个数,则剩余的数组实体用其对应数据类型的默认初始值。例如,示例中最后一个数据为0.0。
(4)结构数据类型
当不同数据类型组合时,可采用结构数据类型(Structured data type),结构数据类型由多种不同数据类型组合。结构数据类型格式是从“结构数据类型名:”及结构关键字“STRUCT”开始,中间包含一个特定类型的子元素的集合,最后是END_STRUCT。
【例1-6】结构数据类型的声明。
结构数据类型用于将多个不同数据类型组合在一起。示例中,结构数据类型AI_Board有三个子元素Range、Min和Max,它们的数据类型分别是SIGNAL_RANGE、ANALOG和ANALOG。这些数据类型是用户定义的数据类型。因此应分别根据它们的数据类型所允许的取值范围确定。例如,如果是ANALOG数据类型,则根据表1-14中序号3a和3b,所允许的取值范围是-4095~4095。
使用结构数据类型时的注意事项如下:
1)IEC61131-3第三版扩展了结构数据类型子元素数据类型的应用范围。结构数据类型结构元素的数据类型可以是基本数据类型(例如,表1-14中序号7a和7b示例中Temp的数据类型为INT)、用户定义的数据类型(例如,表1-14中序号6a和6b示例中RANGE的数据类型为ANALOG_SIGNAL_RANGE枚举数据类型)、功能块类型和类(例如,表1-14中序号7a和7b示例中Cooling的数据类型为TOF功能块类型)、带寻址AT(例如,表1-14中序号8a和8b示例中head的数据类型为AT%B0:INT基本数据类型等)、带重叠的AT(例如,表1-14中序号9a和9b示例中data1AT%B5:BYTE;和data2 AT%B5:REAL;)和带*符号表示部分直接表达的输入和输出(例如,表1-14中序号10a和10b示例中INAT%I*:BOOL;和OUT_VARAT%Q*:WORD:=200;)等。
2)结构数据类型各子元素的取值范围根据各自元素数据类型的取值范围。例如,表1-14中序号7a和7b示例中Temp的数据类型是INT,因此,其取值范围是-32768~32767。表1-14中序号6a和6b示例中RANGE是ANALOG_SIGNAL_RANGE枚举数据类型,根据表1-14中序号1a和1b示例,其取值范围是6种输入信号范围。
3)结构数据类型的各子元素的初始值根据各自元素数据类型的初始值。例如,表1-14中序号7a和7b示例中Temp的数据类型是INT,因没有用户定义的初始值,因此,用系统默认初始值-32768。表1-14中序号6a和6b示例中RANGE是ANALOG_SIGNAL_RANGE枚举数据类型,其初始值是用户定义的初始值UNIPOLAR_1_5V。
4)结构数据类型元素的位置(寻址地址)是相对于结构的开始位置。该结构数据的每个元素名称应跟在关键字AT后面,并表示其相对位置。相对位置由“%”(百分数符号)、位置前缀和位或字节位置组成。字节位置是一个无符号整数文字,表示字节偏移量。位的位置是由字节的偏移量、“.”(点)和位的偏移量组成,位的偏移量是一个0~7范围的无符号整数。在相对位置内是不允许空格的。除了用关键字OVERLAP声明其是重叠外,结构数据类型元素不应在它们的存储分布上重叠。位偏移的计数从最右位的0开始,字节偏移的计数从该结构字节偏移的0开始。
【例1-7】结构数据类型元素的相对位置和重叠。
5)采用部分待定的“*”符号的结构数据类型的直接表示部分中,“*”符号表示未确定输入和输出位置的结构数据类型。当用于一个程序、功能块类型或类时,在声明段的定位部分,“*”符号表示其大小前缀的位置,并且在串联中的无符号整数用于声明直接表示待确定。可见表1-14中序号10a和10b的示例。这类变量不能用于VAR_INPUT、VAR_IN_OUT或VAR_TEMP段。
6)使用部分待定的“*”符号的结构数据类型时,对每个所包含类型的实例,其结构变量的位置应在VAR_CONFIG…END_VAR结构中完整声明。
(5)直接派生数据类型
直接派生数据类型(Directly derived data type)是从基本数据类型或用户定义的数据类型直接派生的数据类型。
直接派生数据类型与其父的数据类型允许的取值范围一致。直接派生数据类型的默认初始值与其父的数据类型的默认初始值相同。
用户可定义直接派生数据类型的初始值,它的优先级高于系统默认的初始值。结构元素的用户定义的初始值在数据类型标识符后面的方括号内声明,在初始值列表中没有列出的初始值元素有系统默认的初始值,它们是这些元素在原始数据类型声明中的默认初始值。
【例1-8】直接派生数据类型的声明。
示例中,用IT作为直接派生数据类型,即INT数据类型,其初始值默认为4。
表1-14中序号11a和11b示例中,CNT是直接派生数据类型,即UINT数据类型,其初始值是UINT的系统默认初始值0;FREQ是直接派生数据类型,即REAL数据类型,其初始值是用户默认初始值50.0。
【例1-9】直接派生数据类型的初始化。
myNewArrayType是直接派生数据类型,其父类的数据类型是ANALOG_16_INPUT_DATA,初始值在方括号内表示,前8个初始值是-1023,后8个初始值是1023。Com3_data是直接派生数据类型,其父类的数据类型是Com2_data结构数据类型,其中,head的初始值是3,length的0初始值是40。
(6)用户定义的数据类型的嵌套
用户定义的数据类型可作为其他用户定义的数据类型的基础。用户定义数据类型的单元素变量能够使用在它父类的变量能够使用的任何地方。即用户定义的数据类型可以嵌套,但需注意,如果这种嵌套造成递归,则这种嵌套是非法的。
【例1-10】用户定义的数据类型的非法嵌套。
例1-10中,结构数据类型S1中变量A2递归调用S2,而S2中变量A1递归调用S1,这样就造成嵌套递归结构。
(7)数据类型的初始化
IEC61131-3标准规定,数据类型的初始化是PLC系统启动时对有关数据类型赋予初始值的过程。变量的初始化是变量在系统启动时对变量赋予初始值的过程,见下述。
数据类型的初始值有下列优先级:
1)用户定义的数据类型初始值具有高优先级。
2)系统默认的数据类型初始值具有低优先级。
4.引用和解引用
引用(Reference)是一个变量,它只包含对一个变量或一个功能块实例的引用。引用可有一个值NULL,即它不引用什么。引用表示被引用者和引用者有相同的数据类型。引用者是被引用者的别名。
(1)引用的声明
对一个已定义的数据类型,引用采用关键字REF_TO和一个数据类型(该引用的数据类型)来声明。该引用的数据类型应该已经被定义,它可以是基本数据类型或用户定义的数据类型。引用绑定一个数据类型,不绑定数据类型的引用超出本标准的范围。
【例1-11】引用的声明。
使用引用时的注意事项如下:
1)引用必须绑定一个数据类型。例如,例1-11中,myRefArrType标识符引用了myArrayType数据类型,它的数据类型是一维整数数组数据类型,即myRefArrType标识符是一维整数数组数据类型的别名。
2)引用只引用给定引用数据类型的变量。引用到直接派生数据类型是指它是基本数据类型引用的一个别名,可以多次引用,例如,例1-11中,myArrOfRefType标识符引用了myRefArrType数据类型,myRefArrType标识符表示的数据类型引用了myArrayType。
3)一个引用的引用数据类型也可以是功能块类型或类。一个基本数据类型的引用也可是该基本类型的派生数据类型实例的引用。
【例1-12】引用的数据类型是一个类。
(2)引用的初始化
引用可用值NULL(默认)或一个已经声明的变量、功能块或类的实例值来初始化。
【例1-13】引用的初始化。
(3)引用操作
引用操作采用REF()操作符。它返回一个引用到给定变量或实例。返回引用的引用数据类型是给定变量的数据类型。不允许对暂存变量(VAR_TEMP声明段声明的变量和在函数中的任何变量)进行引用操作。
【例1-14】引用操作。
引用操作的结果是对该数据类型的变量值赋值。而派生数据类型不能被赋值。
引用操作时应注意下列事项:
1)如果引用数据类型是等于基本数据类型或是已赋值引用的引用数据类型的基本数据类型,则引用能够赋值到另一个引用。而派生数据类型只是数据类型,不能被赋值。
2)如果参数引用的数据类型等于基本数据类型或是引用数据类型的基本数据类型。在调用时,引用能够给一个函数、功能块或方法的参数赋值。需注意它们应具有相同数据类型。
3)引用不能用于输入-输出变量的赋值。
4)如果引用被用于对一个同样数据类型的引用赋值,则后者引用同样的变量。这种情况下,直接派生数据类型被认为是它的基本数据类型。
5)如果引用被用于对一个同样功能块类型的引用或一个基本功能块类型的引用赋值,则该引用将引用同样的实例,但它仍与它的功能块类型绑定,即只能用它的引用数据类型的变量和方法。
(4)解引用
引用可以解除,只需要在引用后添加“^”符号。解引用指将变量或实例的内容直接给该引用的引用变量,而不说明是从该引用所得,故也称为去引用。派生数据类型没有解除派生数据类型的操作功能。
【例1-15】解引用。
图形描述如图1-10所示。
图1-10 例1-15解引用的图形描述
NULL引用不能进行解引用。为此,编译和应用程序检查引用是否是NULL引用。表1-15是引用操作和解引用的示例。
表1-15 引用操作和解引用
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。