签到有奖
消息提醒
运维工程师专区
官方商城
扫码分享好友 任选多种周边
一直想写关于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
这几个指令功能还很多,有待大家挖掘。
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
帖子链接:https://www.ad.siemens.com.cn/club/bbs/post.aspx?a_id=1303281&b_id=50&s_id=0&num=16
很不错的心得体会,仁者见仁智者见智,工控巨头西门子引领PLC编程语言的发展。个人觉得这类似C++将C的指针整合成智能指针(《C++ Primer Plus》第六版有不错的介绍)。
首先先高兴楼主会发出此类的分享!可惜曲高和寡啊!看来针对此类问题研究的人还是很少!
针对楼主提出的几个指令,我以前也偶尔做过实验研究一二,以前用300经常会用STL写间接寻址,初用1200/1500时也会有些苦恼好像不太灵活。但是实际使用,还真没有发现以前300可以实现的功能而现在1200/1500实现不了的。
除了楼主重点提及的几个指令,其实AT指令还是非常好玩的,比如它可以实现Serialize/Deserialize的功能,而不需要“非优化的数据块”. 另外针对VariantGet/VariantPut,西门子有一个FAQ,上面的应用也蛮有趣,不过一般的场合也确实用不到了。
楼主,运动控制里面有个READ_PARAM这个功能块,Parameter这个引脚就是VARIANT(real)。
但是如果将READ_PARAM封装到FB里面去之后,Parameter这个引脚从FB外面给进来就会出错了。
VARIANT需要好好学习
摘抄了一些CSDN上关于变体数据类型年代已久的金句。
1:使用VARIANT来传递参数意味着非强类型语言(例如VBScript)能够调用使用强类型语言(C++)实现的方法。2:VC98,Delphi 2.0均引入了变体类型,能支持所有简单的数据类型,例如整型、浮点型、字符串、布尔型、日期和时间、货币以及Delphi特有的OLE自动化对象等。
3:Variant可以表达不均匀的数组(数组的长度是可变的,它的数据元素能表达前面介绍过的任何一种类型,也可包括另一个Variant数组)。
4:VB中Variant 变量能够存储所有系统定义类型的数据。如果把它们赋予Variant变量,则不必在这些数据的类型间进行转换; Visual Basic 会自动完成任何必要的转换。
呵呵,感谢提醒,其实我在帖子没有贴出关于AT的部分,不是AT不够强大,而是它和VARIANT无关,都是些固定格式的变量。
至于曲高和寡,我觉得应该是S7-1200的间接寻址相对于S7-300来说,方法更多更简单,所以相对AR1,ANY之类的,VARIANT就没有太多人感兴趣了(而且V13SP1的S7-1200之前也确实基本没法用)。我在论坛和找答案也搜了下,关于VARIANT相关的内容,没有看到什么有价值的信息,所以写这个帖子也算是抛砖引玉,如果能帮助到有兴趣的同学也算是没有白写。
主贴稍后会补充和DB_ANY和VARIANT_GET的应用。
我想知道
这个红框里在是什么数据类型,如果是数组的话长度是固定的吗?
就是UDT6_MB里面的一个固定长度数组,不固定体现在UDT的数组不是固定长度
忘贴了,UDT6_MB的组成就是:
MB_ADDR UInt
MODE USInt
DATA_ADDR UDInt
DATA_LEN UInt
DATA_PTR Array
收藏了。谢谢
学习了 ,收藏了
我还在路上慢慢的爬行
感谢楼主分享,挖掘的挺深的。
我是一个S7-1200的学习者,曾在该论坛上发过一些关于1200的求助帖,您给我回了帖,并且帮我解决了好多问题,能否留个联系方式,还希望您日后多多指教,谢谢!QQ:664117132
这位大师能不能把程序发出来,大家学习一好吗?
你好楼主,请问在这个程序中,inout_1接口的实参是什么?
楼主,请给出详细的实参,谢谢
学习了,但还是有点似懂非懂,楼主能不能把程序传上来呢?非常感谢
分享
扫码分享好友 任选多种好礼
收藏
有帮助
欢迎您访问支持中心!
丰富的视频,全方位的文档,大量的网友交流精华……
为了更好的完善这些内容,我们诚邀您在浏览结束后,花20秒左右的时间,完成一个用户在线调查!
感谢您的支持!
密码至少8位,包含大、小写字母,数字和符号至少三种。
允许邮箱和手机接收来自支持中心网站的信息
我已同意《支持中心网站注册协议和隐私政策》
微信登录扫码一键登录
验证码登录
密码登录
二维码失效点击重试
打开微信扫一扫,快速登录/注册
未注册手机验证后自动登录,注册即代表同意《支持中心网站注册协议和隐私政策》
三日内免验证登录
短信登录
登录