4. SCPI命令与仪器控制

在自动化测试平台中,上位机与仪器之间的“语言”就是 SCPI(Standard Commands for Programmable Instruments,可编程仪器标准命令)。无论你使用 Keysight 的示波器、万用表、信号源还是电源,只要它支持 SCPI,就可以用同一套语法规则去控制。理解 SCPI 的语法结构,是写出稳定、可维护测试脚本的第一步。

一、SCPI 语法结构:命令树与参数

SCPI 命令采用树状层级结构,每一层用冒号 : 分隔。例如 :MEASure:VOLTage:DC? 表示“测量 → 电压 → 直流”这一路径。命令分为两类:以问号 ? 结尾的是查询命令,仪器会返回数据;不带问号的是设置命令,用于改变仪器状态。

SCPI 允许大小写混写,但约定大写字母为必需部分,小写字母可省略。例如 :MEASure:VOLTage:DC? 可以简写为 :MEAS:VOLT:DC?。这种“短格式”在脚本中很常见,但要注意不同仪器对缩写支持可能略有差异,正式脚本建议使用完整形式或厂商文档确认的缩写。

参数类型主要有数值、布尔、字符串和枚举。例如设置直流电压量程::SENSe:VOLTage:DC:RANGe 10,其中 10 是数值参数,单位默认伏特;设置自动量程::SENSe:VOLTage:DC:RANGe:AUTO ON,ON 是布尔参数。多个命令可以用分号 ; 连接,例如 :SENSe:VOLTage:DC:RANGe 10;:SENSe:VOLTage:DC:RANGe:AUTO OFF,这样一次发送即可完成两项设置,减少通信开销。

SCPI 命令树与 VISA 通信路径 SCPI 命令树(以万用表为例) :SENSe :VOLTage:DC :RANGe 10 :RANGe:AUTO ON :MEASure:VOLTage:DC? VISA 通信路径 上位机程序(Python / C#) VISA 库(如 Keysight IO Libraries) 接口层:USB / LAN / GPIB 仪器(Keysight 34461A 等)

二、常用命令集:从设置到读取

不同仪器命令集不同,但结构相似。以 Keysight 34461A 数字万用表为例,常用命令包括:

  • *IDN?:查询仪器身份,返回厂商、型号、序列号、固件版本,是连接后的第一条命令。
  • *RST:复位仪器到出厂默认状态,避免上次设置残留影响本次测量。
  • :CONF:VOLT:DC 10:配置直流电压测量,量程 10 V。
  • :SAMP:COUN 5:设置采样次数为 5。
  • :READ?:触发一次测量并返回读数。
  • :MEAS:VOLT:DC?:直接测量并返回直流电压值,内部自动完成配置与触发。

对于信号源,常用命令如 :SOUR:FREQ 1kHz、:SOUR:VOLT 2Vpp、:OUTP ON。对于示波器,常用 :AUTOSCALE、:CHAN1:SCAL 0.5、:MEAS:VPP? CHAN1。掌握这些“动词+对象+参数”的组合,就能快速迁移到不同仪器。

三、通过 VISA 发送命令与读取响应

VISA(Virtual Instrument Software Architecture)是上位机与仪器之间的统一 I/O 接口层。它屏蔽了 USB、LAN、GPIB 等物理接口差异,让程序用同一套 API 通信。Keysight IO Libraries Suite 提供了 VISA 实现,安装后可在 Python 中使用 pyvisa 库。

典型流程如下:

  1. 打开资源管理器,获取仪器地址。例如 USB 仪器地址形如 USB0::0x2A8D::0x1301::MY12345678::INSTR,LAN 仪器地址形如 TCPIP0::192.168.1.100::inst0::INSTR。
  2. 打开连接:inst = rm.open_resource(address)。
  3. 设置超时:inst.timeout = 5000(单位毫秒),避免仪器无响应时程序卡死。
  4. 发送命令:inst.write(":CONF:VOLT:DC 10")。
  5. 读取响应:value = inst.query(":MEAS:VOLT:DC?"),query 等价于先 write 再 read。
  6. 关闭连接:inst.close()。

下面是一段可直接参考的 Python 示例(示例参数为合理假设,实际地址需替换):

import pyvisa

rm = pyvisa.ResourceManager()
inst = rm.open_resource("USB0::0x2A8D::0x1301::MY12345678::INSTR")
inst.timeout = 5000

print(inst.query("*IDN?"))          # 查询仪器身份
inst.write("*RST")                   # 复位
inst.write(":CONF:VOLT:DC 10")       # 配置直流电压,量程10V
inst.write(":SAMP:COUN 5")           # 采样5次
reading = inst.query(":READ?")       # 触发并读取
print("读数:", reading)

inst.close()

读取响应时要注意:query 返回的是字符串,通常需要转换为浮点数。例如 float(reading)。如果返回类似 +1.234567E+00 的科学计数法,Python 的 float() 可以直接解析。若返回多组数据(如采样 5 次),可能以逗号分隔,可用 reading.split(",") 拆分后逐个转换。

提示:发送设置命令用 write,发送查询命令用 query。不要对查询命令使用 write,否则响应会留在缓冲区,导致后续读取错位。
注意:部分仪器在收到 *RST 后需要短暂稳定时间(例如 100 ms),可在复位后加 time.sleep(0.1) 再发送后续命令,避免设置未生效。

四、常见问题与判断依据

如果 query 超时,首先检查仪器地址是否正确、接口是否被其他程序占用、VISA 库是否安装。若返回乱码或空字符串,检查命令拼写和大小写缩写是否被仪器支持。若读数明显异常,检查量程、输入端子连接和触发模式。一个实用的排查顺序是:*IDN? 能否返回 → *RST 后能否设置 → :READ? 能否返回数值。三步都通过,说明通信链路和基本命令集正常。

掌握 SCPI 语法、常用命令和 VISA 读写方法后,就可以把单次测量封装成函数,逐步构建自动化测试序列。下一阶段将进入多仪器协同与测试流程编排。