控制工程师论坛

西门子社区

S7-1200 VARIANT使用之我见

hypermill9
hypermill9

2016-06-21

一直想写关于S7-1200VARIANT数据类型的使用,正好昨天看见一个帖子“variant数据类型如何做指针寻址?”,借这机会谈一下我在这方面的体会,希望能给大家以帮助。

 

S7-1200/1500相比S7-300/400,增加了一个重要的数据类型VARIANT,手册这样写:“Variant 数据类型可以指向不同数据类型的变量或参数。Variant指针可以指向结构和单独的结构元素。 Variant 指针不会占用存储器的任何空间。”。看上去和ANY指针有异曲同工之处,在TIA PORTAL手册给出了它们的不同:

 

我是这么理解的,之所以出现Variant,是因为S7-1200/1500出现了优化块访问这种方式,而P#这种方式无法适应现在的优化块。

 

对于S7-1200,在V13SP1之前,Variant数据类型除了程序自带的库,基本无法使用。

 

在V13SP1出现后,增加了若干和Variant相关的指令,其中最有用的我觉得就是MOVE_BLK_VARIANT和Serialize/Deserialize,其他的只是一些判断比较,只有这两个能真正的从Variant提取变量。(VariantGet/VariantPut不提,只能复制完全一样的变量,目前为止没发现太多价值的2个指令)

 

MOVE_BLK_VARIANT:可以看做S7-1200版的非优化的SFC20。输入输出不限定于优化或是非优化。非优化块之间的复制(如果不写成符号寻址)无所不能,但是只要出现优化块只能是数组或单个变量。输入输出可以是数组名也可以是ANY指针,还可以是单个变量(不一定是数组中的元素),但要求输入输出数组元素或者ANY指针的数据类型一致。通常是用来复制数组的部分元素,也可以解决Variant类型的逐个元素复制,配合循环非常好用。

 

Serialize/Deserialize:主要用于任意块和非优化块(BYTE数组或BYTE类型的ANY指针)之间的转换。对于这种方法来说,既可以在程序中直接使用,也可以做成通用块(需要一个较大的非优化块),既可以在LAD使用,也可以在SCL使用,还不用考虑Serialize的输入和Deserialize的输出是非优化还是优化块,可以弥补MOVE_BLK_VARIANT不能覆盖的优化UDT的复制转化。和MOVE_BLK_VARIANT类似,利用Variant类型的逐个元素复制,配合循环能实现很多功能。

 

举个常见的例子,从模拟量模块读入连续多个变量并转化成工程量,在这之前,主要方法是在SCL中用POLK_BLK写,有了这两个指令就不需要了,见下面的例子:

 

配合数组元素比较类型和元素个数的指令,可以实现程序的通用性。

 

在这里还需要多说一句:除了EQ_TYPE,EQ_ElemType外,S7-1200中任意非优化变量写成任意ANY指针格式,指令都会将其认作数组。例如一个REAL数组,写成P#INT就会被认为为2倍元素个数的INT数组,例如一个TIME类型,写成P#DWORD,会认为是一个元素的DWORD数组。这点非常有用,根据这个可以轻松实现各种类型的复制,这就是前述MOVE_BLK_VARIANT非优化块之间的复制(如果不写成符号寻址)无所不能的原因。当然AT也可以实现,只是提供一种思路。

 

有了这些铺垫,就可以回答最前面帖子“variant数据类型如何做指针寻址?”的答案了:

 

这只是和MB_MASTER相关的程序,大体在这里。在外部实参可以填写任意长度的UDT数组,从而实现程序的通用性。用Serialize/Deserialize也可以实现,就不列举了。

 

这三个指令功能还很多,有待大家挖掘。

 

最后再补充一下关于DB_ANY这个类型,这个类型除了DB_ANY_TO_UINT和UINT_TO_DB_ANY以外,几乎和VARIANT捆绑在了一起,我觉得用途不大,毕竟每个VARIANT都是一个DB块,这样往往需要大量的DB块,使用不太方便,不如在一个DB块内建UDT的数组或是一堆UDT来的便捷,当然这是仁者见仁的事,在TIA PORTAL手册P387倒是给出了一个这样的例子,有兴趣的同学可以去看一下。

回帖

评论10

总共 , 当前 /
首页 | 登录 | 注册 | 返回顶部↑
手机版 | 电脑版
版权所有 Copyright(C) 2016 CE China