NI-VISA 核心 API

发布时间:2026/7/23 12:24:04
NI-VISA 核心 API NI-VISA 核心 API 整理约定ViStatus返回值≥ VI_SUCCESS(0)成功0错误 【IN】输入参数【OUT】输出参数1. viOpenDefaultRM打开 VISA 资源管理器ViStatus viOpenDefaultRM(ViSession *rmSession);调用示例ViSession rmSession; ViStatus status viOpenDefaultRM(rmSession); if(status VI_SUCCESS) { QLOG_ERROR() VISA资源管理器打开失败请确认安装NI-VISA驱动; return false; }参数分析ViSession *rmSession【OUT】 输出资源管理器句柄调用前变量无效成功后得到合法句柄。要点分析所有 VISA 操作入口函数全局建议只打开一次不要反复创建销毁本机未安装 NI-VISA 驱动调用直接失败资源管理器管理本机全部 GPIB/TCPIP/USB 仪器资源。2. viOpen建立单台仪器会话ViStatus viOpen( ViSession rmSession, //【IN】资源管理器句柄 ViConstRsrc resourceName, //【IN】VISA资源字符串 ViAccessMode accessMode, //【IN】访问模式 ViUInt32 timeout, //【IN】打开超时 ViSession *instrSession //【OUT】仪器会话句柄 );调用示例ViSession pInstrHandle; ViStatus status viOpen(rmSession, TCPIP0::192.168.1.70::inst0::INSTR, VI_NULL, VI_NULL, pInstrHandle); if(status VI_SUCCESS) { QLOG_ERROR() 仪器连接失败; viClose(rmSession); return false; }参数说明rmSession上一步打开的资源管理器句柄resourceName仪器资源地址字符串accessMode VI_NULL使用默认共享模式timeout VI_NULL继承会话默认超时pInstrHandle【OUT】连接成功输出仪器句柄后续 viWrite/viScanf 全部依赖此句柄。3. viFindRsrc批量检索 VISA 仪器资源ViStatus viFindRsrc( ViSession rmSession, //【IN】资源管理器句柄 ViString expr, //【IN】检索匹配表达式 ViFindList *findList, //【OUT】枚举列表句柄 ViUInt32 *count, //【OUT】搜索到设备总数 ViChar desc[] //【OUT】缓冲区保存第一条资源字符串 );调用示例ViFindList findList; ViUInt32 numInstrs; char instrDescriptor[VI_FIND_BUFLEN]; ViStatus status viFindRsrc(defaultRM, ?*INSTR, findList, numInstrs, instrDescriptor); if(status VI_SUCCESS) { QLOG_ERROR() 仪器检索失败; return status; }参数 问题分析检索表达式标准写法?*INSTRfindList枚举句柄必须最后调用viClose(findList)释放instrDescriptor字符数组作为输出缓冲区承载资源名称仅获取第一条仪器剩余设备依靠viFindNext循环读取。4. viFindNext获取下一条仪器资源ViStatus viFindNext( ViFindList findList, //【IN】viFindRsrc生成的枚举句柄 ViChar desc[] //【OUT】缓冲区接收下一个资源字符串 );调用示例while (--numInstrs) { status viFindNext(findList, instrDescriptor); if(status VI_SUCCESS) break; QLOG_DEBUG() instrDescriptor; }要点分析必须在viFindRsrc成功之后调用循环持续填充instrDescriptor检索结束或出错返回负数整套枚举完成后务必viClose(findList)。5. viWrite发送 SCPI 命令ViStatus viWrite( ViSession session, //【IN】仪器会话句柄 ViBuf buffer, //【IN】待发送数据指针 void* ViUInt32 count, //【IN】期望发送字节数 ViUInt32 *retCount //【OUT】实际成功发送字节数 );调用示例char stringinput[512]; strncpy(stringinput,*RST\n,sizeof(stringinput)-1); ViUInt32 writeCount; ViStatus status viWrite(pInstrHandle, (ViBuf)stringinput, (ViUInt32)strlen(stringinput), writeCount); if(status VI_SUCCESS) { QLOG_ERROR() 指令发送失败; return false; }分析常用于下发*RST、CONF:VOLT、READ?、ROUT:MONretCount可用来校验半包预期长度 实际长度代表发送异常SCPI 网口仪器建议指令末尾带上\n作为命令终止符。6. viScanf格式化阻塞读取ViStatus viScanf(ViSession session, ViString format, ...);调用示例double DQ973A_voltage_data[16]; ViStatus status viScanf(pInstrHandle,%,1000lf,DQ973A_voltage_data); if(status VI_SUCCESS) { QLOG_ERROR() 读取测量数据超时/失败; return false; }格式说明%,1000lf%lf读取 double 浮点,代表自动识别逗号分隔1000最多解析 1000 个浮点数重点风险阻塞函数超时时间由VI_ATTR_TMO_VALUE控制主线程直接调用会 UI 卡死必须判断返回 ViStatus你原有代码完全忽略返回值读取失败数组保留旧数值造成虚假测量结果适配 DQ973AREAD?指令仪器返回val1,val2,val3...自动拆分填入数组无需手动字符串切割。7. viSetAttribute设置会话属性ViStatus viSetAttribute( ViSession session, //【IN】仪器句柄 ViAttr attribute, //【IN】属性ID ViAttrState value //【IN】属性配置值 );调用示例viSetAttribute(pInstrHandle, VI_ATTR_TMO_VALUE, 5000); viSetAttribute(pInstrHandle, VI_ATTR_SUPPRESS_END_EN, VI_FALSE); viSetAttribute(pInstrHandle, VI_ATTR_SEND_END_EN, VI_FALSE);参数分析全部为输入参数无输出VI_ATTR_TMO_VALUE读写超时单位 msVI_ATTR_SEND_END_EN VI_FALSE关闭底层自动 END 信号TCP 网口仪器标准配置不要随意修改。8. viClose关闭各类 VISA 会话ViStatus viClose(ViSession session); //【IN】任意合法句柄调用示例viClose(pInstrHandle); //关闭仪器会话 viClose(findList); //关闭枚举列表 viClose(rmSession); //关闭资源管理器两条标准业务流程流程 A界面扫描仪器列表viOpenDefaultRM → viFindRsrc → 循环viFindNext → viClose(findList) → viClose(defaultRM)注意窗口扫描完成后关闭资源管理器长期运行程序不建议频繁开关。流程 B连接 设备 采集数据viOpenDefaultRM(全局一次) → viOpen(资源串, pInstrHandle) → viSetAttribute 配置超时、END参数 → viWrite 下发SCPI配置指令 → viWrite(READ?\n) → viScanf 读取多路测量值 //采集结束/断开设备 → viClose(pInstrHandle) //程序退出时 viClose(rmSession)统一避坑清单viOpenDefaultRM全局只打开一次不要循环反复调用viOpen/viSetAttribute/viWrite/viScanf每一步都校验ViStatusviScanf阻塞禁止在 Qt 主线程大量循环采集viClose成对调用禁止重复关闭同一个句柄网络仪器固定配置VI_ATTR_SEND_END_EN VI_FALSE通讯异常优先仅关闭仪器句柄不要轻易关闭资源管理器rmSessionviWrite建议增加半包校验对比writeCount与预期发送长度。