3. 仪器驱动与命令解析
在多仪器协同测试系统中,LabVIEW 与仪器之间的“对话”依赖一套标准化语言——SCPI(Standard Commands for Programmable Instruments,可编程仪器标准命令)。理解 SCPI 的语法结构、驱动库的调用层次,以及如何把零散命令封装成可复用模块,是构建稳定测试程序的基础。本节从命令语法出发,逐步过渡到驱动封装与自定义驱动开发。
一、SCPI 命令的语法结构
SCPI 建立在 IEEE 488.2 通用命令之上,采用树状层次结构。每条命令由“路径”组成,用冒号分隔层级,例如 :MEASure:VOLTage:DC? 表示测量直流电压。命令分为两类:以问号结尾的查询命令(Query)返回数据,不带问号的设置命令(Set)只执行动作。SCPI 还支持长短格式,如 :MEAS:VOLT:DC? 与 :MEASure:VOLTage:DC? 等价,长格式便于阅读,短格式节省传输时间。
参数类型包括数值、布尔、字符串和枚举。例如 :SENSe:VOLTage:DC:RANGe 10 设置 10 V 量程;:OUTPut:STATe ON 打开输出;:TRIGger:SOURce BUS 选择总线触发。查询响应通常以逗号分隔多值,如 :MEAS:VOLT:DC? 返回 +1.2345E+00。编写程序时必须注意:设置命令后若需立即读取状态,应使用 *OPC? 或 *WAI 同步,否则可能读到旧值。
二、驱动库调用:从 VISA 到 Plug & Play
LabVIEW 中调用仪器驱动有三种典型方式。最底层是 VISA(Virtual Instrument Software Architecture),通过 VISA Write 和 VISA Read 直接发送 SCPI 字符串。例如向地址为 TCPIP::192.168.1.10::INSTR 的示波器发送 :MEAS:VOLT:DC?,再读取返回字符串并转换为数值。这种方式灵活但需要手动处理字符串拼接、超时和错误。
中间层是仪器厂商提供的 Plug & Play 驱动,如 niDMM、niScope、Keysight 34410A 等。这些驱动以 VI 形式提供,内部已封装 SCPI 命令,用户只需连接“资源名称”和“功能参数”即可。例如 niDMM Read.vi 只需输入量程和分辨率,内部自动完成命令发送与解析。优点是开发快、错误少;缺点是依赖厂商驱动版本,跨品牌复用性差。
最高层是自定义封装 VI。当测试系统需要统一管理多台不同品牌仪器时,建议在 Plug & Play 驱动之上再封装一层“项目专用驱动”,统一接口命名、错误码和超时策略。例如定义 DMM_ReadVoltage.vi,输入为“仪器句柄”和“量程”,输出为“电压值”和“错误簇”,内部根据仪器型号选择调用 niDMM 或 Keysight 驱动。
三、命令封装与复用
命令封装的核心目标是“一次编写,多处调用”。以常见的“设置量程并读取电压”为例,若每次都在主程序中写 VISA Write + VISA Read,代码会迅速膨胀且难以维护。更好的做法是创建一个子 VI,输入为 VISA 资源句柄、量程和超时,输出为测量值和错误信息。
VI 名称:DMM_ReadVoltage.vi
输入:
VISA In(VISA 资源句柄)
Range(数值,单位 V,默认 10)
Timeout(毫秒,默认 5000)
输出:
Voltage(数值,单位 V)
VISA Out
Error Out
内部逻辑:
1. 格式化命令字符串:":MEAS:VOLT:DC? " + Range
2. VISA Write 发送命令
3. VISA Read 读取响应(字节数 64)
4. 字符串转数值(小数点数)
5. 错误簇传递
封装时需注意三点:一是命令字符串末尾必须加换行符 \n 或 \r\n,否则仪器不响应;二是读取字节数要足够大,建议 64 或 128,避免截断;三是错误处理要统一,使用 LabVIEW 的错误簇连线,确保错误能沿数据流传递到顶层。
:MEAS:VOLT:DC? 或 :MEASure:VOLTage:DC?,对外接口保持一致。四、自定义仪器驱动开发
当遇到非标准仪器或厂商未提供驱动时,需要自行开发驱动。开发流程通常包括:获取仪器编程手册,整理命令集;在 LabVIEW 中创建驱动项目,按功能划分 VI;定义统一的错误码和资源管理方式;最后打包为 .lvlib 或 .vip 供项目调用。
以一台自定义电源为例,其 SCPI 命令集可能为::VOLT 5.0 设置电压,:CURR 1.0 设置电流,:OUTP ON 打开输出,:MEAS:VOLT? 读取实际电压。开发时先创建 PSU_Initialize.vi(打开 VISA 会话并发送 *IDN? 验证连接),再创建 PSU_SetVoltage.vi、PSU_SetCurrent.vi、PSU_OutputEnable.vi 和 PSU_MeasureVoltage.vi。每个 VI 内部只负责一条命令的发送与响应解析,保持单一职责。
自定义驱动开发的关键是“接口稳定、内部可换”。对外暴露的输入输出参数应尽量使用通用类型(数值、布尔、字符串、错误簇),避免暴露具体命令字符串。这样即使仪器固件升级、命令微调,只需修改驱动内部,上层测试代码无需改动。
*OPC? 查询并等待返回 1,或使用固定延时(如 100 ms)。延时时间应参考仪器手册中的“命令处理时间”参数。五、命令解析中的数值与单位处理
SCPI 返回的数值通常为科学计数法字符串,如 +1.2345E+00。LabVIEW 的“小数数字符串至数值转换”函数可直接解析,但需注意小数点符号和千位分隔符可能因仪器区域设置不同而变化。稳妥做法是先去除首尾空格,再转换。对于带单位的响应(如 1.2345E+00 V),需先用“截取字符串”函数提取数值部分。
多值响应如 :MEAS:VOLT:DC?;:MEAS:CURR:DC? 会返回 +1.2345E+00,+5.6789E-01,此时需用“分隔符”函数按逗号拆分,再逐个转换。若响应中包含状态字节或错误信息,应优先检查错误队列(SYST:ERR?),确认无错误后再解析数据。