3. LabVIEW数据类型与数据流编程

在LabVIEW中,程序框图上的每一根连线都携带一种确定的数据类型。数据类型不仅决定数据在内存中的存储方式,还决定哪些函数可以连接、哪些控件可以显示、哪些转换需要显式处理。理解数据类型与数据流机制,是写出可运行、可维护、可扩展的采集程序的前提。

一、基本数据类型:数值、布尔与字符串

数值型是采集程序中最常见的数据类型。按精度与范围可分为整数(I8、I16、I32、I64)、无符号整数(U8、U16、U32、U64)、单精度浮点(SGL)、双精度浮点(DBL)和扩展精度(EXT)。此外还有定点数(FXP)和复数(CDB)。选择原则是:采集卡原始码值通常用I16或U16;电压换算结果用DBL;需要节省内存或与硬件寄存器对齐时用整数。例如,一块16位、量程±10 V的采集卡,原始码值范围是−32768~32767,对应电压换算公式为:电压 = 码值 × 10 V ÷ 32768。若用I16存储码值、用DBL存储电压,既保留原始精度又便于显示。

布尔型只有真/假两个状态,常用于表示开关、报警、使能、超限标志等。布尔控件在程序框图中可直接驱动条件结构的选择器,也可通过“布尔数组至数值转换”函数打包成位模式。字符串型用于表示设备命令、文件路径、日志文本和仪器响应。字符串在LabVIEW中不是以空字符结尾,而是带长度信息,因此可以包含任意字节。串口通信中常用“连接字符串”拼接命令,用“扫描字符串”解析返回值。

二、复合数据类型:数组、簇与波形

数组是同类型元素的集合,可以是一维、二维或多维。采集程序中最典型的一维数组是“一次采集的多点电压序列”,二维数组则是“多通道×多采样点”的数据矩阵。数组的关键属性是元素类型和维度,索引从0开始。使用“数组大小”函数可获取长度,使用“索引数组”可取出单个元素或子数组,使用“创建数组”可拼接或构建新数组。需要特别注意的是,对数组进行“自动索引”的For循环,输入数组会自动按元素拆分,输出端会自动累积成数组,这是LabVIEW处理批量数据的核心手段。

簇是把不同类型元素组合成一个整体的结构,类似C语言的结构体。簇中元素有固定顺序,顺序由簇常量或控件中元素的排列决定。采集程序中常用簇封装“一个通道的配置”:物理通道名(字符串)、量程(数值)、耦合方式(枚举)、使能(布尔)。簇可以整体连线,减少连线数量,也便于用“按名称解除捆绑”读取指定元素。簇与数组的区别在于:数组要求同类型,簇允许不同类型;数组长度可变,簇元素个数固定。

波形数据类型是LabVIEW为时域信号专门设计的一种簇,包含四个分量:t0(起始时间,时间戳)、dt(采样间隔,双精度)、Y(幅值数组,双精度)和属性(可选,用于携带通道名、单位等信息)。波形数据类型可以直接连接波形图、波形图表、频谱分析和滤波函数,是采集任务中最自然的中间表示。例如,以1 kHz采样率采集1秒数据,t0设为任务开始时刻,dt为0.001 s,Y为1000个点的电压数组,这样一个波形就完整描述了“何时、以何间隔、采到了什么”。

三、动态数据类型与类型转换

动态数据类型是Express VI之间传递数据的一种特殊类型,外观为深蓝色粗线。它内部可以携带单个数值、数组、波形或簇,并附带时间信息和通道信息。动态数据类型不能直接连接大多数底层函数,必须先用“从动态数据转换”函数提取出波形、数组或标量。在正式工程中,建议尽早把动态数据转换为波形或数组,避免类型模糊带来的调试困难。

类型转换分为自动转换和强制转换。当把I16连接到DBL输入时,LabVIEW会自动插入转换点,这通常安全但会隐藏精度变化;当把DBL连接到I16输入时,会出现红色强制转换点,表示可能丢失小数部分或溢出。对于采集数据,应显式使用“转换为双精度浮点”或“数值至字符串”等函数,明确转换意图。字符串与数值之间的转换常用“小数数字符串至数值”和“数值至小数数字符串”,前者可指定小数点和宽度,后者可控制格式。布尔与数值之间可用“布尔至0/1”转换。数组与簇之间可通过“数组至簇转换”和“簇至数组转换”互转,但要求元素类型兼容。

LabVIEW 数据类型与数据流执行示意 数据源 / 输入 I16 原始码值 DBL 电压值 布尔 超限标志 类型转换 码值 × 10V ÷ 32768 数值至字符串 布尔至 0/1 复合数据类型 数组 [DBL] 簇 {通道,量程,使能} 波形 {t0,dt,Y,属性} 显示 / 存储 波形图 数值显示 TDMS 文件 数据流执行机制:节点在全部输入就绪后才执行,输出就绪后驱动下游节点 节点 A 采集 1000 点 节点 B 滤波处理 节点 C 峰值检测 节点 D 显示与记录 并行分支 E 超限报警判断 B 与 E 无数据依赖,可并行执行

四、数据流执行机制与并行执行

LabVIEW采用数据流编程模型:一个节点只有在所有输入端子都收到数据后才会执行;执行完成后,输出端子产生数据,并沿连线传递给下游节点。这与传统文本语言按行顺序执行完全不同。数据流带来的直接结果是:没有数据依赖的节点可以并行执行。例如,采集任务A输出波形给滤波节点B,同时采集任务A也输出原始数据给报警判断节点E,B和E之间没有连线,它们可以同时运行。在多核CPU上,LabVIEW会自动把可并行的节点分配到不同线程,从而提高吞吐量。

理解数据流对调试非常重要。如果某个节点一直不执行,首先检查它的所有输入是否都已就绪,尤其是条件结构、事件结构和循环结构中的隧道。未连线的输入端子会导致节点无法执行;错误簇连线会强制顺序执行,因为错误簇本身携带数据依赖。若希望两个节点按特定顺序执行,可以用顺序结构,但更推荐用错误簇或数据依赖来建立顺序,这样既保证顺序又保留并行空间。

五、实践中的类型选择与转换策略

在一个典型的电压采集任务中,推荐的数据类型路径是:采集卡输出I16原始码值 → 用DBL常量做电压换算 → 得到DBL电压数组 → 与t0、dt组合成波形 → 送波形图显示并写入TDMS文件。若需要判断超限,从电压数组分支出一路,用“数组最大值”与阈值比较,输出布尔报警。若需要记录日志,用“数值至小数数字符串”把电压值转成字符串,再与时间字符串拼接。整个过程中,类型转换点应尽量少而明确,避免在循环内反复转换造成不必要的内存分配。

在程序框图上,不同类型的连线颜色不同:DBL为橙色,I16为蓝色,布尔为绿色,字符串为粉色,波形为棕色,动态数据为深蓝色。养成看线识类型的习惯,可以快速发现类型不匹配的问题。
强制转换点(红点)表示可能丢失数据。例如把DBL电压值直接连到I16显示控件,小数部分会被截断。若确实需要取整,应显式使用“舍入至最近整数”函数,而不是依赖强制转换。

总结来说,数值、布尔、字符串是基础砖块,数组、簇、波形是组织数据的容器,动态数据类型是Express VI的过渡格式,类型转换是连接不同容器的桥梁,而数据流机制决定了程序何时执行、哪些部分可以并行。把这六个概念串起来,就能在采集程序中做出清晰、高效、可维护的数据通路。