电子说
变量,有别于LabVIEW图形化编程环境所倡导的数据流(连线)形式,看似简单,其实在LabVIEW编程中是一个高级的话题。使用变量,如果理解不透,处理不好,轻则影响程序执行效率,重则产生一些意想不到的后果。
这篇推送里我们讲解一下LabVIEW中常见的变量,它们各自的作用范围、使用方法和使用时的注意事项。相信你认真看完后一定会有所收获。
LabVIEW里常见的变量类型:局部变量、全局变量、移位寄存器、反馈节点。
1.局部变量Local Variable 局部变量作用范围为当前VI内,必须在前面板上有对应的控件。 在程序框图里局部变量用一个带小房子的图标表示。
创建/使用局部变量的方法:
1)程序框图界面下从Structure分类里选择Local Variable,放置到代码框图里,选择需要关联的控件。
2)选中前面板或程序框图中的控件,右键弹出快捷菜单,选择Create->Local Variable,移动鼠标把创建的局部变量放置到需要的位置。
2.全局变量Global Variable
全局变量作用范围为本地计算机,可在多个VI、多个LabVIEW设计的应用程序之间共享数据。 在程序框图里全局变量用一个带地球的图标表示,global variable。
创建/使用全局变量的方法:
1)程序框图界面下从Structure分类里选择Global Variable,放置到代码框图里,选择需要关联的控件。如果没有可关联控件,则双击全局变量打开全局变量前面板,在前面板上放好全局变量对应的控件(完成了全局变量的创建)。
2)对于已经创建好的全局变量,选择保存全局变量的VI即可选择调用。
不同于局部变量,全局变量需要一个单独的VI保存。多个全局变量可以保存在一个VI中。
这个VI只有前面板(没有程序框图),用于保存全局变量对应的控件。 我们设计两个独立运行的VI,一个给全局变量写数据,另一个可以把全局变量的数据读取出来。这就通过全局变量实现了在两个小程序之间进行数据传递。
3.移位寄存器Shift Register
移位寄存器用于循环结构多次循环之间传递数据,将上一次循环更新的数据传递到下一次循环,在程序框图中以上下两个箭头表示。
移位寄存器的作用范围为所在循环结构。 创建/使用移位寄存器的方法: 在循环结构的边框上单击鼠标右键,选择Add Shift Register就创建了一对移位寄存器,循环结构的左右侧各一个。
在左侧移位寄存器放置一个数值常量/控件,为移位寄存器设定初始值,同时LabVIEW会根据输入值的类型自动设定移位寄存器的数据类型。
例如下面这个代码,通过移位寄存器实现N+(N-1)+(N-2)+...+2+1。
4.反馈节点Feedback Node
反馈节点保存上一次执行更新的数据,可以用于循环结构,也可以用于其它代码。反馈节点作用范围为当前VI。 在程序框图中反馈节点用下面这个图标表示,*那里的接线端用于给反馈节点设置初始值。与移位寄存器一样,反馈节点通过初始值自动确定数据类型。
例如下面这个代码,通过反馈节点实现N+(N-1)+(N-2)+...+2+1。
反馈节点和移位寄存器的功能和本质完全相同,但是反馈节点有以下几个特点:
1、反馈节点有启用输入端,可以设置启用条件。 2、反馈节点可以设置延时次数,规定每多少次迭代反馈一次数据。 3、反馈节点相当于为所在VI创建了移位寄存器;而移位寄存器只是为所在循环结构创建。
5.使用注意事项
1)局部/全局变量必须有控件与之对应;全局变量的控件需要保存在单独的VI文件中。
2)无论哪种形式的变量,使用前都必须初始化。
3)必须考虑竞争对局部/全局变量的影响。
对局部变量来说,要处理好VI内可能的并发访问。
对全局变量来说,既要处理好VI内可能的并发访问,也要处理好多线程可能的并发访问。
处理的基本方法就是要么避免并发访问,设法改为顺序访问;要么使用信号量等同步机制。
4)考虑内存使用量
每次对变量的读取,LabVIEW都会创建内存缓冲区保存读取的数据。多次、不同位置、大容量数据在使用变量保存时,应由其注意。
5)反馈节点初始化和未初始化差异 下面这个代码,VI首次运行时会初始化反馈节点。所以无论这个VI自身执行多少次,N等于5的时候结果都是15。
下面这个代码,反馈节点没有进行初始化。第一次执行该VI,反馈节点使用数据类型默认初始值0作为初始值,VI执行完之后反馈节点的值为10,加上N(5)后作为本次VI执行后的输出值15。第二次执行该VI,反馈节点使用上一次VI执行后的反馈节点值10作为初始值,循环执行完之后反馈节点的值为20,加上N(5)后作为第二次VI执行后的输出值25。
6)多次调用含有反馈节点的VI 注意这里说的是“多次调用”,不是含有反馈节点的VI自身多次执行(Ctrl+R)。
上面这个VI,执行一次后反馈节点等于10。这个10就作为下次该VI被调用时反馈节点的初始值。所以这个VI被调用两次后,输出的值为25,三次后输出的值为35。
相比之下,Shift Register因为针对的是所在循环结构,所以使用Shift Register就不存在这样的问题。
7)嵌套循环中Shift Register和Feedback Node的不同
下面这个代码,都是计算5+4+3+2+1,多次执行后的终值却是不一样的。 使用ShiftRegister的,执行三次后终值是15,和单次执行一样。因为Shift Register作用范围为所在循环结构,内部For循环每次执行前移位寄存器都被初始化为0,所以三次执行后终值还是15。 使用Feedback Node的,执行三次后终值是35(你是不是认为应该是15或者45?)。
因为Feedback Node作用范围为整个VI,前面说过相当于为VI创建了移位寄存器。VI每次执行时都使用上一次执行后的反馈节点值作为初始值。所以执行三次后,10+10+10+5 = 35。
8)如何改变6)和7)中反馈节点的“异常”表现
Feedback Node之所以会有上面讲述的那些“异常”表现,主要是因为它只在首次执行VI时执行初始化,之后多次调用都是使用同一块内存区域保存数据。我们改变Feedback Node所在VI的可重入执行设置,让其变为Preallocated clone reentrant execution,这样每次调用这个VI都使用的是不同的内存,多次调用之间就不会再有影响(但是反馈节点在多次VI调用之间反馈数据的功能也丢失了)。
更改之后无论执行多少次,结果都是15。
6.查看当前VI全局/局部变量使用情况
Tools->Profile->VI Metrics,勾选Globals/locals。LabVIEW会自动统计当前VI及其调用的子VI中全局/局部变量使用情况。
以上是一些关于局部变量、全局变量、Shift Register、Feedback Node的知识共享,希望能够引起大家的思考。有些莫名其妙的Bug就是隐藏在对变量不透彻的理解和运用中。感兴趣的朋友可以去试一试,一定能够对以后的开发工作有所帮助。
审核编辑:刘清
全部0条评论
快来发表一下你的评论吧 !