故事作者:空果仁

最近创作

看看TA的故事

【9】引用(终结)——从S7-300_400到S7-1500看变址寻址的改变系列故事之九

已锁定

空果仁

官方工程师 西门子1847工业学习平台

  • 帖子

    210
  • 精华

    47
  • 被关注

    328

论坛等级:侠圣

注册时间:2011-07-11

普通 普通 如何晋级?

【9】引用(终结)——从S7-300_400到S7-1500看变址寻址的改变系列故事之九

17967

26

2020-04-02 11:23:53

star star star

 

5 引用(References)

     先说一下我自己的感觉,在TIA博途V13 SP1(具体是哪一个版本忘了)以前是没有引用(References)的,指正介绍都是围绕着Variant进行的。后续的版本才推出了引用(References),原来为什么没有推出?要不就是计划有,但是没有开发出来;要不就是市场有新的需求,新加入的功能。既然推出引用(References),就有它的应用地方,例如程序块的开发者声明一个INOUT参数,数据类型为Variant,如果程序块的开发者想修改赋值变量中的一个元素怎么办? 参考上面Variant部分,是不是先使用typeof判断类型,然后使用指令VariantGet读出并复制到一个类型相同的副本中,再修改变量中一个元素(例如PLC数据类型),最后使用指令VariantPut写出,问题出现了,写的时候只写其中一个元素,其它元素怎么办?一定是使用读出的值替代,如果外面的值发生变化,就会将过程值覆盖。怎样才能修改其中一个元素又不覆盖变量中其它元素的值呢?只有在INOUT参数中声明一个复制类型(不能是引用类型)的变量才可以,例如DINT、real类型变量,这样将使程序的灵活性降低(不能使用Variant了),为了解决这样的问题才推出了引用(References)类型(只代表我的理解呀!)。好了下面开始介绍引用(References)了。

     引用(References)是一种变量,不含任何值却指向其它变量的存储位置,参考图34。 通过引用,可在块外进行变量传递。因此,可直接修改变量的值,而无需创建变量副本。

 

                                                                                                            图 34

      使用加粗标记的就是引用(References)的特点。

5.1 引用声明

     使用引用限制条件还是比较多的,看看下面的限制条件:

1:必须事先声明,也就是创建一个引用变量。引用可在优化访问的函数或函数块的接口中声明。并且地址区必须是临时变量区,例如:

     ●  FC:Input, Output, Temp, Return

     ●  FB:Temp

     ●  OB:Temp

     要进行引用声明,可使用关键字“REF_TO”指定被引用变量所需的数据类型。参考图35。

 

                                                                                                                   图 35

2:引用与被引用的数据类型必须相同,应用的数据类型如下:

     ●  位字符串(BYTE 、WORD、 DWORD、LWORD)

     ●  不支持 BOOL 引用。

     ●  整数

     ● 浮点数

     ● 字符串

     ● 不支持针对字符串的长度声明。

     ● IEC 定时器

     ● 支持 IEC_TIMER 和 IEC_LTIMER 引用。 不支持派生数据类型引用,例如 TON。

     ● IEC 计数器

     ● 支持 IEC_COUNTER/IEC_UCOUNTER、IEC_SCOUNTER/IEC_USCOUNTER、IEC_DCOUNTER/IEC_UDCOUNTER 引用。不支持派生数据类型引用,例如 CTU。

     ● PLC 数据类型 (UDT)

     ● 系统数据类型 (SDT)

     ● 已声明的数据类型的 ARRAY

     ● 不支持 ARRAY[*] 引用。不支持没有声明的数据类型的ARRAY,例如ARRAY of

     ● REF_TO<数据类型>。

 

5.2 变量的引用

     引用声明只是创建了一个变量和引用的数据类型,没有指向有效的存储器,系统使用值NULL对其进行初始化,如果在编程中使用将导致编程错误,所以必须为引用分配实际地址。

引用只能指向优化的全局 DB 或FB块静态变量中的数据。

    使用关键字“REF()”,可将声明的引用指向变量,如图36所示。LAD和SCL两种编程语言都支持变量的引用。


                                                                                                                    图 36

