一、背景知识
1.1 虚拟仪器的定义、组成和应用
- 虚拟仪器的特点
虚拟仪器的突出特征为“硬件功能软件化”,虚拟仪器是在计算机上显示仪器面板,将硬件电路完成信号调理和处理功能由计算机程序完成。
- 虚拟仪器的组成
硬件+软件
硬件是基础,负责将物理信号转换成数字信号。
软件是灵魂,负责控制硬件,又负责对采集到的数据进行分析、显示和存储。
- 虚拟仪器的应用
DRLab综合实验平台
1.2 labview软件的应用
labview软件是NI设计平台的核心,主要用途:
- 测试测量。至今,大部分主流的测试仪器、数据采集设备都拥有专门的 labview驱动程序,使用labview可以非常便捷的控制这些硬件设备。
- 程序控制。labview拥有专门用于控制领域的模块——LaBVIEWDSC。除此之外,工程控制领域常用的设备、数据线等通常也都带有相应的labview驱动程序。使用labview可以十分方便的编制控制程序。
- 仿真。在设计机电设备之前,可以先在计算机上用LaBVIEW搭建仿真原型,验证设计的合理性。
注:驱动——一种特殊的软件程序,其中包含硬件设备的信息,便于计算机和软件识别和控制硬件设备。
1.3 常用快捷键
Ctrl+T:可用于左右栏显示labview的前面板和程序框图。
Ctrl+鼠标滚轮:可快速浏览条件分支。
Ctrl+E:前面板与程序框图前后切换。
二、 基本数据类型
2.1 控件与常量
输入控件与输出控件的区别
- 输入控件 = 来自用户的输入 = 数据源
- 显示控件 = 给用户的输出 = 数据的目的地或“接收器”
如何创建控件与常量
- 控件的两种创建方式
- 在前面板中通过控件选板创建
- 在程序框图中通过快捷菜单创建
- 常量的两种创建方式
- 在程序框图中通过函数选板创建
- 在程序框图中通过快捷菜单创建
labview中数据类型可以通过连线的形状和颜色来分辨:
- 数值型——浮点数、复数——橙色
- 数值型——整型——蓝色
- 布尔型——绿色
- 字符串型——粉色
2.2 数值型
2.2.1 数值类型控件
数值类型控件
- 创建数值输入控件默认为双精度浮点型(DBL)
- 可以手动改变数值类型(控件鼠标右键-属性-表示法)
- labview中的数值类型主要分三类:浮点型、整数型、复数型
- 类型的详细分类如下:
图标 数据类型 EXT 扩展精度浮点型 DBL 双精度浮点型 SGL 单精度浮点型 FXP 定点浮点型 I64 64位整型 I32 长整型 I16 双字节整型 I8 单字节整型 U64 无符号64位整型 U32 无字符长整型 U16 无字符双字节整型 U8 无字符单字节整型 CXY 扩展精度复数 CDB 双精度复数 CSG 单精度复数
2.2.2 数值类型转换
数值类型转换
- 强制转换(直接在不同数据类型的数值输入输出控件间连线)
- 显示转换(非强制转换,即温柔转换)
程序框图鼠标右键-数值-转换
数值进制转换(仅用于整型数值)
控件鼠标右键-显示项-基数
2.2.3 课后小练
例一:整型数值之间进行进制转换(十进制->二进制、八进制、十六进制)
例二:利用labview实现一个单位换算器
2.3 布尔型
2.3.1 布尔型控件
- labview的布尔类型占用一个字节
- 布尔控件的外观分为四大类(新式、银色、系统、经典)
- 布尔型输入控件,分为按钮型布尔输入控件、开关型输入控件
按钮型:按下时会改变状态,松开时恢复状态。
开关型:按下时会改变状态,松开时会一直保持在当前稳定的状态,直到下一次按下开关。
2.3.2 布尔型控件的机械动作
- 布尔控件机械动作图标
M:表示操作控件时鼠标的动作。
V:表示控件的输出值。
RD:表示VI读取空间的时刻
- 布尔控件机械动作类型(转换型、触发型)
转换型(第一行三个):类似开关型,按下后一直保持值改变的状态。
触发型(第二行三个):类似按钮型,按下后值改变,随后又恢复初始状态。
2.4 字符串型
2.4.1 字符串型控件的显示方式
- labview字符串控件有四种不同的显示方式
正常显示,\代码显示,密码显示,十六进制显示
2.4.2 字符串型控件的属性
- 限于单行输入:只允许输入一行文本,不响应回车换行操作。
- 键入时刷新:控件的值在输入每个字符时将同步刷新,默认情况未选中,表明必须在结束输入时才产生字符串值改变事件。
- 启用自动换行:当输入到字符串输入控件的行末尾时,将自动转到下一行。
2.5 下拉列表与枚举控件
下拉列表与枚举(控件->银色->下拉列表与枚举)
下拉列表和枚举都是用文本的方式表示数值.
- 下拉列表有多种表现形式,包括文本下拉列表、菜单下拉列表、图片下拉列表、文本与图片下拉列表。下拉列表用文字或图片表示数字。数字可以是整型数、浮点数,也可以是有序值、无序值,由用户自定义它代表的数值。
- 枚举控件只能代表整数,而且是有序的、自动分配的。
下拉列表与枚举控件的区别
- 下拉列表属于数值型,枚举控件属于枚举型。
- 下拉列表支持任何浮点实数类型,枚举只支持三种无符号整型数据(U32/U16/U8)。
- 下拉列表可以给每个条目设定任意值,但不能有数值相同的条目。枚举型按照顺序给每个条目设定一个整数值,从0开始,之后每个条目加1。
- 在条件结构选择器标签中,下拉列表按照每个条目的值判定条件是否满足;枚举控件按照每个条目的标签判断条件是否满足。
- 下拉列表通过控件属性设置,在程序运行时,可动态修改每一项的标签。枚举控件只能在编辑状态下修改枚举类型每一项的标签。
- 下拉列表都是同一种数据类型,可以直接相互赋值。而拥有不同条目的枚举属于不同数据类型,之间不能直接赋值。
三、程序结构
3.1 循环结构
3.1.1 while循环
while循环的特点
labview中的循环框图运行规律与C语言中的do-while相同,都是先执行一次循环再判断是否满足循环条件,以确定是否进行下一次循环。
while循环框图
labview中的while循环框图分为三部分:循环框架、循环计数变量、循环条件
- 循环计数变量i:返回循环执行次数,初始值为0,每执行一次循环变量i自动加1,循环条件端用于判断循环是否执行。每次循环结束时,条件端子会自动检测输入的布尔值。
- 循环条件端:有两种可供选择(true时停止,true时继续)
true时停止:若判断循环条件端子输入的布尔值为真时,循环停止。
true时继续:若判断循环条件端子输入的布尔值为真时,循环继续。
(C++中的for循环、while循环、do-while循环,循环判断语句都是真时继续)
while循环编程注意点
- 循环体至少执行一次
- 条件端子有两种形式,实际应用时可灵活选择
- 避免死循环
- 循环结束条件可以使用错误簇
课后小练:
例1:labview中利用循环结构计算0~100的和。
猜数游戏:编程猜0~100之间的整数,直到猜对程序自动停止
3.1.2 for循环
for循环框图
labview中的for循环框图分为三部分:循环框架、循环计数、循环总数
- 循环计数i:初始值为0,每次循环递增步长为1。
- 循环总数N:在程序运行前必须为其赋值,该值的数据类型和循环计数数据类型一致,均为I32长整型。若将其他数据类型连接到端口,for循环会进行强制类型转换,将其自动转换为长整型。
for循环的特点
- labview的for循环最大特点在于:循环次数固定。
故,通常用于已知代码循环次数的情况。
- labview8.5版本后,for循环新增了功能:增加条件终止端,可提前结束循环。
for循环和while循环的比较
- for循环
- 按照约定的次数执行(除非增加了条件终止端)
- 可以一次也不执行
- 默认情况下,隧道输出的是一个数组(需要禁用索引才能输出值)
- while循环
- 终止执行由终止条件决定的
- 至少会执行一次
- 默认情况下,隧道输出的是一个值(需要开启索引才能输出数组)
3.1.3 循环自动索引
循环结构的数据隧道
labview循环结构的数据隧道一般有三种:
- 一般隧道
- 索引隧道
- 移位寄存器
数据的传入与传出
数据在循环结构中的传入与传出,遵循数据流执行模式。
- 数据的传入:数据会在循环开始前进入。
- 数据的传出:数据会在循环结束后输出。
“启用索引”与“禁用索引”
对于数据输入隧道,如果输入的是数组,可以通过循环快捷菜单,选择“启用索引”或者“禁用索引”。
- 启用索引:每次循环使用数组中的一个元素。
- 禁用索引:数组会一次性的输入或输出,即操作的是所有数据。
对于数据输出隧道:
- 当“启用索引”时,每次循环产生的数据会形成一个数组。
- 当“禁用索引”时,数据流出的是最后一次循环所产生的数据。
- 一般来说,while循环默认的隧道是“禁用索引”,for循环默认的隧道是“启用索引”。
自动索引与for循环次数
当开启索引时,for循环可以根据数组长度自动设定循环次数,此时循环总数N端子可以不连接任何数据。
3.1.4 移位寄存器
移位寄存器的特性
- 移位寄存器的依附于循环结构的。
- 使用移位寄存器可以申请一段内存空间,用来保存中间运行结果,以供下次循环使用。(移位寄存器可在循环体之间传递数据,将上次循环的值传给下一次循环)
- 移位寄存器是数据的容器,可以包含任何数据类型,运行中的移位寄存器是不允许更改数据类型的。
- 移位寄存器遵循先入先出(FIFO)。
- 移位寄存器右侧接线端存储循环结束时的数据,并在下一次循环开始时出现在左侧接线端。
层叠移位寄存器
- 在循环中,如果需要访问之前多次循环的数据,就需要使用层叠移位寄存器。可以通过增加移位寄存器左侧接线端子的数量,用来保存前几次的运行结果。
- 移位寄存器左侧端子有几个,就可以保存循环前几次的运行结果。当第i次循环开始时,移位寄存器左侧每一个端子会将前几次循环由右侧端子存储到缓冲区的数据送出来,左侧第一个端子送出的是第i-1次循环时存储的数据,左侧第二个端子送出的是第i-2次循环时存储的数据,依此类推。
初始化移位寄存器
移位寄存器在使用之前,还需要初始化,否则它内部保存的初始数据是毫无意义的。
反馈节点
- 反馈节点与移位寄存器在本质上是相同的。
- 如果单纯是为了让下一次迭代使用上次迭代的数据,也可以使用反馈节点。
3.2 条件结构
3.2.1 条件结构的基本构成
基本的条件结构由以下几个基本元素组成:
- 条件选择器接线端:它连接的数据类型可以是布尔型、错误簇、数值型、枚举型、下拉列表、字符串等。
- 条件分支增减按钮:用于浏览前一个或下一个分支,具有自动回卷功能,即到达最后一个后自动回卷到第一个条件分支,反之向前浏览到最前面分支,会自动回卷到最后面的分支。
- 条件分支下拉列表:以下拉列表的方式显示所有分支列表,可以在这里选择需要的分支。
- 条件标签:用文本的形式表现当前分支的条件(工具选板->编辑文本)。
- 结构体:条件分支中的空白部分,用来输入程序框图。
3.2.2 条件结构的输入
labview的条件结构可以接受多种数据类型输入,可以构成各种复杂的条件结构,下面列出条件结构中的几种典型输入:
- 布尔型输入:相当于C语言中的if-else结构,只有真、假两个分支。默认创建的条件结构就是布尔型输入的。
- 错误簇输入:错误簇输入的条件结构常用创建子VI。(创建方式:1.文件->新建N->VI->基于模板->框架->带错误处理的子VI。2.新建VI->选择条件框架->给条件结构接线端连接错误簇->绿色边框正确分支,红色边框错误分支。)
- 数值型输入:由于条件结构的限制,labview只允许有符号整数和无符号整数作为条件结构的输入。单精度和双精度浮点数作为输入时,会自动转换为有符号整数。对于整数数值型输入,一个分支可以表示一个数值选择或多个数值选择。条件标签中数值型输入的表示方法有很多种:
注:数值型必须要有默认分支。
分支标签中的输入 含义 1,3,5 表示1、3、5三个数的列表方法 1...20 表示包含1~20范围内的所有整数 ...10 是范围开端口表示法,指所有小于等于10的整数 10... 是范围开端口表示法,值所有大于等于10的整数 ...10,11,13,20 是列表和范围的混合表示法,表示小于等于10的整数、11、13和大于等于20的整数 a...d 字符串范围是a,b,c,但不包含d a...d,d 字符串范围是a,b,c,d - 枚举型输入:枚举型输入的条件结构具有其他类型输入的条件结构无法比拟的特点。枚举型数据在条件结构标签中显示的是枚举的字符串,能够更直观的说明分支的具体用途。
- 下拉列表输入:与数值型输入的条件结构类似,这也表明了下拉列表数据类型本质上就是数值型。
- 字符串输入:labview条件结构的强大功能还在于条件选择器接线端可以接收字符串或组合框等。使用labview的条件结构可以处理字符串命令,这在仪表通信中非常重要。编辑条件标签文本时,不要加引号,编辑完成后,labview自动添加。
3.2.3 条件结构的输出
条件结构的输出有两种方式:
- 在条件分支内部输出数据
- 通过数据输出隧道,在条件结构外部输出数据
注:尽量避免在分支内部输出数据,应该通过隧道输出,特别是调用子VI时。
条件结构的分支输出隧道有三种形式:
- 实心方框:表示数据已连接。
- 空心方框:表示有分支未连接,此时程序错误无法运行。
- 半空心状态:表示有分支未连接,但使用默认值。
3.3 顺序结构
3.3.1 平铺式顺序结构
程序执行顺序
- 传统文本编辑语言的语句是按照顺序从上到下逐条进行。
- labview程序是由数据流驱动。
- 若程序中有两个无数据线连接的程序,则labview自动把它们放置到不同的线程中并行执行(自动多线程)。
在labview中顺序结构有两种:平铺式和层叠式。
平铺式顺序结构的创建
- 顺序结构执行时会按照帧的顺序由小到大依次执行。
- 平铺式顺序结构更利于代码的阅读、更直观。
- 平铺式顺序结构在外形上是平铺,占用更多空间。
3.3.2 层叠式顺序结构
从本质上看,平铺式顺序结构和层叠式顺序结构是相同的,二者可以相互转换。
层叠式顺序结构的创建
- 层叠式顺序结构适用于帧数量较多的场合。
- 层叠式顺序结构将每帧代码都叠放隐藏,用户只能看到其中一帧。
- 优点:节省程序框图空间。
- 缺点:代码不直观,可读性较差。
3.3.3 顺序结构中帧间的传递
平铺式数据结构:主要采用隧道来实现帧间的数据传递。
层叠式数据结构:主要采用顺序局部变量来实现帧间的数据传递。(顺序局部变量上的箭头,表示数据流动方向)
顺序局部变量:
顺序局部变量的使用使得层叠式顺序结构可读性降低,顺序局部变量只能通过翻看结构中的每一帧来找到数据源和接收数据的节点,其次由于一个顺序局部变量在每一帧的位置都固定,导致某些数据线上数据流动方向与从左向右的习惯不符。
labview编程的主要特点是数据流形式,这便于VI按照并行方式运行,优化了程序的计算性能。
顺序结构强行中断了labview固有的数据流程,人为规定了运行次序,禁止程序并行操作,而且顺序结构不能从指定的某帧开始执行,只能从第0帧开始直到最后一帧结束,在顺序执行中途不能停止该执行。所以用户在编程时应尽量不用或少用顺序结构,只有在必要的时候才使用。
3.3.4 局部变量
局部变量的定义
- 局部变量的作用域是局部的,它用于单个VI中传输数据。
- 局部变量 不能单独存在,与某个输入控件或显示控件对应。
- 局部变量代表控件的值的属性,而不是控件的本身。
- 一个控件可以生成数量不受限制的局部变量,每一个局部变量都需要复制它所代表的控件所包含的数据。
局部变量的创建
- 局部变量既可以用作写入数据,也可以作为读出数据。(右键快捷菜单->转换为读取/转换为写入,即可改变局部变量的数据流向)。
局部变量的典型应用
- 初始化
程序启动时,控件的初始化很重要,虽然在编程时可以设置控件的默认值,但有时候,启动初始值往往与上次结束时的状态有关。
- 把数据写入输入控件或从显示控件读取数据
- 并行循环间共享数据
注意事项:
- 每一个局部变量都要引起数据的复制,小号更多内存。大的数据结构不宜使用局部变量,因为复制内存,所以局部变量的运行速度远快于控件的值属性。
- 局部变量的使用还可能引起数据竞争。
- 因此,在使用局部变量之前要仔细斟酌。
四、数组及数组函数
4.1 数组的创建
4.1.1 数组的定义
- 数组是相同类型元素的集合。
- labview中的数组元素可以为任意数值类型(数值型、布尔型、字符串型、路径、波形、簇),但不能是数组、图表、图形。
- 数组元素必须同时都是输入控件或同事都是显示控件。
- 数组的元素和维度
数组由元素和维度组成,元素是组成数组的数据,而维度是数组的长度、高度或深度。
- 数组元素的索引
对数组元素的访问是通过索引进行的,索引从0开始,索引值的范围是0~n-1,其中n是数组中元素的个数。
4.1.2 数组的创建
- 在前面板上创建数组控件
- 在程序框图中创建数组常量
- 采用循环结构产生数组
- 采用数组函数创建数组
4.2 数组的运算
4.2.1 数组的运算函数
labview中有些函数专门针对数组,例如计算数组长度、排序、计算最大值最小值。也有一些函数,本来用于数值类型、布尔类型等数据的计算,也可直接用于对相应数据类型的数组进行计算。
labview可以根据输入数据的类型判断相应的运算方法,即自动实现多态。例如,在labview中可以直接将两个数组相加,labview会自动根据数组大小、数据类型决定相应的运算方法。
4.2.2 数组之间的加减乘除运算
对于加减乘除,数组之间的运算满足以下规则:
- 相同维度、相同大小的数组运算
将两个数组中索引相同的元素进行运算形成一个新的数组。
- 相同维度、不同大小的数组运算
将忽略较大数组多出来的部分。
- 数组与标量的运算
将数组的每个元素都和该数值进行运算。
- 空数组
相同维度的数组与空数组进行运算,结果为空数组。
4.2.3 数组之间的比较运算
对于比较函数,数组之间的运算规则:
可在右键菜单中选择“比较元素”或“比较集合”
- “比较元素”:是对两个数组中对应的每一个元素分别进行对比,比较结果构成一个同长度的布尔型数组。
- “比较集合”:把数组整体作为一个数据,与另一个数组比较,结果为真或假。
4.3 数组函数的使用
在labview中提供了大量VI函数用于数组相关的操作,这些函数的功能十分强大,使用非常灵活,参数也很多变。同一问题往往可以用多种函数来解决,因此仔细分析它们的用法非常重要,下面对常用的一些数组函数进行举例说明:
- 数组大小函数
通过该函数返回数组每个维度中元素的个数。对于一维数组,该函数返回一个I32位整型数值,表示一维数组的长度。对于二维或多维函数,则返回一个元素为I32类型的数组,数组中每一个元素表示对应维数的大小。
- 索引数组函数
通过该函数主要用于返回数组的元素或子数组。对于一维数组,该函数返回其中某个元素。对于二维或多维数组,该函数不仅可以返回数组中的某个元素,还可以返回数组的某行或某列。
- 替换数组子集函数
该函数功能是从索引中指定的位置开始替换数组中的某个元素或子数组。“索引”输入端子如果不连接,则默认从0开始替换。若索引号和子数组长度大于原数组长度,则只替换到末尾,多余部分将被省略。
- 数组插入函数
该函数功能是在n维数组中索引指定的位置插入元素或子数组。如果未连接索引则自动将新增内容加至数组末尾。如果指定的索引超出原数组范围,则操作被忽略。
- 删除数组元素函数
该函数从数组删除一个元素或子数组,输出端子将返回删除后的数组子集和已删除的元素或子集。当索引未连接时,自动从数组末尾开始删除。
- 初始化数组函数
函数功能是创建n维数组,每个元素都初始化为元素的值。数组大小定义的是数组的长度,向下拖动“维数大小”输入端可以增加维数。初始化数组的维数可为0,如果维数为0,则初始化后的数组为空数组。
- 创建数组函数
该函数有两个功能:
- 可将多个数组合并为一个数组
- 可将新的数组或数组元素连接到数组尾端
在该函数的快捷菜单中,选择“连接输入”选项可以将输入数组连接起来,否则将数组合并为高一维的数组。
- 数组最大值与最小值函数
该函数返回数组中最大、最小值及其索引。
- 一维数组排序函数
该函数返回元素按升序排序的数组。如需要降序排列,对升序数组反转即可(加个反转一维数组函数)。
- 搜索一维数组函数
此函数搜索一维数组中是否存在指定元素。如果存在,则返回元素的索引号,如果不存在,返回-1。搜索到第一个符合条件的元素后,搜索立即停止,如果需要搜索多个或全部符合条件的元素,可以通过while循环来实现。
- 一维数组移位函数
当输入参数n>0时,该函数将数组最后n个元素置于前端。
当输入参数n<0时,该函数将数组前面n个元素至于后端。
- 数组至簇和簇至数组函数
- 数组至簇函数:将一维数组转换为簇,簇元素和一维数组元素类型相同。数组可以自由改变大小,而簇的大小是固定的。这就需要在转换之前,手动指定簇的大小(右键单击函数,快捷菜单“簇大小”,设置簇中元素的数量)。簇的大小默认是9,最大是256。
- 簇至数组函数:该函数要求转换的簇元素类型必须相同。
五、簇及簇函数
5.1 簇的创建
5.1.1 什么是簇?
- 簇是由不同类型的数据元素组成的一种数据类型。
- 使用簇可以为编程带来便利:
- 把程序框图中不同数据类型的多个数据捆绑成簇,减少连线混乱。
- 子VI中有多个不同数据类型的参数输入输出时,将某些控件组成一个簇,可以减少连接板上的接线端数量。
5.1.2 簇的创建
创建方式:
- 在前面板创建簇输入控件和显示控件。
注:簇不能同时含有输入控件和显示控件
- 在程序框图中创建簇常量。
粉色——混合簇
褐色——数值簇
5.1.3 错误簇
控件选板->选择“数组、矩阵与簇”->选择“错误输入3D”和“错误输出3D”
黄褐色——错误簇
- labview使用错误簇返回错误信息。
- 错误簇包含的元素:
- 状态——布尔值,产生错误时布尔值为真。而无错误时布尔值为假。
- 错误代码——32位有符号整数,标识错误代码。
- 错误源——字符串,标识错误发生的位置
5.2 簇元素顺序
5.2.1 簇的大小
- 簇的大小固定,簇元素相互独立(不同数据类型的多个元素)。
- 自动调整簇外观大小。(无、匹配大小、垂直排列、水平排列)
5.2.2 簇元素顺序
- 簇的逻辑次序:簇元素顺序与元素控件的位置无关。
- 簇元素重新排序
右键(垂直排列or水平排列)->右键(重新排序簇中控件)->白框为原来顺序,黑框会更改后顺序->确认
5.2.3 簇与数组的比较
- 簇可以包含不同数据类型,数组仅包含一种数据类型。
- 簇与数组都只能包含输入控件或显示控件,不能同时包含两种控件。
5.3 簇函数使用
本讲主要讲解一些常见的簇函数:
(位于程序框图->簇、类与变体)
- “解除捆绑”与“捆绑”函数
- 解除捆绑函数:功能是把一个簇中的每个元素进行分解,并将分解后的元素输出。
- 捆绑函数:有两种用法。 a.用捆绑函数将几个元素捆绑成一个簇——组合簇。 b.用捆绑函数替换一个簇中的几个元素——替换簇元素。
- “按名称解除捆绑”与“按名称捆绑”函数
- 按名称接触捆绑函数:按名称解除捆绑函数按指定的元素名称从簇中提取元素。
- 按名称捆绑函数:按名称捆绑函数是按簇中元素的名称替换簇中的元素。输入簇端子必须接线。
- 数组与簇互换函数
- 数组至簇转换函数:把输入的一维数组转换为簇。
- 簇至数组转换函数:把输入的簇转换为一维数组,簇元素数据类型必须一致。
六、图形显示器
6.1 波形图标
6.2 波形图
6.3 XY图
6.4 强度图
6.5 二维图片
七、子VI设计
7.1 图标和连线板设计
7.2 创建子VI
7.3 多态VI
7.4 可重入VI
八、条件结构
九、DAQ数据采集程序设计
十、顺序结构