4 Variant数据类型指针
总结一下前面介绍过的指针,ANY可以包含POINTER,POINTER可以包含32位寄存器或者存储器指针,还有一个独立的16位指针,这些指针都是一个对象,占用存储器的空间。在S7-1500中,推荐使用的是符号寻址方式,没有绝对地址,所以上述指针都不适合符号寻址方式。从面向对象的编程方式上看,一个对象具有属性,可以是REAL类型、BOOL、字符串类型的组合,就算可以使用绝对地址(非优化的程序块),使用ANY、POINTER指针进行地址的迭代也感觉非常奇怪、不方便,不是以一个对象整处理。
在S7-1500中推出一个新的变量类型Variant,不占用存储器的空间(所以必须使用相关指令),感觉比ANY指针还要ANY,看一看Variant变量类型的特点吧:
1. 可以指向不同数据类型变量的指针。VARIANT 指针可以是基本数据类型(例如,INT 或 REAL)的对象,还可以是STRING、DTL、STRUCT 、PLC数据类型等元素构成的ARRAY。
2. VARIANT 指针可以识别PLC数据类型,并指向各个结构元素。
3. VARIANT 数据类型的操作数不占用背景数据块或工作存储器中的空间。VARIANT 类型的变量不是一个对象,而是对另一个对象的引用(ANY其实也是引用),因此不能在数据块或函数块的块接口静态部分中声明,只能在输入参数、输入输出参数、或临时变量区中声明。
4. 调用含有VARIANT类型参数的块时,可以将这些参数连接到任何数据类型的变量。块调用时,除了传递变量的指针外,还会传递变量的类型信息。块中的代码随后可以根据运行期间传递的变量类型来执行。
重点部分已经加粗标记,为了更加清晰化Variant变量类型的特点,我们使用示例的方式进行介绍。
4.1 VARIANT与PLC数据类型
在S7-1500中还推荐使用PLC数据类型,就是UDT,在UDT中可以定义控制对象的属性,当然,一个控制对象可以包含多个UDT。UDT就是一个优化的结构体变量,区别就是,1:在多个程序块中使用了相同的结构体变量,如果需要修改结构体变量,则必须逐一修改每一个块中的结构体变量,使用UDT可以中央修改,然后更新所有块中调用的UDT;2:UDT可以作为库中的模板,具有版本控制功能。
下面介绍一个VARIANT与PLC数据类型的使用示例(示例仅供参考),怎么识别PLC数据类型(参考VARIANT的特点2、4)。
假设变频器可以控制两种报文格式的通信,分别是PZD8/8(8个字输入/输出)和PZD10/10(10个字输入/输出),函数和函数块的开发者使用VARIANT作为输入形参,然后进行判断分析。好处是可以不用考虑程序块使用者需要赋值的是哪一个格式的报文(如果是数组可以使用可变数组,如果是结构体则可能变得麻烦)。
首先创建4个PLC数据类型(UDT),PZD8_IN、PZD8_OUT、PZD10_IN和PZD10_OUT,分别对应PZD8/8和PZD10/10的报文格式。然后创建一个FB块,定义接口参数和temp变量如图21所示。
图21
FB块中的程序参考图22。
图22
程序中对输入参数“mess format_in”的格式进行判断,如果数据类型是“PZD8_IN”,
则使用指令“VariantGet”将“mess format_in”的数据读出并复制到临时变量“temp_ PZD8_IN”,然后用户程序对变量“temp_ PZD8_IN”(变频器PZD 8输入的格式)的数据进行处理;如果数据类型是“PZD10_IN”,则复制到临时变量“temp_ PZD10_IN进行数据处理;如果数据类型是“PZD8_OUT”,则对临时变量“temp_ PZD8_OUT进行数据处理,然后使用指令“VariantPut”写回到参数“mess format_out”作为输出。
上面示例介绍的是Variant变量的识别功能,读写Variant变量的内容必须调用程序块,“VariantGet”和“VariantPut”,不能直接赋值,例如:
#TEMP_PZD8_IN:=mess format_in;
这是因为Variant变量不占用存储器空间,是对另外一个对象的引用,参考Variant变量特点3。
未完待续!
------------------------------------------------------------------------------------------------------------
上一篇:【6】pointer 和ANY——从S7-300_400到S7-1500看变址寻址的改变系列故事之六
下一篇:【8】Variant的使用——从S7-300_400到S7-1500看变址寻址的改变系列故事之八
汇总帖:技术Π活动故事、视频与案例分享汇总