我们在写C语言的时候,一些模块化的功能或者多次调用的功能,我们一般会用一个函数封装起来,方便使用并且让代码看起来更加的简洁。这种函数一般都会包含这几个概念,输入参数、输出参数和返回值。而LabVIEW的VI就可以当作是一个函数,输入参数就是输入控件,输出参数就是显示控件,不同于C函数,LabVIEW可以有多个返回值,当然C也能使用指针和引用让函数调用结束后得到多个返回值得效果。
VI的层次结构
每个VI都可以是一个独立的模块,实现独立的、特殊的、复用性高的的功能。和函数一样,VI都能够被其他的VI调用,被调用的称呼为子VI。一个上位机一般都能够拥有几十个子VI文件,这也是LabVIEW希望我们实现的模块化编程思想,在视图VIEW->VI Hierarchy可以查看层次结构。
在上图我们通过1号位置可以设置层次结构的布局方向,默认为垂直方向布局,可以改为水平方向布局。
可以看到在层次结构里面,除了工程的vi还有一个Main Application Instance,这里可以理解为这里就是程序的入口,也就是我们常用的main函数,而VI又能调用子VI,就类比函数之间的调用。
子VI的制作
从前面的章节,我们知道VI是前面板+程序框图组成,但是有这两个是不够的。C函数需要有入参和出参,我们的子VI也需要有参数和连接关系。
接下来我们来制作实现一个s=a²+2ab+b²的示例,参数有a、b、s。
现在前面板和程序框图弄好了,还需要制作图标,在VI层次结构可以看到。双击右上角图标,在弹出图标编辑器icon Editor中制作自定义图标。
最后一步,需要制作连线板和前面板控件的关系。我们选择连线工具,模型选择三个参数的就行,因为我们只要a、b、s三个参数,左侧两个,右侧一个,表示输入和输出。然后先点击连线板的端子白色小框,在选择一个控件,绑定好的关系会导致端子的颜色改变。重复这个操作,把三个控件都绑定即可。
调用子VI
在上面我们新建好了一个子VI,包含前面板、程序框图、连线板和图标,完成一个函数的运算,接下来我们新建一个VI去调用它,拉子VI进来的方法有四种。
1)在程序框图中右击,弹出的函数选板中选择“Select a VI”。
选择我们上面制作的VI,得到了一个制作的图标,并且可以看到有左侧两个输入,右侧一个输出。
2)直接在文件夹中找到VI文件,拖入到程序框图中。
3)子VI如果开着,甚至可以直接从子VI中选中图标直接拖到当前VI中,不过不建议这么干。
4)从项目中把VI文件拖进来,我们前面创建的都是单独的VI,还没有项目的概念,后面再补充。
拖进来后,我们再查看VI层次结构,这时候就发现,当前VI底下多了子VI。
当前VI同样创建两个输入控件,一个输出控件,两个输入给子VI的输入,子VI输出到输出控件,这样就完成了子VI的调用,而运算在子VI中实现。
VI属性
最后讲一下VI的属性,在File->VI Properties或者直接快捷键Ctrl+I调出属性窗口。
这里根据类别Category来设置VI的相关属性,有些信息是只读的不能修改,有些是设置的,比如外观、图标、版本。
1)常规属性General。
常规属性这里可以设置VI的文件名,文件存储的位置,当前修订的版本信息Current revision、源版本Source version、修订历史revision History和编辑图标信息,没错,这里也可以修改图标。这里注意两点:
1、由于LabVIEW有个很大的缺点,就是不同版本的LabVIEW很有可能会打不开非当前版本制作的项目,所以在源版本中我们可以知道是使用了什么版本的LabVIEW制作的,让程序员可以正确的打开它。
2、只要有对VI文件做了改动,甚至是移动了一下控件,当前修订版本就会往上加1,在版本信息修改中选择重置reset可以把修订版本重置为0。
3、版本信息的修改,这里比较重要的功能,每次对VI有重大的修改,都要有修改的原因,添加的功能,这是每个程序员必须要养成的习惯。
2)内存使用Memory Usage
在这里我们可以看到VI的内存使用情况,包括前面板、程序框图、代码空间和数据空间,还有硬盘占用的空间大小。一个程序的内存占用情况,可以决定一个程序的优劣,我们要尽量避免没必要的占用。
3)说明信息Documentation
和前面板的控件说明一样,调用子VI的时候,如果有设置了说明信息,那么会在即使帮助窗口显示该说明,说明信息可以保存在VI本身,也可以保存在帮助文件中。
在Help->Show Context Help或者使用快捷键Ctrl+H调出及时帮助窗口。
单击子VI,在窗口即可看到VI的说明信息。
4)修订历史revision History
设置提示输入修订信息的触发条件和规则,当满足条件的时候会主动弹出修改历史的窗口,提示程序员要输入修改记录。条件包括每次保存VI、每次关闭VI,还可以选择是否由LabVIEW生成的注释。
5)编辑器选项Editor Options
这里可以设置当前VI前面板和程序框图的网格尺寸,值得注意的是这里设置网格尺寸只针对当前VI,前面我们讲过在工具栏也有设置该属性的位置,那是针对全部的VI的。
除了网格尺寸,编辑器选项还可以选择控制控件的样式,包括现代风格Modern style、经典风格Classic style、跟随系统风格System style、银色风格Silver style、NXG风格Silver style。
6)保护选项Protection
保护选项保护用户不对它非法编辑。一种常规锁定,用户必须在保护界面解锁否则无法编辑前面板和程序框图。还有一种密码锁定,用户如果没有密码打不开VI程序。这里要注意一点,如果你忘记了密码,是没有任何办法可以解锁的。
7)外观窗口Window Appearance
该界面设置VI的外观方式,在前面章节提到的属性界面也可以设置该属性。外观选项又四种,顶层VI、对话框、默认、自定义。区别在于是否显示主菜单、工具栏和一些窗口最大、最小、关闭按钮等。
8)窗口尺寸Window Size
该窗口用来设置前面板的最小尺寸,使用”设置当前面板尺寸“按钮即可得到当前面板尺寸,也可以手动输入。
9)窗口运行位置Window Run-Time Position
该窗口用来设置VI运行的时候相对于桌面的位置和大小,如果设置为不改变Unchanged,那么就保持原来VI窗口原来的位置。也可以设置为居中、最大化、最小化、自定义的方式,如果设置自定义就需要设置前面板和程序框图的位置和大小。
10)执行Execution
该界面左侧默认勾选允许调试Allow debug,可以进行单步跟踪、设置断点等。
重入设置Reentrancy,默认为非重入执行Non-reentrant execution,在多线程中,如果出现两个子线程需要调用同一个子VI,就会出现户锁的情况,不允许同时操作该VI,比如涉及到了操作硬件。共享克隆重入执行Shared clone reentrant execution,共享统一的数据空间,多个副本之前共享数据。预分配克隆重入执行Preallcated clone reentrant execution,每个线程运行都是子VI的备份,具有独立的数据空间和代码空间。正常的计算模块VI都是需要允许重入的,不然效率非常低。根据VI的结构和功能适当选择是否重入和重入方式。
右侧优先级Priority和首选执行系统Preferred Execution System这两个一般都不需要设置。我们来了解下下面几个复选框。
启动自动错误处理Enable automatic error handing,默认是选中状态,提示程序运行中当出现一些错误。这里不是VI本身的错误,编译期的错误在连线的时候如果不能运行,就会弹窗提示了。在一些无人值守的场景下,我们可能会把该功能关闭,因为一但弹出对话框,会停止程序的运行,这是不合理的,这种场景下需要程序设置错误捕捉陷阱,根据错误在做处理,类似C的try+catch。
打开时运行Run when opened,默认未选中,勾选则双击vi或者File导入的时候直接运行,这一般用不上。
调用时挂起Suspend when called,默认未选中。这个功能主要是调试的时候使用,勾选后,当程序调用这个VI的时候,暂时停止程序,这时候我们通过探针等工具观察VI的运行情况。
调用时清空显示控件Clear indicators when called,默认未选中。显示控件的值一般都取决于接线端子,这里就是一个清空默认值的情况,防止出现误导。
启动时自动处理菜单Auto handle menus at launch,默认勾选。
11)打印Print Options
该界面涉及一些打印的属性,包括是否打印页眉、是否前面板加边框、是否缩放、自定义上下左右边距等。每次VI执行结束自动打印前面板默认不勾选,这个选项一般用于票据系统,输入一些数据之后点击执行,顺便把结果打印出来,其他情况下,一般不会勾选。