正文11.docx
《正文11.docx》由会员分享,可在线阅读,更多相关《正文11.docx(11页珍藏版)》请在冰豆网上搜索。
正文11
11数据类型(DataTypes)
11.1标准数据类型
11.1.1.1数据类型
在编程的时候可以使用标准数据类型和用户自定义数据类型。
每个标识符都定义了数据类型,它指示被保留存储空间的大小以及存储的数值类型。
11.1.1.2布尔类型(BOOL)
BOOL类型变量的值为TRUE和FALSE.。
8位存储空间将被保留。
(参看:
BOOL常量)
11.1.1.3整数类形(IntegerDataTypes)
BYTE,WORD,DWORD,SINT,USINT,INT,UINT,DINT,和UDINT都是整数类型。
每个不同的数字类型包括不同的数值范围。
以下范围限制将适用于整数类型:
类型
低限
高限
存储空间
BYTE
0
255
8Bit
WORD
0
65535
16Bit
DWORD
0
4294967295
32Bit
SINT
-128
127
8Bit
USINT
0
255
8Bit
INT
-32768
32767
16Bit
UINT
0
65535
16Bit
DINT
-2147483648
2147483647
32Bit
UDINT
0
4294967295
32Bit
当大范围的类型转换为小范围的类型时,信息可能会丢失。
参看:
数字常量
11.1.1.4实数(REAL)
实数也称为浮点类型。
实数需要表现有理数。
实数的存储空间为32位。
参看附录F:
实数常量
11.1.1.5字符串(STRING)
字符串变量可包含任意字符。
声明中输入的尺寸决定了将为变量保留多少存储空间。
它指出字符串中字符的数量,并放在圆括号或方括号中。
如果没有指定大小,将使用80个字符的默认值。
例如:
具有35个字符的字符串声明:
str:
STRING(35):
='ThisisaString';
参看:
字符串常量
11.1.1.6时间数据类型(TimeDataTypes)
数据类型TIME,TIME_OF_DAY(缩写TOD),DATE和DATE_AND_TIME(缩写DT)如同DWORD类型,是内部操作。
在TIME和TOD中,时间以毫秒给出,TOD的时间从12:
00A.M.开始。
在DATE和DT中,时间以秒给出,从1970年1月1日的12:
00A.M.开始。
参看以下时间数据格式以为时间常量分配值:
TIME常量:
总是以字首字母"t"或"T"(由"time"或"TIME"拼出来的)和一个数字符号"#"构成。
其后跟随实际时间的声明,包括天(以"d"表示),小时(以"h"表示),分钟(以"m"表示),秒(以"s"表示)和毫秒(以"ms"表示)。
请注意时间必须按照一定顺序(天,小时,分钟,秒,毫秒)输入,但不必都包括。
例如:
在ST赋值语句中正确的时间常量:
TIME1:
=T#14ms;
TIME1:
=T#100S12ms;(*Thehighestcomponentmay
beallowedtoexceeditslimit*)
TIME1:
=t#12h34m15s;
下面的写法是不正确的:
TIME1:
=t#5m68s;(*limitexceededinalower
component*)
TIME1:
=15ms;(*T#ismissing*)
TIME1:
=t#4ms13d;(*Incorrectorderofentries*)
DATE常量:
以"d","D","DATE"或"date"开始,后面跟随"#"。
你可以Year-Month-Day的格式输入日期。
例如:
DATE#1996-05-06
d#1972-03-29
TIME_OF_DAY常量,用于储存日时间:
以"tod#","TOD#","TIME_OF_DAY#"或"time_of_day#"开始,后跟一个时间,时间的格式为:
小时:
分钟:
秒。
秒可以作为实数输入或输入一个秒的分数。
例如:
TIME_OF_DAY#15:
36:
30.123
tod#00:
00:
00
DATE_AND_TIME常量,结合了日期和时间:
以"dt#","DT#","DATE_AND_TIME#"或"date_and_time#"开始。
在日期的后面用连号连接时间。
例如:
DATE_AND_TIME#1996-05-06-15:
36:
30
dt#1972-03-29-00:
00:
00
11.2定义数据类型
11.2.1.1数组(ARRAY)
1维,2维和3维数组作为基本数据类型来支持。
数组可以在POU的声明部分和全局变量表中定义。
语法结构:
:
ARRAY[..,..]OF
.
ll1,ll2,ll3为数组的下限;ul1,ul2和ul3为数组的上限。
范围值必须是整数。
例如:
Card_game:
ARRAY[1..13,1..4]OFINT;
初始化数组:
例如:
一个数组的完整初始化。
arr1:
ARRAY[1..5]OFINT:
=1,2,3,4,5;
arr2:
ARRAY[1..2,3..4]OFINT:
=1,3(7);
(*shortfor1,7,7,7*)
arr3:
ARRAY[1..2,2..3,3..4]OFINT:
=2(0),4(4),2,3;
(*shortfor0,0,4,4,4,4,2,3*)
例如:
一个结构数组的初始化。
TYPESTRUCT1
STRUCT
p1:
int;
p2:
int;
p3:
dword;
END_STRUCT
ARRAY[1..3]OFSTRUCT1:
=
(p1:
=1;p2:
=10;p3:
=4723),(p1:
=2;p2:
=0;p3:
=299),
(p1:
=14;p2:
=5;p3:
=112);
例如:
一个数组的部分初始化。
arr1:
ARRAY[1..10]OFINT:
=1,2;
没有预先分配数值的单元将初始化为基本类型的默认值。
在上述例子中,数组单元[6]至单元[10]被初始化为0。
使用以下语法结构,在二维数组中访问数组单元:
[Index1,Index2]
例如:
Card_game[9,2]
提示:
如果在项目中使用CheckBounds名定义了一个功能,则在项目中可用它来检查溢出范围。
11.2.1.2Checkbounds功能
如果在项目中使用CheckBounds名定义了一个功能,则在数组中可自动检查超出范围(out-of-range)错误。
功能名被固定并只有这个名称。
CheckBounds功能的例子。
下列测试CheckBounds功能的程序实例超出了已定义数组的范围。
CheckBounds功能允许数值TRUE被分配,不是在A[10],而是在有效界限A[7]之上。
使用CheckBounds功能,数组边界的外围是正确的。
CheckBounds功能的测试程序
11.2.1.3指针(Pointer)
当程序运行时,变量或功能块地址被存储到指针中。
按以下语法结构声明指针:
:
POINTERTO;
指针可以指向任何数据类型或功能块甚至是用户自定义类型。
地址操作符ADR的功能是将变量或功能块的地址分配给指针。
在指针标识符之后加上操作符"^"可废除指针。
例如:
pt:
POINTERTOINT;
var_int1:
INT:
=5;
var_int2:
INT;
pt:
=ADR(var_int1);
var_int2:
=pt^;(*var_int2isnow5*)
11.2.1.4枚举(Enumeration)
枚举是用户自定义数据类型,是由一些字符串常量组成。
这些常量被作为列举值
枚举值在项目的所有区域中被识别,即使其被声明在一个POU中。
在对象管理器的登记卡Datatypes下创建列举。
以关键字TYPE开始,并以END_TYPE结束。
语法结构:
TYPE:
(,,...,);
END_TYPE
类型变量具有一个枚举值,并被初始化为第一个值。
这些数值和整数是兼容的,这意味着你可以使用它们完成操作正象你使用INT一样。
你可以分配一个数字x给变量。
如果枚举值没有被初始化,其将从0开始计算。
当初始化后,确定这个初始值是增加的。
在运行过程中数字的正确性将被重新检查。
例如:
TYPETRAFFIC_SIGNAL:
(Red,Yellow,Green:
=10);(*The
initialvalueforeachofthecolorsisred0,
yellow1,green10*)
END_TYPE
TRAFFIC_SIGNAL1:
TRAFFIC_SIGNAL;
TRAFFIC_SIGNAL1:
=0;(*Thevalueofthetrafficsignal
isred*)
FORi:
=RedTOGreenDO
i:
=i+1;
END_FOR;
相同的枚举值不能被使用两次。
例如:
TRAFFIC_SIGNAL:
(red,yellow,green);
COLOR:
(blue,white,red);
Error:
redmaynotbeusedforbothTRAFFIC_SIGNALand
COLOR.
11.2.1.5结构(Structures)
在对象管理器中的登记卡Datatypes下,结构作为对象被创建。
以关键字TYPE和STRUCT开始,并以END_STRUCT和END_TYPE结束。
结构声明的语法结构如下:
TYPE:
STRUCT
.
.
END_STRUCT
END_TYPE
是在整个项目中所识别的类型,并可象标准数据类型一样使用。
联锁结构是允许的。
唯一的限制就是变量不可以放置地址(AT声明不允许!
)。
例如:
命名为Polygonline的结构定义。
TYPEPolygonline:
STRUCT
Start:
ARRAY[1..2]OFINT;
Point1:
ARRAY[1..2]OFINT;
Point2:
ARRAY[1..2]OFINT;
Point3:
ARRAY[1..2]OFINT;
Point4:
ARRAY[1..2]OFINT;
End:
ARRAY[1..2]OFINT;
END_STRUCT
END_TYPE
例如:
结构的初始化。
Poly_1:
polygonline:
=(Start:
=3,3,Point1=5,2,Point2:
=7,3,Point3:
=8,5,Point4:
=5,7,End:
=3,5);
使用变量初始化是不可能的。
参看'Arrays'下结构数组的初始化例子。
使用如下语法结构获得对对结构单元的访问:
.
例如,如果有一个名为"Week"的结构,它包含一个名为"Monday"的单元,可按下列方法获得它:
Week.Monday
11.2.1.6参考(References)
使用用户自定义的参考数据类型来为变量,常量或功能块创建一个替换名字。
在对象管理器中的登记卡Datatypes下,参考作为对象被创建。
以关键字TYPE开始,并以END_TYPE结束。
语法结构:
TYPE:
;
END_TYPE
例如:
TYPEmessage:
STRING[50];
END_TYPE;
11.2.1.7子域类型(Subrangetypes)
子域类型的数值范围是基本类型的子集。
声明可以在数据类型登记卡中完成,但变量也可直接使用子域类型来声明:
在'Datatypes'登记卡中声明的语法结构:
TYPE:
(..)END_TYPE;
必须是一个正确的IEC标识符,
是下列数据类型之一:
SINT,USINT,INT,UINT,DINT,UDINT,BYTE,WORD,DWORD(LINT,ULINT,WORD)。
是一个常数,必须与基本类型一致,且规定了范围类型的下
限。
下限本身包含在这个范围内。
是一个常数,必须与基本类型一致,且规定了范围类型的上
限。
上限本身包含在这个范围内。
例如:
TYPE
SubInt:
INT(-4095..4095);
END_TYPE
使用子域类型直接声明变量:
VAR
i:
INT(-4095..4095);
ui:
UINT(0..10000);
END_VAR
如果一个常量被赋值给一个子域类型(在声明中或在执行中),但不属于
这个范围(例如,1:
=5000),则会出现一个错误信息。
在运行过程中为了检测范围的界限,功能CheckRangeSigned或CheckRangeUnsigned必须被引进。
在这种情况下,超出界限可用适当的方法和手段记录下来(例如,切除超出的值或设定错误标志)。
当属于一个子域类型(由符号类型或无符号类型构造)的变量被写入时,它们被隐含调用。
例如:
当变量属于带符号子域类型时,功能CheckRangeSigned被调用;它可以按下面的方法将一个数值修整到允许的范围:
FUNCTIONCheckRangeSigned:
DINT
VAR_INPUT
value,lower,upper:
DINT;
END_VAR
IF(valueCheckRangeSigned:
=lower;
ELSIF(value>upper)THEN
CheckRangeSigned:
=upper;
ELSE
CheckRangeSigned:
=value;
END_IF
自动调用函数,一定是名为CheckRangeSigned的函数,作为规定界面:
返回值和类型DINT的三个参数。
当调用时,功能设置如下参数:
-值(value):
分配给范围类型的数值
-下限(lower):
范围下限
-上限(upper):
范围上限
-返回值(Returnvalue):
这是实际分配给范围类型的数值
在下列例子中,赋值语句i:
=10*y被隐含处理:
i:
=CheckRangeSigned(10*y,-4095,4095);
例子中,即使y的数值为1000,分配后,i的数值仍只为4095。
对于功能CheckRangeUnsigned同样适用:
功能名和界面必须正确。
FUNCTIONCheckRangeUnsigned:
UDINT
VAR_INPUT
value,lower,upper:
UDINT;
END_VAR
提示:
如果CheckRangeSigned功能和CheckRangeUnsigned功能都未使用,则在运行中,不进行子域类型的无类型检查!
在任何时侯,变量i能具有-32768至32767之间的任任意数值!
注意:
如果CheckRangeSigned功能和CheckRangeUnsigned功能都不像上述所描述的那样,子域类型被用于FOR循环中,则结果会出现死循环。
当FOR循环所给的范围比子域类型范围大时,这种情况就会发生!
例如:
VAR
ui:
UINT(0..10000);
END_VAR
FORui:
=0TO10000DO
…
END_FOR
因为ui不可能大于10000,所以FOR循环将无法完成。
当定义FOR循环的增加值时,同样也要定义CheckRange功能!