简介:面向使用 LabVIEW 控制 Keithley 2600 系列源表的测试工程师与科研人员,这份驱动资源包专门解决仪器程控与数据采集问题,适用于半导体器件、太阳能电池、电池、电化学传感器等自动化测试场景,覆盖 2602、2604、2612 等 26xx 型号,并支持通过局域网远程连接仪器,方便构建分布式或网络化测试系统,提升实验室与产线的测试灵活性。
包内共 154 个文件,压缩包约 1.94MB,以 136 个 VI 虚拟仪器程序为主体,辅以菜单配置文件、自定义控件及 LabVIEW 项目文件,构成从界面交互到底层通信的完整驱动框架。用户无需从零编写 SCPI 指令,即可直接调用电压设定、电流读取、四端口电阻测量等常用功能,同时仍可基于底层 VI 扩展测试序列,适配不同被测对象。
目前已有 866 人学习下载。资源附带说明文档与示例工程,解压后按项目文件组织即可快速导入 LabVIEW 环境并安装引用,能帮助研发与产线人员减少重复通信代码编写,把精力集中在测试流程优化与数据分析上,尤其适合需要快速集成 Keithley 2600 系列仪表的自动化系统开发。
1. Keithley 2600系列源表驱动:先弄清楚你下载的到底是什么
拿到一台Keithley 2600系列源表(比如常见的2636B双通道),最尴尬的不是不会测,而是LabVIEW里压根找不到它。好多人的第一反应是重装驱动、重启电脑,折腾半天仍然报错。实际上,Keithley 2600的LabVIEW驱动不是单一的一个安装包,它分两层:底层是NI-VISA提供的总线抽象层,上层才是仪器自身的TSP固件和命令接口。这份资源解决的就是从VISA底包到TSP命令的这条完整链路——怎么装、怎么配LAN、怎么在LabVIEW里正确下发SCPI和TSP命令、以及驱动装上后为什么还是连不上的排查点。适合做半导体I-V特性、LED光电测试、可靠性老化筛选的工程师,也适合刚从GPIB切到LAN控制的入门选手。下面按我实际拆过的流程走一遍。
2. 驱动安装与LabVIEW环境配置:分清VISA底包和TSP固件两层
2.1 驱动两层架构:VISA是总线抽象,TSP才是仪器内脏
Keithley 2600系列(2601B/2611B/2634B/2636B等)和普通台式万用表不一样,它内部跑的是一个完整的TSP脚本处理器。TSP(Test Script Processor)是Keithley自己的一套嵌入式脚本语言,可以让仪器脱离PC独立执行一段测量序列。也就是说,仪器本身就是一台小计算机。
但PC要跟它对上话,得先解决“通道”问题——LAN口也好、GPIB也好、USB也好,LabVIEW里的VISA节点只认VISA资源名,不认IP地址和端口。所以你要装的驱动有两层:
第一层是NI-VISA Runtime,它负责把TCPIP、GPIB、USB这些物理总线抽象成统一的VISA指令。没有这一层,LabVIEW的VISA Write和VISA Read节点就是灰色的。
第二层才是Keithley 2600 Series的LabVIEW驱动程序。这一层本质上是两个东西的组合:一个是官方的仪器驱动封装(通常以Keithley 2600 Series命名,安装后会在LabVIEW的函数选板里出现),另一个是仪器端的TSP固件命令集,这套固件出厂就烧在机器里,但固件版本会影响*IDN?返回的FW号,也影响某些TSP语法是否可用。
很多人在这一步就开始翻车:只装了NI-VISA,以为LabVIEW里就能直接控制2600,结果连*IDN?都发不出去。原因就是第二层驱动缺失,或者驱动版本跟LabVIEW位数不匹配。
2.2 安装清单与顺序:NI-VISA、Keithley I/O Layer与LabVIEW驱动
我一般建议按以下顺序装,顺序反了会出现注册表冲突,很麻烦:
| 组件 | 作用 | 是否必装 | 版本注意 |
|---|---|---|---|
| NI-VISA Runtime | 提供VISA总线抽象层 | 必装 | 建议2020及以上,且位数要与LabVIEW一致 |
| Keithley I/O Layer(KIO) | Keithley仪器在PC上的通信层,负责LAN设备发现 | 强烈建议 | Windows下32/64位要选对 |
| Keithley 2600 Series LabVIEW Driver | 官方的LabVIEW驱动封装 | 按需 | 老版本可能不兼容新版LabVIEW |
| TekVISA | 部分场景替代NI-VISA | 不推荐混装 | 跟NI-VISA同时装容易冲突 |
安装时最容易忽略的一个点:LabVIEW是32位还是64位。如果你用的是LabVIEW 32位,那NI-VISA Runtime和KIO必须装32位版本,否则MAX里能看到设备,但LabVIEW的VISA节点运行时找不到VISA库。64位同理。
具体安装步骤:
- 先装NI-VISA Runtime,装完不急着重启。
- 再装Keithley I/O Layer(名字里带KIO字样的包)。
- 然后安装Keithley 2600 Series LabVIEW驱动,安装器会把
.llb或.lvlibp文件放到LabVIEW的instr.lib或user.lib目录下。 - 全部装完再重启电脑。
# 安装完成后,在命令行确认VISA运行时版本 visaconf –l # 如果系统提示找不到 visaconf,说明NI-VISA没装进去 # 此时检查Windows服务管理器里是否有 "VISA Shared" 相关服务这段命令不是必须执行的,但visaconf能帮你在装完驱动后第一时间确认VISA核心库是否注册成功。我经常在给客户远程排查时先跑一遍这个,十有八九能定位到VISA没装上或位数为题。
2.3 装完怎么验证:MAX里能枚举到,才算第一关过了
装完驱动后的第一件事不是打开LabVIEW,而是打开NI Measurement & Automation Explorer(简称MAX)。
在MAX左侧树形菜单里,找到“设备和接口”,展开后如果能看到TCPIP0::192.168.1.100::inst0::INSTR这样的节点,说明VISA这层已经通了。如果这里空空如也,说明驱动层没生效,继续纠结LabVIEW是没用的。
这里插入一个我踩过的坑:有一次装完KIO后MAX里始终刷不出2600,后来发现是Windows防火墙把KIO的广播发现端口拦了。解决方法是安装时选择“专用网络”放行,或者在防火墙入站规则里手动放行KIO相关的程序。
提示:KIO的LAN发现走的是UDP广播,如果你把PC和仪器放在不同VLAN里,MAX很可能扫不到设备。这种情况下不要纠结发现,直接手动添加VISA资源名也行。
验证完MAX能看到设备后,右键点击这个VISA资源名,选择“VISA Test Panel”,在Input/Output标签页里发一条*IDN?,如果仪器返回KEITHLEY INSTRUMENTS INC.,MODEL 2636B,xxxxxx,FW x.x.x,说明驱动链路已经完全打通。接下来要做的才是关键:把LAN配置固化下来,避免每次开机IP漂移。
3. Keithley 2600的LAN通信:从IP配置到VISA资源名验证
3.1 给2600配IP:前面板菜单或Keithley Remote Explorer
2600系列出厂默认LAN是动态IP(DHCP)。如果你直接把网线插到办公室网络里,仪器会自动拿到一个IP,你可以在前面板的System页面里翻到IP地址那一栏查看。但动态IP有个致命问题:源表每次重启后可能换个地址,你LabVIEW里的VISA资源名就得跟着改,这在自动化产线上完全不可接受。
所以第一步,我一般是把LAN改成静态IP。操作路径:前面板按System键 → 选择Communication→ 选LAN→ 选Configuration→ 把Mode改成Static,然后手动填IP、子网掩码、网关。
如果你觉得前面板按键太费劲,还有更省事的办法:在PC上装Keithley Remote Explorer(KIO组件包里自带),它会自动扫描局域网里的所有Keithley仪器。双击扫描到的仪器,可以直接在图形界面里修改LAN参数。这个工具还能看到仪器的MAC地址,方便你在路由器里绑定固定IP(双保险)。
我个人的习惯是:静态IP和MAC绑定二选一即可,但实际实施时两个都会做。因为静态IP设置只能在仪器里存一组,万一恢复出厂设置,前面的配置全没了,这时候路由器端的MAC绑定还能兜底。
3.2 VISA资源名格式与连接方式选择
LAN通上之后,接下来是VISA资源名的写法问题。
在MAX里添加设备时,通常会自动生成两种资源名的其中一种:
| 资源名格式 | 底层链路 | 适用场景 |
|---|---|---|
TCPIP0::192.168.1.100::inst0::INSTR | VISA TCPIP协议 | 官方驱动、VISA Test Panel推荐 |
TCPIP0::192.168.1.100::5025::SOCKET | Raw Socket直连 | 绕过VISA、非LabVIEW环境通信 |
两种方式我都试过。inst0::INSTR走的是VISA封装好的TCPIP协议,配合VISA Read/Write节点最稳定,LabVIEW里推荐用它。SOCKET方式相当于直接开了一个raw TCP端口,好处是不依赖VISA也能调,比如用Python的socket库都能直接连——但坏处是数据格式需要自己管理终止符,容易飘,而且LabVIEW里用VISA节点时对超时更敏感。
在LabVIEW中,最靠谱的做法是直接拖一个“VISA资源名称控件”到前面板,然后在下拉列表里选MAX里已有的那个资源名,不要手打。手打最容易出问题:小数点打成句号、漏写inst0、IP段抄错,任何一处错误都是超时错误,仪器完全没反应。
3.3 VISA Test Panel验证*IDN?回读
验证LAN连接是否通,我一般不用Windows的ping,因为源表对ICMP的响应不一定稳定,ping通了Windows可能也显示超时。我更倾向于直接进VISA Test Panel发命令验证。
打开MAX → 右键设备 → 选择“VISA Test Panel” → 切到Input/Output标签页。在输入框里加一个换行符,输入*IDN?,点Write。然后再点Read,缓冲区返回应该是一行以换行为结尾的仪器标识字符串。
如果这一步成功:
# 用pyvisa模拟一下从LabVIEW之外验证LAN链路 # 实际逻辑跟VISA Test Panel一致,只是用代码跑一遍 import pyvisa rm = pyvisa.ResourceManager() inst = rm.open_resource("TCPIP0::192.168.1.100::inst0::INSTR") inst.write("*IDN?") print(inst.read()) # 预期输出类似:KEITHLEY INSTRUMENTS INC.,MODEL 2636B,V2.6.1,FW 2.6.1注意这里的write之后马上read,不需要手动把终止符改成\n,VISA的TCPIP默认终止符就是LF。如果在LabVIEW里你用VISA Write发完*IDN?后用VISA Read读,发现读到的字符串带一个奇怪的框或者读不到,多半是缓冲区没清空或者终止符不匹配。
提示:在读操作之前,先对VISA Resource Name执行一次“清空”操作。我在LabVIEW里习惯在每次VISA Read前接一个
VISA Clear节点,这样能避免上一次的残留字符干扰当前读取。
4. 用SCPI还是TSP:两套命令体系的LabVIEW调用与选型
4.1 SCPI与TSP的本质区别
LAN通了、VISA也通了,接下来是真正的业务逻辑问题:你到底用哪套命令控制2600?
SCPI是IEEE 488.2标准定义的可编程仪器命令集,它的特征是“面向单次查询”,比如:SOUR:VOLT 1、:MEAS:CURR?,发一条、回一条,人力和LabVIEW的循环结构很容易配合。TSP则完全不是这个思路,它是把一整段脚本下发给仪器,让仪器自己跑完循环、判断、决策,最后再一次性返回结果。
这两套体系在2600系列上都能用,但它们的设计哲学不同。SCPI是你控制一步、仪器走一步;TSP是你把整个流程交给仪器,仪器自己走完全程。
实际项目中我的体会是:如果你只是做简单的IV特性采集,用SCPI完全够用;但如果你要做带扫描、带判断条件的序列(比如从0V扫到10V,电流超过1A就跳变保护),SCPI会把PC和仪器之间的通信带宽拖垮,因为每一步都要来回一次,而TSP脚本可以在仪器内部完成整个循环,只是最后把数据回传。
4.2 SCPI命令的LabVIEW调用与代码示意
在LabVIEW中调用SCPI命令,其实就是三件套:VISA Write下发命令、VISA Read读回结果、把字符串解析成数值。
以一次最简单的电压输出并回读电流为例。先在Python里用pyvisa验证逻辑:
import pyvisa rm = pyvisa.ResourceManager() src = rm.open_resource("TCPIP0::192.168.1.100::inst0::INSTR") # 复位到默认状态 src.write("*RST") # 设置SMU1为电压源模式 src.write(":SOUR:FUNC VOLT") # 电压1V src.write(":SOUR:VOLT 1.0") # 设置电流限值100mA,防止测试件短路时烧板 src.write(":SENS:CURR:PROT 0.1") # 打开输出通道 src.write(":OUTP ON") # 回读电流 src.write(":MEAS:CURR?") al = src.read() print("Measured current (A):", al) # 关闭输出 src.write(":OUTP OFF")在LabVIEW里,这段代码对应的是:用VISA Write节点发送每一个字符串命令,用VISA Read节点读取查询结果。注意:MEAS:CURR?这种以问号结尾的命令必须跟上VISA Read,否则仪器的输出缓冲区会把数据一直挂着,影响下一条命令的执行。
SENS:CURR:PROT这个参数很多人会漏。如果测试对象是LED或者二极管,不设置电流限值,一旦电压加过头,源表输出直接过载报警,严重时会烧坏的不仅仅是器件,还有源表的输出级。我通常每次设置电压源之后,第一件事就是写电流限值。
4.3 TSP脚本的加载、执行与数据回读
TSP的用法就不同了。你需要先把脚本文本下发到仪器,然后执行。
# 定义一个扫压脚本,在2600内部完成扫描 script = """loadscript IVScan smua.source.func = smua.OUTPUT_DCV smua.source.limitv = 10 smua.source.levelv = 0 smua.source.output = smua.OUTPUT_ON for v = 0, 5, 0.5 do smua.source.levelv = v local volt, curr = smua.measure.iv() print(volt, curr) end smua.source.output = smua.OUTPUT_OFF endscript """ import pyvisa rm = pyvisa.ResourceManager() inst = rm.open_resource("TCPIP0::192.168.1.100::inst0::INSTR") inst.write(script) # 执行脚本 inst.write("IVScan()") # 读取回显数据 data = inst.read_raw(1024) print(data.decode('ascii'))这段脚本用loadscript和endscript关键字定义了一个名为IVScan的脚本块,里面用smua.source.levelv改电压、smua.measure.iv()回读电压和电流。print()输出的数据会推到PC端,你在LabVIEW里可以用VISA Read读取。
在LabVIEW里下发TSP脚本比SCPI复杂一点点,关键在于loadscript和endscript必须放在同一次VISA Write里,或者脚本太长时分段写,但要注意不能把loadscript和endscript拆到两次Write里,否则仪器会报脚本未闭合的错误。实际操作中,我一般把脚本字符串拼到同一个常量里,一个VISA Write节点整体下发。
4.4 选型建议与混合用法
| 维度 | SCPI | TSP |
|---|---|---|
| 实时性 | 每条命令都有往返,适合稀疏控制 | 脚本内部高速执行,适合批量扫描 |
| 调试难度 | 逐条命令,出错定位快 | 脚本整体下发,报错定位到行号 |
| LabVIEW集成 | 直接VISA Write/Read,简单 | 需管脚本字符串拼接,略有门槛 |
| 数据体积 | 每次读一条 | 可以一次回传整个数组 |
我的选型习惯是这样的:单点测量、手动调试、临时验证时用SCPI;正式的自动化测试序列(尤其是含循环和条件判断的)用TSP,把仪器当成一台独立执行器来用,PC只管发“开始”和收“结果”。
还有一种混合用法:用SCPI来控制仪器开启/关闭、复位等全局操作;用TSP跑核心扫描。这种组合的好处是全局操作出错容易定位,核心扫描又不占用PC和仪器的通信带宽。
5. 避坑常见问题:驱动翻车现场与排查记录
5.1 现象:MAX能看到设备,LabVIEW程序里却报VISA超时错误
我遇到过一次非常典型的VISA错误:MAX里设备好好列在“设备和接口”下,*IDN?也能通过VISA Test Panel正常返回。但一回到LabVIEW,程序跑起来永远在VISA Read节点上超时,错误代码-1073807331或-1073807343,翻译过来就是“VISA TCP/IP读操作超时”。
排查才发现,原因是我在程序前面板手打了一个VISA资源名控件,而且用的是默认的TCPIP0::192.168.1.100::inst0::INSTR字符串。看起来一模一样,但VISA资源名控件本身关联着会话属性,我手打的那个字符串被LabVIEW当作新资源去打开,会话属性里的IO超时被重置成了默认的2000毫秒,而TSP的测量脚本跑一次要好几秒,直接触发超时。
解决方法是,把MAX里自动枚举的那个资源名拖到前面板上,不要手打;同时在VISA Read节点上把Timeout参数改成10000毫秒,给仪器留足执行时间。
5.2 现象:Windows提示“无法验证此设备所需的驱动程序的数字签名”
在Windows 10/11上装老版本Keithley驱动时,常会弹出来一个警告:“Windows无法验证此设备所需的驱动程序的数字签名”。这不是仪器的问题,是老版本驱动的签名证书过期了,而Windows的新安全策略会拦截这类未签名驱动。
处理方法有两种。第一种是去官网下载最新版的KIO和LabVIEW驱动,新版本驱动都重新签过名,装起来不会再报这个提示。第二种是如果你只能拿到旧版驱动安装包(比如测试现场断网),那需要在Windows的启动设置里进入“禁用驱动程序强制签名”模式再装。注意这个模式只对当前启动会话生效,重启后自动恢复,不是永久关闭安全策略。
我在产线上遇到过一次特别离谱的:现场电脑是离线环境,连驱动安装包都无法更新,最后是通过把驱动文件从另一台机器的instr.lib目录里拷贝过来,手动放置在LabVIEW目录下才解决的。手动放驱动文件的方式可不可靠取决于你用的是VISA节点还是官方驱动封装,如果只是用VISA节点,其实基本用不到官方驱动封装,放不放意义不大。
5.3 现象:LAN连上后第一条命令超时,后面又恢复正常
这种情况很玄学,但确实高频出现:程序刚启动时发*IDN?,第一次超时,再点一次就秒回。原因Abel,其实很多是TCP/IP的ARP缓存问题——PC的网卡第一次要广播寻找仪器的MAC地址,这本身要几十毫秒,加上部分无线网卡休眠导致的链路唤醒,时间就拖满了。
我验证过,最有效的规避方式是:程序初始化时先发一条空命令或*IDN?,不管它是否超时,紧接着再发正式命令前加一个200ms的延时。用LabVIEW实现就是用“等待(ms)”函数在VISA Write之前做一个短延时,同时把VISA的Timeout设到3000ms以上。
另外,检查一下网卡是无线还是有线连接。无线网卡对TCP/IP实时性影响很大,源表这种仪器控制的场景我建议一律用有线直连或者经过独立交换机,不建议走Wi-Fi。
5.4 现象:TSP脚本里用了冒号代替点号,仪器报语法错误
TSP脚本语法跟SCPI有个特别容易混淆的点:SCPI的层级分隔符是冒号(:SOUR:VOLT),而TSP里访问对象的属性用的是点号(smua.source.levelv = 1)。如果把两个体系的写法混在一起,仪器会直接报Expected '(' or '.'之类的语法错误。
我见过最尴尬的一回:把之前写的SCPI命令直接复制改前缀,结果脚本发下去,仪器报了一长串错误,连loadscript都没解析成功。解决方法是严格执行两套命令体系:TSP永远用点号访问成员,用等号赋值,用for循环控制扫描;SCPI则完全按IEEE 488.2语法来写,不要尝试在SCPI里插入TSP脚本。
5.5 现象:smua.source.output = smua.OUTPUT_ON执行了,但源表没有电压输出
TSP脚本里输出通道明明开了,电压也设置了,但用万用表量源表的输出端子,电压是0V。这通常有三个可能的原因。
第一,限流值太小,电流还没到设定值就触发了限流保护,电压被拉低。检查smua.source.limitv设置,如果是1mA,而测试对象导通电压附近的电流需求超过1mA,源表会进入限流状态,输出端的电压会低于设定值。第二,前面板的输出键被手动关掉了,仪器前面板的Output灯是熄灭的。TSP脚本执行过程中,如果你在仪器前面板按了输出键或者触发了互锁,输出会被硬件切断。第三,互锁开关没接好。2600系列后面板有interlock端子,如果这个端子处于断开状态,高压输出会被强制禁止,这在半导体测试台里是个安全机制。
解决方式:先检查前面板Output灯状态;再确认电流限值和互锁;最后在TSP里加一行print(smua.source.getStatus())回读输出状态,定位到底断在哪一环。
6. 把驱动封装成可复用子VI:从三行命令到I-V扫描模块
6.1 最小控制模板:打开会话、写、读、关
驱动装好、命令也调通之后,下一步一定是封装。我不建议在每个程序里都重新写一遍VISA Write和VISA Read的连线,那样出错的概率太高。我一般会先做一个最小控制子VI:输入VISA资源名和一个命令字符串,输出回读数据。
子VI的内部逻辑很简单:
# 用Python描述一下LabVIEW子VI的内部逻辑: def visa_send_recv(resource_name, command, timeout_ms=5000): # 对应LabVIEW的VISA Open inst = rm.open_resource(resource_name) inst.timeout = timeout_ms # 对应LabVIEW的VISA Clear inst.clear() # 对应LabVIEW的VISA Write inst.write(command) # 判断命令是否带问号,带问号才读 if "?" in command: return inst.read() return ""在LabVIEW里,这个子VI的连线板上就四个端子:资源名输入、命令输入、超时毫秒、回读字符串输出。VISA Open后用Clear清一次缓冲区,再Write,如果命令尾部带问号就Read,最后Close。封好之后,任何新的测试程序都从这个子VI起步,不会再出现漏读或清空不当的问题。
6.2 封装一个I-V扫描子VI
有了最小模板,下一步就是封装扫描子VI。输入是起始电压V_start、终止电压V_stop、步进V_step、电流限值I_limit,输出是电压数组和电流数组。
核心思路是这样的:在LabVIEW的For循环里,每次迭代把一个电压值拼进命令字符串,调用最小控制子VI发送smua.source.levelv = x和smua.measure.iv(),把返回的电流值存入数组。扫描结束后一起输出。
这里有三个参数细节需要注意。第一,V_step有正负之分——从正电压往负电压扫时,步进值要设成负数,否则循环条件永远不成立。第二,限流值一定要在扫描前设置好,而不能在循环里每步重复设置,每步都写限流命令会增加程序运行时间,而且没必要。第三,回读的电流值是字符串,LabVIEW里需要用Fract/Exp String To Number函数转换,转换时机我习惯放在循环内即时转换,别等到数组攒完了再转,那样出错的地址不好定位。
6.3 连续采集:用队列缓冲测量值
如果你要做的不是单次扫描,而是类似于老化测试的长时间连续采集,我建议把扫描子VI接到一个生产者消费者结构里。生产者循环负责把每一条扫描命令发给源表并读回数据,消费者循环负责把数据写入TDMS文件或数据库。这样的好处是,即使写入磁盘的速度跟不上采集速度,队列能起到缓冲作用,不会丢数据。
我最后的习惯是:每接一台新的2600源表,第一步永远是做最小的三行验证——*IDN?、强制输出1V、回读电流。这三步能顺利走通,再往I-V扫描、序列老化这些复杂方向封装。从那以后,我几乎再没有遇到过驱动层面的疑难杂症。希望帮到你。
本文还有配套的精品资源,点击获取