用數(shù)字萬用表驅(qū)動:從SCPI到數(shù)據(jù)讀取)
簡介面向C開發(fā)者和NI硬件用戶的DMM驅(qū)動資源聚焦NI數(shù)字萬用表DMM板卡的編程控制。資源對應(yīng)《深入理解DMM驅(qū)動NI數(shù)字萬用表的C編程實踐》涵蓋設(shè)備初始化、測量參數(shù)配置、數(shù)據(jù)采集、錯誤處理與設(shè)備關(guān)閉等核心環(huán)節(jié)適合需要以C直接操作萬用表完成電壓、電流、電阻自動化測量的工程場景。資源包為zip壓縮包僅含1個cpp源文件包體約2KB文件雖小但可作為入門示例幫助理解NI-DMM API的基本調(diào)用流程。已有283人學習下載適合實驗室測試、生產(chǎn)檢測及儀表自動化學習者參考。通過研讀該驅(qū)動源碼可快速掌握NI萬用表驅(qū)動程序的框架結(jié)構(gòu)學會封裝底層硬件操作并接入自有測量程序為構(gòu)建更復雜的測試系統(tǒng)提供參考。1. 為什么“DMM驅(qū)動”不只是一張光盤里的老掉牙文件如果你在某個工控論壇或者舊電腦的D盤里翻到dmm.zip大概率第一反應(yīng)是“哪個年代的驅(qū)動包”。但真正在實驗室里被NI數(shù)字萬用表折磨過的人會知道這個名字背后是一整套鏈路硬件是Keysight或者NI的臺式數(shù)字萬用表接口是GPIB、USB或者LAN軟件是NI-VISA而驅(qū)動文件里的那些DLL和C頭文件決定了你上層寫的測量程序是秒回數(shù)據(jù)還是黑匣子一樣彈出一串錯誤碼。這個場景在產(chǎn)線老化測試、電池容量分選、傳感器標定的工位上太常見了。這文章要聊的不是怎么雙擊Setup.exe裝個驅(qū)動程序而是當你拿到dmm.zip這類驅(qū)動包之后怎么在NI-VISA體系內(nèi)用C把它調(diào)起來把數(shù)字萬用表的電壓、電流、電阻讀數(shù)取回你的程序里。適合誰看正在用LabVIEW但被要求改成C上位機的工程師或者手上有一臺支持SCPI的臺式萬用表、想繞開廠商自帶的上位機自己寫采集邏輯的人。我會把驅(qū)動層次、NI-VISA的角色、C調(diào)用方法、SCPI命令格式串起來講最后落在幾個我踩過的坑上。2. DMM驅(qū)動到底驅(qū)動了什么硬件、固件還是SCPI指令先把概念釘死數(shù)字萬用表不是聲卡顯卡那種即插即用的PC外設(shè)它本質(zhì)上是一臺自帶測量固件的儀器。所謂“驅(qū)動”在臺式儀器領(lǐng)域并不是給操作系統(tǒng)提供設(shè)備節(jié)點而是給上層應(yīng)用提供“訪問測量功能”的接口。很多人翻車就是沒分清這一點以為裝了驅(qū)動就等于能讀數(shù)據(jù)結(jié)果程序打開后連設(shè)備地址都枚舉不到。2.1 儀器驅(qū)動的三層結(jié)構(gòu)廠商DLL、VISA層和應(yīng)用層NI體系下的DMM驅(qū)動常見的有兩種形態(tài)。一種是廠商把功能封裝成IVI-C或者IVI-COM驅(qū)動你調(diào)用niDMM_Init、niDMM_ConfigureMeasurement這類API就行另一種是更薄的做法驅(qū)動里只提供VISA的viWrite和viRead封裝真正的測量邏輯靠你的代碼寫SCPI命令讓萬用表自己執(zhí)行。dmm.zip這類包里通常兩類東西都有include目錄下是頭文件lib目錄下是導入庫還有一堆PDF是編程手冊。這三層的關(guān)系要捋清楚。最底層是VISA——NI-VISA是NI提供的IO接口標準它統(tǒng)一了GPIB、USB、LAN和串口四種物理連接。中間層是廠商驅(qū)動DLL它內(nèi)部調(diào)用VISA來做傳輸。最上層才是你的C程序。如果你用IVI方式程序只跟廠商DLL打交道如果你直接發(fā)SCPI那程序繞過中間層直接通過VISA的viWrite/viRead跟儀器對話。后者的好處是少一層封裝排查問題更直接壞處是你要自己管理測量配置和錯誤檢測。2.2 從dmm.zip里先找這三個文件別急著解壓安裝解壓驅(qū)動包后別急著跑安裝程序先確認三樣東西在不在。第一編程手冊PDF里面通常有SCPI命令列表和VISA屬性表第二對應(yīng)版本的nidmm.h頭文件如果是NI的DMM或者廠商自己的xxxDMM.h第三32位和64位的導入庫常見命名是nidmm.lib或者NIDMM_64.lib。缺任何一個后面都有得折騰。我一般會先裝好NI-VISA哪怕廠商驅(qū)動安裝包里面自帶VISA也建議單獨裝一遍最新版。版本對齊是玄學也是血淚經(jīng)驗NI-VISA 2010左右的老版本在Win10上經(jīng)常枚舉不到USB設(shè)備而新版又可能跟廠商老驅(qū)動DLL的依賴沖突。一個穩(wěn)妥的做法是先裝NI-VISA再裝驅(qū)動包最后用NI MAXMeasurement Automation Explorer看一眼設(shè)備能不能在“設(shè)備和接口”里出現(xiàn)。這一步過了C側(cè)的活才剛開始。2.3 量程、分辨率、觸發(fā)這些名詞其實是驅(qū)動API的參數(shù)讀萬用表不是“打開設(shè)備然后一串數(shù)據(jù)流進來”每次測量都是一次“配置—觸發(fā)—讀取—處理”的單次事務(wù)。驅(qū)動API的參數(shù)比如量程Range、分辨率Resolution、觸發(fā)源Trigger Source、采樣數(shù)Sample Count直接映射到萬用表前面板的功能鍵。在C里你就是在跟這些參數(shù)打交道。舉例來說niDMM_ConfigureMeasurement函數(shù)需要你傳measurement function和range兩個關(guān)鍵參數(shù)。測直流電壓時function選NIDMM_VAL_DC_VOLTSrange傳預期最大值如果傳NIDMM_VAL_AUTO_RANGE就是自動量程。分辨率參數(shù)決定讀數(shù)的位數(shù)——6位半還是5位半數(shù)據(jù)處理速度完全不同。這些參數(shù)不是拍腦袋填的在下一章接線和配置里我會把一套能直接跑的數(shù)值方案給出來。3. 在NI-VISA下用C跑通DMM的最小工程從環(huán)境到第一個電壓讀數(shù)這一章是全文的動手核心。不要被“萬用表驅(qū)動”這個名字嚇住本質(zhì)上就是用C調(diào)VISA函數(shù)把一行SCPI命令發(fā)給儀器再把返回的ASCII字符串解析成double。我按一套能最小復現(xiàn)的流程來跟著做就能看到讀數(shù)。3.1 環(huán)境準備VC和NI-VISA的版本選擇先說編譯器選擇。NI-VISA對Visual Studio的支持比較老派用VS2015到VS2019都沒問題VS2022也能跑但要注意平臺工具集按VS2019(v142)來設(shè)置避免某些頭文件的CRT兼容問題。我一般用Visual Studio 2019創(chuàng)建空控制臺項目項目屬性里的配置類型選“應(yīng)用程序”平臺選x64前提是裝了64位VISA。NI-VISA的安裝版本建議用NI-VISA 20.0以上的版本因為它包含VISA 5.4標準支持USB RAW和最新的GPIB驅(qū)動。裝完確認一下C:\Program Files\IVI Foundation\VISA\Win64\Include目錄下有visa.h和visatype.hWin64\Lib\msc\visa64.lib存在。這兩個是硬依賴缺一個連編譯都過不了。3.2 找到設(shè)備地址NI MAX提供的“后悔藥”設(shè)備地址不對后面全白搭。打開NI MAX左側(cè)“我的系統(tǒng)—設(shè)備和接口”DMM設(shè)備會列出來。右鍵屬性能看到VISA資源名稱常見格式是USB0::0x2A8D::0x0001::MY57290123::INSTRKeysight或者GPIB0::22::INSTR。這個字符串就是連接鑰匙。如果設(shè)備沒出現(xiàn)在NI MAX里先檢查物理連接USB線要插儀器的USB Device口而不是Host口GPIB要確認板卡的IEEE-488地址和儀器面板設(shè)置一致。還有一個高頻翻車點儀器開機后默認處在“本地”模式LOCAL按鍵燈亮此時PC發(fā)的SCPI指令會被面板鎖定需要先通過驅(qū)動API里的viClear或者前面板LOCAL鍵解鎖。這一條知道的人不少但每次忘記都會浪費20分鐘。3.3 最小C代碼發(fā)送SCPI并讀取電壓值來看一段可以直接編譯的代碼。假設(shè)設(shè)備地址是上面Keysight那種USB格式換成你自己的資源名即可。// dmm_read.cpp - 通過NI-VISA發(fā)送SCPI命令讀取DMM讀數(shù) #include stdio.h #include string.h #include visa.h int main() { ViStatus status; ViSession rm, instr; ViUInt32 retCount; char buf[256] {0}; char command[64] MEAS:VOLT:DC? 10.0,0.001; // 測直流電壓量程10V分辨率1mV // 1. 打開默認資源管理器會話 status viOpenDefaultRM(rm); if (status 0) { printf(打開資源管理器失敗錯誤碼: 0x%x\n, status); return -1; } // 2. 連接儀器超時設(shè)為5000ms status viOpen(rm, (ViString)USB0::0x2A8D::0x0001::MY57290123::INSTR, VI_LOAD_LIBRARY_NATIVE, VI_NULL, instr); if (status 0) { printf(打開設(shè)備失敗檢查VISA資源名稱。錯誤碼: 0x%x\n, status); viClose(rm); return -1; } // 3. 設(shè)置I/O超時 viSetAttribute(instr, VI_ATTR_TMO_VALUE, 5000); // 4. 清空輸入輸出緩沖區(qū)避免殘留數(shù)據(jù)干擾 viClear(instr); // 5. 發(fā)送命令 status viWrite(instr, (ViBuf)command, (ViUInt32)strlen(command), retCount); if (status 0) { printf(指令發(fā)送失敗錯誤碼: 0x%x\n, status); viClose(instr); viClose(rm); return -1; } // 6. 讀取響應(yīng) status viRead(instr, (ViBuf)buf, sizeof(buf) - 1, retCount); if (status 0) { printf(讀取響應(yīng)失敗錯誤碼: 0x%x\n, status); viClose(instr); viClose(rm); return -1; } buf[retCount] \0; // 7. 輸出結(jié)果 printf(測量值: %s V\n, buf); // 8. 清理會話 viClose(instr); viClose(rm); return 0; }邏輯說明這段代碼做了四件事——建立VISA會話、發(fā)命令、收響應(yīng)、清理。viOpenDefaultRM打開VISA的資源管理器返回會話句柄rmviOpen把資源管理器會話和一個具體的儀器地址綁定返回儀器的獨立會話instr后續(xù)所有操作都對著這個句柄來。viWrite發(fā)送SCPI命令第三個參數(shù)是命令字符串的長度retCount返回實際寫入的字節(jié)數(shù)。viRead是阻塞讀它會在收到換行符或者達到Timeout后返回超時時間在viSetAttribute里配了5秒。參數(shù)說明SCPI命令MEAS:VOLT:DC? 10.0,0.001是個“一條龍”測量命令問號表示儀器測完直接把結(jié)果返回。第一個參數(shù)10.0是量程第二個0.001是分辨率單位是伏特。如果量程參數(shù)傳AUTO儀器會先做一次預測量確定量程速度稍慢但更省心。連接超時VI_ATTR_TMO_VALUE的單位是毫秒表筆懸空或者量程設(shè)置錯誤時命令會一直阻塞到超時所以這個值別設(shè)太大5000ms比較合理。3.4 配置測量類型和觸發(fā)模式的正式姿勢SCPI一步命令適合快速測試但做正經(jīng)采集時最好用“配置-觸發(fā)-讀取”三步解析方式。原因是一步命令每次都要重置儀器狀態(tài)連續(xù)采樣的節(jié)拍會不穩(wěn)兩步走可以預先配好量程和濾波然后靠觸發(fā)信號讓每次采集的起點對齊。兩步前綴命令示例// 配置直流電壓10V量程分辨率1mV內(nèi)部觸發(fā) const char* configCmd CONF:VOLT:DC 10,0.001;TRIG:SOUR IMM;SENS:VOLT:DC:AVER:COUN 5; // 觸發(fā)并讀取 const char* readCmd READ?;CONF命令做測量配置TRIG:SOUR IMM把觸發(fā)源設(shè)為內(nèi)部立即觸發(fā)SENS:VOLT:DC:AVER:COUN 5開啟平均值濾波采樣5次取平均。之后每次需要新數(shù)據(jù)時發(fā)READ?并用viRead讀結(jié)果。這一步的工程意義在于濾波次數(shù)和讀數(shù)速率是直接對立的。平均值次數(shù)設(shè)為1時34401A類儀表每秒能出1000個讀數(shù)設(shè)成5次速率降到大約每秒100。產(chǎn)線場景要求單次測量決策多取幾個平均值更穩(wěn)研發(fā)場景掃曲線恨不得每秒500點那就得果斷關(guān)掉濾波。這個參數(shù)取舍我后面還會再提。4. 把DMM讀數(shù)接入你自己的高精度系統(tǒng)C二次開發(fā)的關(guān)鍵讀到一個電壓值只是第一步。實際工程里你得把這個電壓轉(zhuǎn)成溫度、電阻或功率再跟上下限比較、寫入數(shù)據(jù)庫、畫曲線。這個環(huán)節(jié)里C代碼的組織方式直接決定調(diào)試效率。4.1 封一個DMM類用RAII管好VISA會話VISA會話是資源開著不關(guān)會導致下次打開設(shè)備失敗。C里自然要用RAII資源獲取即初始化把viOpen和viClose包進構(gòu)造函數(shù)和析構(gòu)函數(shù)。下面這個類封裝了最常用的三個動作連接、讀取、斷開。// DMMSession.h #pragma once #include string #include visa.h class DMMSession { public: DMMSession(const std::string resourceName); ~DMMSession(); double ReadVoltageDc(double range 10.0, double resolution 0.001); bool IsOpen() const { return m_open; } private: ViSession m_rm VI_NULL; ViSession m_instr VI_NULL; bool m_open false; bool SendCommand(const std::string cmd); }; // DMMSession.cpp #include DMMSession.h #include cstring #include cstdio DMMSession::DMMSession(const std::string resourceName) { if (viOpenDefaultRM(m_rm) 0) { printf(默認資源管理器打開失敗\n); return; } if (viOpen(m_rm, (ViString)resourceName.c_str(), VI_LOAD_LIBRARY_NATIVE, VI_NULL, m_instr) 0) { printf(設(shè)備打開失敗: %s\n, resourceName.c_str()); viClose(m_rm); m_rm VI_NULL; return; } viSetAttribute(m_instr, VI_ATTR_TMO_VALUE, 3000); viClear(m_instr); m_open true; } DMMSession::~DMMSession() { if (m_instr ! VI_NULL) { viClose(m_instr); m_instr VI_NULL; } if (m_rm ! VI_NULL) { viClose(m_rm); m_rm VI_NULL; } } bool DMMSession::SendCommand(const std::string cmd) { if (!m_open) return false; ViUInt32 retCount 0; ViStatus status viWrite(m_instr, (ViBuf)cmd.c_str(), (ViUInt32)cmd.size(), retCount); return status 0; } double DMMSession::ReadVoltageDc(double range, double resolution) { char cmd[128]; snprintf(cmd, sizeof(cmd), MEAS:VOLT:DC? %.4f,%.6f, range, resolution); if (!SendCommand(cmd)) return -999.0; char buf[64] {0}; ViUInt32 retCount 0; if (viRead(m_instr, (ViBuf)buf, sizeof(buf) - 1, retCount) 0) return -999.0; buf[retCount] \0; return atof(buf); }邏輯說明構(gòu)造函數(shù)里連續(xù)做了三件事——開資源管理器、開設(shè)備、設(shè)超時和清緩沖區(qū)。任何一個失敗m_open保持false析構(gòu)時也不會誤關(guān)句柄。ReadVoltageDc把上文的SCPI一步命令包的嚴嚴實實返回-999.0作為錯誤哨兵值。在工控里錯誤的統(tǒng)一處理很重要為0可能會被當成正常讀數(shù)這個哨兵值我習慣用-999.0在配置上下限時天然不會誤判。參數(shù)說明snprintf里的%.4f和%.6f是格式控制——量程打印4位小數(shù)如10.0000分辨率打印6位小數(shù)如0.001000。嚴格來說SCPI解析器容忍多余空格和零但強迫癥式的格式對齊能讓你在調(diào)試日志里快速比對命令差異。另外注意viClear和超時的組合如果設(shè)備卡在某個錯誤狀態(tài)viClear能發(fā)設(shè)備清除信號比純軟件等超時可靠。4.2 多設(shè)備與多線程VISA會話不是線程安全的很多自動測試系統(tǒng)里一臺主機控制四臺萬用表每個表測不同的點。別用共享會話加鎖的笨辦法正確姿勢是每個線程自己開一個viOpen會話。VISA對同一設(shè)備允許多個會話日在硬件層面做了仲裁代價是并發(fā)性能一點點但對幾十赫茲的采樣率來說完全夠用。常見翻車寫法是把DMMSession的對象作為全局變量然后多線程直接調(diào)ReadVoltageDc。別這么干。VISA內(nèi)部雖然有些鎖但廠商驅(qū)動DLL的很多靜態(tài)變量不是線程安全的輕則數(shù)據(jù)錯亂重則訪問沖突。我自己的習慣是按測試工位分區(qū)工位1線程實例化自己的DMMSession工位2線程實例化自己的互不相干。4.3 上報狀態(tài)碼用字符串轉(zhuǎn)義錯誤信息C里viRead返回負數(shù)狀態(tài)碼光打印0x80001004這種裸碼沒人看得懂。VISA提供了viStatusDesc函數(shù)把狀態(tài)碼轉(zhuǎn)成描述字符串。調(diào)試時建議統(tǒng)一打出來ViStatus err viRead(m_instr, (ViBuf)buf, sizeof(buf) - 1, retCount); if (err 0) { char desc[256] {0}; viStatusDesc(m_instr, err, desc); printf(viRead失敗: %s\n, desc); return -999.0; }viStatusDesc的第三個參數(shù)是輸出緩沖區(qū)典型問題會顯示“VI_ERROR_TMO”超時或“VI_ERROR_RSRC_BUSY”資源忙。超時90%是命令語法錯導致儀器不響應(yīng)資源忙在GPIB菊花鏈拓撲里更常見檢查一下鏈上其他設(shè)備的地址是否沖突。把這些描述打進日志文件比寫errno管用得多。5. 避坑指南DMM驅(qū)動和C聯(lián)調(diào)中我踩過的五個典型問題5.1 現(xiàn)象NI-VISA設(shè)備枚舉存在但viOpen返回VI_ERROR_RSRC_NLOCKED原因這臺儀器被另一個進程占用了。最常見的是NI MAX在后臺打開了Test Panel或者你的調(diào)試程序上次異常退出沒執(zhí)行viClose。VISA的鎖定分共享鎖和排他鎖viOpen默認排他。解決先把NI MAX所有關(guān)聯(lián)窗口關(guān)掉。程序里給viOpen的第五個參數(shù)傳VI_EXCLUSIVE_LOCK默認就是并在析構(gòu)函數(shù)里冪等關(guān)閉。如果確認沒有其他進程占用重啟萬用表電源不是重啟電腦即可釋放硬件鎖。這一條幾乎每個第一次接儀器的人都會撞上。5.2 現(xiàn)象讀數(shù)突然變成9.91000000e37開頭的一串數(shù)原因這串數(shù)在DMM世界里是“過載Overload”。表筆沒接好或者輸入超出當前量程。34401A和34410A在超量程時返回的就是9.91000000E37注意這個數(shù)字不是真實讀數(shù)。解決程序里加上越界判斷讀取到這個前綴時直接報“端子開路或超量程”然后重新viClear儀器。不要試圖把它當成一個很大的電壓參與運算否則后面算平均值時會被一次性拉飛。自動化產(chǎn)線里更強的習慣是測之前做自檢先撤掉被測對象或者短路輸入端子讀一個接近0V的底噪確認鏈路正常再開始正式測量。5.3 現(xiàn)象viWrite成功但viRead超時程序卡在讀取那里十幾秒原因你發(fā)的SCPI命令不是問號命令如CONF:VOLT:DC儀器只配置不返回數(shù)據(jù)而viRead永遠等不到東西。解決先確認協(xié)議命令里帶?儀器才吐數(shù)據(jù)。另一種情況是儀器開啟了連續(xù)測量模式INIT后測量在后臺跑但READ?被堵塞在高優(yōu)先級觸發(fā)里。解決方式是發(fā)TRIG:SOUR IMM強制觸發(fā)或者用ABOR中止當前測量后再READ。寫測量循環(huán)時記住“每一條讀操作之前都必然有一次寫操作”沒有例外的。5.4 現(xiàn)象Debug模式下程序正常切換到Release模式后C調(diào)用出現(xiàn)Access Violation C0000005原因這是老生常談的調(diào)用約定和平臺位數(shù)不一致。最常見于你Debug用Win32編譯Release改成了x64但鏈接的導入庫是32位的。VISA的老版本中visa32.lib和visa64.lib不能混用。解決項目屬性—鏈接器—輸入—附加依賴項里Win32平臺寫visa32.libx64平臺寫visa64.lib。另一種可能你自己包裝的DLL導出函數(shù)用了__cdecl但頭文件聲明是__stdcall。檢查所有聲明ViStatus已經(jīng)是_VI_FAR定義過的宏通常無需改但如果你在類外單獨聲明VISA函數(shù)一定要保持完全一致。5.5 現(xiàn)象AGILENT/KEYSIGHT的34461A和NI驅(qū)動不兼容發(fā)命令沒反應(yīng)原因NI的nidmm.dll只能控制NI自己的DMM或者明確聲明支持IVI-Compatibility的型號。Keysight的34461A雖然支持SCPI但如果你用的是NI-DMM驅(qū)動而不是VISA直發(fā)通道驅(qū)動層會拒絕識別。解決對非NI品牌的萬用表統(tǒng)一走VISA直發(fā)SCPI路線跳過NI的nidmm。把代碼里對niDMM_Init的調(diào)用全換成viOpen加viWrite這個思路對Keysight、Rigol、Keithley都成立。反正SCPI命令大體兼容MEAS:VOLT:DC?全系通用只是分辨率的特性和響應(yīng)格式略有不同。6. 進階玩法用空測量校準通道把短時漂移壓到最低如果你要做高精度計量或者長時間老化數(shù)據(jù)采集就會發(fā)現(xiàn)同一個電壓今天測是10.0001V明天變成了10.0018V。除了萬用表自身的溫度系數(shù)還有一個容易被忽略的影響——熱電動勢和輸入通道接觸電阻。把DMM當成一臺“能讀電壓的儀器”是最低境界再往上走是學會利用它內(nèi)部的自校準機制。我的做法是每個測量周期開頭做一次“空測”在表筆短接的狀態(tài)下讀100個點取平均得到底噪補償值然后在正式測量序列里把每個讀數(shù)減去這個底噪。不要小看這一步對數(shù)字萬用表而言量程在1V以下時短接狀態(tài)的殘余電壓常常在幾十微伏到幾百微伏之間波動如果被測信號本身是毫伏級的熱電偶輸出這誤差就會直接變成溫度偏差。代碼層面的植入很簡單在DMMSession里加一個成員函數(shù)CalibrateOffsetdouble DMMSession::CalibrateOffset(int samples) { double sum 0.0; for (int i 0; i samples; i) { sum ReadVoltageDc(0.1, 0.00001); // 100mV量程, 10uV分辨率 } return sum / samples; }調(diào)用約定是接線時把輸入端子短路開機預熱至少30分鐘然后執(zhí)行這個函數(shù)拿到offset。后續(xù)每次ReadVoltageDc的實際數(shù)據(jù)表達式變成raw - offset。這里注意量程越低分辨率越高空測效果越明顯如果你在10V量程下做空測那個殘差本身就被量程噪聲蓋住了校準等于白做。還有一個小技巧跟觸發(fā)源配合如果你做的是連續(xù)的自動化測試試著把萬用表的觸發(fā)源設(shè)為外部觸發(fā)比如數(shù)字IO板卡的脈沖然后把采樣節(jié)奏交給硬件時鐘軟件循環(huán)只負責收集讀數(shù)。這樣做的優(yōu)點是測量間隔抖動從毫秒級降到微秒級在電池內(nèi)阻測試或者繼電器吸合時序測試里特別有用。SCPI配置命令是TRIG:SOUR EXT接線參考萬用表手冊的External Trigger端口。最后說個習慣問題每次改完代碼重新編譯之前我都會習慣性地先把viClear(instr)放進構(gòu)造函數(shù)里執(zhí)行一次。這不是多余的防御而是避免上一次程序殘留未決的SCPI操作把當前會話帶進黑洞。VISA是黑匣子你看不到它內(nèi)部堆了多久的陳舊調(diào)用只有那次主動清空才是在真正重置儀器狀態(tài)。這個習慣救過我很多次。希望幫到你。本文還有配套的精品資源點擊獲取