找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6316|回复: 0
打印 上一主题 下一主题
收起左侧

基于SoMachine平台PLC自定义数据编程应用

[复制链接]
跳转到指定楼层
楼主
ID:105323 发表于 2016-2-22 15:08 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

自定义数据类型(DUT

新建自定义数据类型:结构,枚举,引用,子范围,数组,指针。

结构(Structures)

结构声明的语法如下:

TYPE <结构名>:
STRUCT
<
变量的声明1>
..
<
变量声明n>
END_STRUCT
END_TYPE

<结构名>是一种可以在整个工程中被识别的数据类型,可以像标准数据类型一样使用。

您可以使用互锁结构。唯一的限制是不可以指定结构中变量的地址(不允许使用AT来指定变量的地址)

定义名为Polygonline的结构举例:

TYPE Polygonline:

STRUCT

Start:ARRAY [1..2] OF INT;

Point1:ARRAY [1..2] OF INT;

Point2:ARRAY [1..2] OF INT;

END_STRUCT

END_TYPE

结构的初始化:

结构初始化举例:

Poly_1:polygonline := ( Start:=[3,3], Point1 =[5,2], Point2:=[7,3];

不能以变量作为初始化的值。参见数组中结构数组的初始化举例。

结构成员的访问:

您可以使用下述的语法访问结构的成员:

<结构名>.<结构成员名>

因此对于上述的结构“polygonline”,您可以用Poly_1.Start访问结构成员“start”

枚举(Enumerations)

枚举是由很多字符串常量组成的用户定义数据类型。这些常量称为枚举值。

即使在POU之内声明枚举值,枚举值仍然可以在整个工程范围内被识别。

用户可以通过添加对象对话框建立“DUT”对象来创建一个枚举。

语法:

TYPE <标识符>:(<Enum_0>,<Enum_1>, ...,<Enum_n>) |<base data type>;
END_TYPE

<标识符>变量可以代表枚举值 <Enum_..> 并被初始化为第一个值。这些值与所有的数字类型兼容,也就是说可以像使用整形变量一样对其进行操作。您也可以把数x赋给这个值。如果在声明中枚举值没有被初始化为指定的值,将从0开始递增依次进行初始化。请确保初始化时的初始值在内部元素中递增。运行时将会检查这些值的有效性。

例如:

TYPE TRAFFIC_SIGNAL: (red,yellow, green:=10); (* 每个颜色的初始值是Red=0Yellow=1Green=10 *)

END_TYPE

TRAFFIC_SIGNAL1 :TRAFFIC_SIGNAL;

TRAFFIC_SIGNAL1:=0; (* 交通信号的值是Red *)

FOR i:= red TO green DO

i := i + 1;

END_FOR;

IEC 61131-3标准的扩展:

枚举类型的名称可以(作为范围操作符)用来确定需要访问的枚举常量。

因此,您可以在不同枚举中使用相同的常量

例如:

定义两个枚举:

TYPE COLORS_1: (red, blue);
END_TYPE

TYPE COLORS_2: (green,blue, yellow);
END_TYPE

POU中使用枚举值Blue

声明:

colorvar1 : COLORS_1;

colorvar2 : COLORS_2;

实现:

(* 可以这样使用:*)

colorvar1 := colors_1.blue;

colorvar2 := colors_2.blue;

(* 不能这样使用:*)

colorvar1 := blue;

colorvar2 := blue;

 可以明确指定枚举所指向的数据类型(默认类型是INT)。

例如:

需要将枚举BigEnum的数据类型指定为DINT:

TYPE BigEnum : (yellow,blue, green:=16#8000) DINT;

END_TYPE

引用(References)

引用是一个对象的别名。这个别名可以通过标识符读写。与指针不同的是,引用所指向的数据将被直接改变,因此引用的赋值和所指向的数据是相同的。设置引用的地址用一个特定的赋值操作完成。一个引用是否指向一个有效的数据(不等于0),可以使用一个专门的操作符来检查,如下所示。

用以下语法声明引用:

语法

<标识符> : REFERENCE TO<数据类型>

声明示例:

ref_int : REFERENCE TO INT;

a : INT;

b : INT;

此时ref_int可以作为整型变量的别名使用

使用示例:

ref_int REF= a; (* 此时ref_int指向a *)

ref_int := 12; (* 此时a的值为12 *)

b := ref_int * 2; (* 此时b的值为24 *)

ref_int REF= b; (* 此时ref_int指向b *)

ref_int := a / 2; (* 此时b的值为6 *)

ref_int REF= 0; ( *引用的显式初始化 *)

子范围(子范围(Subrangetypes) )

子范围是一种用户自定义类型,其值的范围是基本数据类型的一个子集。注意可以使用隐含的范围边界校验(Range boundary checks

DUT中声明子范围。您也可以把一个变量直接声明为子范围:

声明为一个DUT对象的语法如下:

TYPE <名称> : <Inttype>(<ug>..<og>) END_TYPE;

<名称>

必须是一个有效的IEC标识符。

<Inttype>

是以下数据类型中的一个:SINTUSINTINTUINTDINTUDINTBYTEWORDDWORD (LINTULINTLWORD)

<ug>

是一个与基本数据类型相兼容的常量,它设定了范围数据类型的下界。下界本身也属于这个范围。

<og>

是一个与基本数据类型相兼容的常量,它设定了范围数据类型的上界。上界本身也属于这个范围。

例如:

TYPE

SubInt : INT (-4095..4095);

END_TYPE

把变量直接声明为子范围:

VAR

i : INT (-4095..4095);

ui : UINT (0..10000);

END_VAR

如果一个(在声明或实现中)被指定为子范围的值不在子范围的界限之内(如令以上声明中的i:=5000),系统将报错。

导致死循环的例子:

VAR

ui : UINT (0..10000);

END_VAR

FOR ui:=0 TO 10000 DO

...

END_FOR

由于校验函数使变量ui的值不会超过10000,故程序永远无法跳出这个FOR循环。

数组(数组(Arrays) )

一维、二维和三维数组属于基本的数据类型。您可以在POU的声明部分或者全局变量表中定义数组。请注意可以使用隐含的边界检查。

语法:

<数组名>:ARRAY[<ll1>..<ul1>,<ll2>..<ul2>] OF <基本数据类型>

ii1, ll2, ll3表示字段范围的最小值,ul1, ul2 and ul3表示字段范围的最大值。字段范围必须是整数。

例如:

card_game: ARRAY [1..13, 1..4] OF INT;

数组的初始化:

数组的完全初始化举例:

arr1 : ARRAY [1..5] OF INT := [1,2,3,4,5];

arr2 : ARRAY [1..2,3..4] OF INT := [1,3(7)]; (* 1,7,7,7的缩写形式 *)

arr3 : ARRAY [1..2,2..3,3..4] OF INT := [2(0),4(4),2,3];

(* 0,0,4,4,4,4,2,3的缩写形式 *)

结构数组的初始化举例:

结构定义:

TYPE STRUCT1

STRUCT

p1:int;

p2:int;

p3:dword;

END_STRUCT

END_TYPE

数组初始化:

ARRAY[1..3] OF STRUCT1:= [(p1:=1,p2:=10,p3:=4723),(p1:=2,p2:=0,p3:=299),
(p1:=14,p2:=5,p3:=112)];

数组的部分初始化举例:

arr1 : ARRAY [1..10] OF INT := [1,2];

对于那些没有预先赋值的元素,按照基本数据类型的缺省初始值进行初始化。在上例中,元素[3][10]被初始化为0

数组元素的访问:

在二维数组中访问数组元素,使用下面的语法:

<数组名>[Index1,Index2]

指针(Pointers)

指针用来在应用程序运行时存储变量、程序、功能块、方法和函数的地址。它可以指向上述的任何一个对象以及任意数据类型,包括用户定义数据类型。请注意,您可以使用隐含的指针校验功能。

声明指针的语法如下:

<标识符>: POINTER TO <数据类型 | 功能块 | 程序 | 方法 | 函数>;

取指针地址内容即意味着读取指针当前所指地址中存储的数据。通过在指针标识符后添加内容操作符“^”,可以取得指针所指地址的内容: 请看下面“pt^”的使用示例。

通过地址操作符ADR可以将变量的地址赋给指针。

示例:

VAR

pt:POINTER TO INT; (* 声明一个指针pt *)

var_int1:INT := 5; (* 声明变量var_int1var_int2 *)

var_int2:INT;

END_VAR

pt := ADR(var_int1); (* varint1的地址赋给指针pt *)

var_int2:= pt^; (* 通过取指针pt的地址内容,将var_int1的值5赋给var_int2 *)

建立好自定义数据类型的引用

其中:数组,指针可以在局部和全局变量中独自定义并引用。

自定义数据引用开始前必须声明引用的自定义数据

可以在全局和局部变量中关联引用声明。

在程序中输入引用名后加“.”选择相应的后缀名来使用引用的数据:

对于数据交流量大,数据流多的可以采用该方法来区别和方便的使用数据。

其中:数组,可以是等于一个数据表格,通过寻表找出我们所需要的值;枚举,是我们这个数据可能存在的不同值的可能,当其等于某个值的时候代表这某些值;指针,一般用在间接寻址,从而简化了大量数据的存取赋值等操作(需结合FOR语句来使用),同时也实用与间接性过度值的一些数据应用;子范围,也就是局限了数据的肯能值范围,防止数据超出范围或者不在范围内。

该文仅此记录相关概念,留个存档。相关应用欢迎交流。

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表