5.3 解引用

      引用指向变量只是指向变量的实际地址或者物理地址,要读取或写入一个被引用变量的值,则可使用插入符号“^”,这种访问方式又称为“解引用”。解引用的使用参考图37所示,程序块运行一次,“c”的值为15,此时“a”的值为10,在第二条语句中,将“My refint”指向变量“a”(引用),在第三条语句中解引用变量“My refint”并赋值20,这样20赋值给引用变量“My refint”, 引用变量“My refint”指向变量“a”的地址,实际上是将20传递到变量“a”,这时“c”就变为25了,第四、五条语句作用相同。如果程序再次执行一次,第一条语句中“c”的值将被25替代。


                                                                                                                      图 37

     引用指向的是变量的地址,而解引用得到变量的值,在应用中容易混乱出错,例如语句:#ref_int1 := #ref_int2; 这条语句是将#ref_int2引用的变量地址赋值给#ref_int1,如果#ref_int2没有分配地址,相

当于将NULL赋值给NULL,程序将报错。引用也可以应用到函数、函数块间的数据传递。例如FC1(Block_1)中使用接口声明计算A+B=C,在OB中调用FC1并赋值,示例参考图38,


                                                                                                                            图 38


    可以看到调用FC1时为接口声明A和B指向了实际地址,但是C有问题,赋值的方向反了,可以在FC1直接为引用C分配变量,或者不使用引用,示例如图39。


                                                                                                       图 39

5.4 引用与VARIANT

      引用声明时,使用关键字“REF_TO”指定被引用变量所需的数据类型必须是确定的,如果是数据类型是VARIANT,则不能使用上面介绍的引用方式,可以使用赋值尝试“?=”,将 VARIANT 数据类型的变量分配给一个引用。由于引用是后期开发的指令,与VARIANT数据类型的结合使用使开发更加灵活和简单。

      VARIANT可以读出输入变量的数据类型,然后通过VariantGet指令复制到一个类型相同的副本中进行分析判断,使用赋值尝试“?=”,将 VARIANT 数据类型的变量分配给一个引用将使这样的应用变得更加简单,参考图40。

 

                                                                                                                             图 40

      引用声明一个变量“Ref_motorA”,指定的数据类型为“REF_TO "Motor_A"”("Motor_A"为PLC数据类型),通过赋值尝试“?=”而不是关键字“REF()”,将VARIANT变量分配给“Ref_motorA”,如果分配成功,则变量“Ref_motorA”不等于 “NULL”,否则等于“NULL”。然后将“电机A”赋值给变量“#Ref_motorA^.Info”。

      赋值尝试“?=”的方式也支持LAD编程语言,如图41所示,使用LAD编程语言调用赋值尝试指令“?=”,如果分配成功,ENO等于1,否则等于0。


                                                                                                                                                      图 41

     上述的应用如果使用先前的方法:首先需要使用指令type of判断数据类型,然后使用VariantGet指令将数据复制到一个副本中,修改以后再使用VariantPut指令写回(开头应用介绍的使用场景),使用赋值尝试“?=”和引用的方式,使函数和函数块的开发变得更加方便。

     好了,所有变址寻址的方式已经介绍完了,希望大家可以受益。上面的描述大部分是自己多年的总结和目前学习的心得,不足之处还请大家指正和补充,也希望大家提供一些应用的案例(自己的案例都是猜想,有可能不符合实际),一起探讨,分享给其他工程师学习使用!

--------------------------------------------------------------------------------------------------------

上一篇:【8】Variant的使用——从S7-300_400到S7-1500看变址寻址的改变系列故事之八

汇总帖:技术Π活动故事、视频与案例分享汇总


【9】引用(终结)——从S7-300_400到S7-1500看变址寻址的改变系列故事之九 已锁定
编辑推荐: 关闭

请填写推广理由:

本版热门话题

西家技术派

共有63条技术帖

相关推荐

热门标签

相关帖子推荐

guzhang

恭喜,你发布的帖子

评为精华帖!

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

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

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