S7-1200 VARIANT使用之我见

已锁定

pkh2006

西门子1847工业学习平台

  • 帖子

    878
  • 精华

    11
  • 被关注

    120

论坛等级:奇侠

注册时间:2013-08-25

黄金 黄金 如何晋级?

S7-1200 VARIANT使用之我见

49662

16

2016-06-13 18:08:16

star star star star star

一直想写关于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,VariantGet/VariantPut,其他的只是一些判断比较,只有这几个能真正的从Variant提取变量。


VariantGet/VariantPut,可以看做S7-1200版的非优化块SFC20。

这个指令要求VariantGet输入/VariantPut输出一定是Variant,不能是其他类型,所以主要放置于子程序中,VariantGet输出/VariantPut输入不限定于优化或是非优化,不限定类型,但要求两边的类型完全一致,长度可以不同,只复制双方从头开始相同长度的部分,可以在LAD/SCL使用。

VariantPut输出可以是OutPut,可以是InOut,但不可以是Temp,也就是说无法在一个程序块中,先用VariantPut输出Variant到一个Temp,然后VariantGet输入为这个Temp,但是反过来可以。这就是说Variant类型一定要确确实实的指向一个真实地址,而不是一个临时变量。

如果输入输出均为非优化块,则可以写成相同数据类型的ANY指针,完成任意复制。

 

MOVE_BLK_VARIANT,可以看做VariantGet/VariantPut的Advanced版。输入输出可以是任意类型,只需类型相同,可以从任意索引开始复制任意长度,可以在LAD/SCL使用。通常是用来复制数组的部分元素,但更重要的是可以解决Variant类型的逐个元素复制和逐个元素处理,配合循环非常好用。利用这一点,可以在LAD方便的实现类似于S7-300 FC105/FC106的循环调用,也可以轻易实现Modbus轮询修改缓冲区的功能。

 

Serialize,Deserialize,主要用于任意块和非优化块(BYTE数组或BYTE类型的ANY指针)[1]之间的转换。Serialize的输入/Deserialize的输出不限定于优化或是非优化,不限定类型,解决了源目的双方类型不同的复制问题,可以在LAD/SCL使用。和MOVE_BLK_VARIANT类似,利用Variant类型的逐个元素复制,配合循环能实现很多功能。例如IDEVICE功能,需要将各种类型的数据区送入Q区,或者将I区送入各种类型的数据区,这两个块简直就是为这个功能量身打造的。

和MOVE_BLK_VARIANT指令一起,对比VariantGet/VariantPut,最大的不同是可以根据索引逐个复制数据后单独处理,而VariantGet/VariantPut只能完整复制,只能够整体复制后整体处理,而这往往需要很大的处理区域。


 

[1] S7-1200 4.2版本及其以上使用TIA V14 及其以上,这两个指令的2.0版本不再要求BYTE数组是非优化块。

 

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

 

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

 

再举个刚才提到的例子,IDEVICE功能的数据传输:


 控制器的输出和智能设备的输入都是这两个DB块,它们加在一起就是上面的512字节

左边是控制器的程序,右边是智能设备的程序,它们很相似


控制器侧使用序列化,将DB块的数据,序列化为BYTE数组,智能设备侧使用反序列化,将BYTE数组反序列化,存入DB块。

 


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

 

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

 

 

 

 

 

 

 

 

 

又完善了下程序,重新贴一下截图,后面附上下载地址。

链接: https://pan.baidu.com/s/1o9XXPnO 密码: h7t7


在外部实参可以填写任意长度的UDT数组,从而实现程序的通用性。用Serialize/Deserialize也可以实现,就不列举了。


同学们也可以和这个进行一下比较。

 http://www.ad.siemens.com.cn/club/bbs/post_elite.aspx?b_id=66&a_id=1301576

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



 

S7-1200 VARIANT使用之我见 已锁定
编辑推荐: 关闭

请填写推广理由:

本版热门话题

SIMATIC S7-1200系列

共有12957条技术帖

相关推荐

热门标签

相关帖子推荐

guzhang

恭喜,你发布的帖子

评为精华帖!

快扫描右侧二维码晒一晒吧!

再发帖或跟帖交流2条,就能晋升VIP啦!开启更多专属权限!

top
您收到0封站内信:
×
×
信息提示
很抱歉!您所访问的页面不存在,或网址发生了变化,请稍后再试。