1. 程式人生 > >LabVIEW學習筆記(十一)——利用VISA進行串列埠通訊

LabVIEW學習筆記(十一)——利用VISA進行串列埠通訊

前言:

       在1993年,為了確保多廠商的儀器具有協同工作的能力以及降低包含了多廠商儀器的完整測試系統的開發時間,NI 聯合許多大公司開發出來了虛擬儀器軟體架構 ( Virtual Instruments Software ArchitectureVISA )。隨著VISA 的出現,使得一套儀器控制程式適用於種硬體介面成為可能,通過呼叫相同的VISA庫函式並配置不同的裝置引數,就可以編寫控制各種 I/O 介面儀器的通用程式。

       通過VISA使用者能與大多數儀器匯流排連線,包括GPIBUSB、串列埠等等,無論底層是何種硬體介面,使用者只需要面對統一的程式設計接VISA。所以今天來學習如何利用VISA進行串列埠通訊。

  一、   VISA 函式 

          VISA 函式在函式面板的 儀器I/O ——> 串列埠子面板中,通過串列埠子面板中的這些 VISA 函式可以與GPIBUSB、串列埠等中的任何一種匯流排通訊。

          用 LabVIEW 來寫串列埠驅動控制儀器,只需要下圖的幾個函式即可。事實上,真的只需要下面幾個函式:

         一般的串列埠控制結構是:配置(開啟)串列埠、讀寫串列埠、關閉串列埠,接下來我們依次來學習這三個步驟。

1.1  配置(開啟)串列埠

      配置串列埠是進入串列埠通訊的門檻,只有配置成功了,才能進行正確的通訊。首先我們看下 VISA 配置串列埠函式:

        這裡有個小技巧,配置串列埠時最好是在對應的引數埠那裡,右鍵,新建常量或者輸入控制元件,然後再在新建出來的常量或者輸入控制元件上面修改。因為,新建出來的資料型別,肯定是對的。接下來解釋下主要的輸入引數:

      (1)  啟用終止符: 目的是使序列裝置做好識別終止符的準備,預設值為TRUE, VI_ATTR_ASRL_END_IN屬性設定為識別終止符;如值為FALSE,VI_ATTR_ASRL_END_IN屬性設定為0(無)且序列裝置不識別終止符。

      (2)終止符:通過呼叫終止讀取操作。從序列裝置讀取終止符後讀取操作終止。 0xA是換行符( \n )的十六進位制表示。訊息字串的終止符由回車( \r )改為0xD。

      終止符的設定如下所示:

    (3) 超時:指定讀/寫操作的時間,以毫秒為單位。 預設值為10000ms,即10s。如果你設定了超時,等待超時時間到了,程式就不執行了,錯誤輸出會輸出錯。
   (4)VISA資源名稱:指定要開啟的資源。VISA資源名稱控制元件也可指定會話控制代碼和類。

   (5)波特率是傳輸速率。 預設值為9600。

   (6) 資料位是輸入資料的位數。 資料位的值介於5和8之間。預設值為8。

   (7)奇偶指定要傳輸或接收的每一幀使用的奇偶校驗。 

1.2  VISA讀取

     首先看下 VISA 讀取幫助:

        左邊輸入有個 VISA 位元組總數,你必須指定你要讀的位元組數。那麼問題來了,這個位元組數怎麼確定呢?

        一般讀取串列埠的通訊程式都如上圖所示, VISA 讀取函式 的 “讀取位元組數” 這個輸入埠設定十分關鍵。由於在串列埠通訊中,如果指定讀取 100 個串列埠緩衝區的位元組數,如果當前緩衝區的資料量不足 100 個時,程式會一直停在 VISA 讀取 這個節點上,如果在超時的時間(預設是 10 秒)內還沒有湊足 100 個數據的話,程式就會報 “Time out” 的錯誤,如果超時時間設定得太長,有可能導致程式很長時間停止在 VISA 讀取 這個節點上。

        因此, 我們常採用上面的解決的辦法:使用  “Bytes at Port” 這個串列埠的屬性節點,在儀器I/O子面板下,如下圖:

    也可以在 VISA 資源線上右鍵 >> 建立 >> Instr類的屬性 >> Serial  Settings >> Number of Bytes at Serial Port,如下圖所示:

       這個屬性節點讀取當前串列埠緩衝區有位元組數,然後將它的輸出連線到 VISA  讀取 的 “讀取位元組數” 這個輸入端上即可,這樣當前緩衝區中有多少個位元組就讀回多少個,不會有任何等待。

       目前串列埠的應用大致有兩種型別:一種是儀器控制型別的,一般是上位機發送一個指令,然後下位機作出響應,返回資料給
上位機,上位機再讀取出來,完成一次通訊,即一問一答;另一類是被動接收形的,即下位機會一直髮送資料上來。

、實戰

2.1 讀取串列埠位元組

        我們新建一個空白 VI,藉助串列埠除錯助手和虛擬串列埠,在 LabVIEW 中編寫的一個最簡單的例子:寫一個基本的讀取串列埠位元組的程式,在程式框圖中程式設計如下:

注意這裡,串列埠配置放到迴圈外,不要往復讓這個執行。執行程式,在前面板我們可以看到:

 以下幾點必須注意:

         (1)串列埠有個緩衝區,存在計算機記憶體裡,VISA 讀取,就是從緩衝區讀取資料,讀完之後,讀取的就不存在緩衝區裡了。如果你沒讀取,那就一直在緩衝區裡,直到緩衝區溢位。 

        (2)如果有多個執行緒,都有讀 VISA,或者一個 while迴圈 裡,多個地方同時讀,這樣,肯定會有錯。記住,保證一個串列埠,只有一個讀,或者寫。232 接口裡,讀和寫可以同時進行,因為他是全雙工的。而 485 半雙工 2 線制時候,請注意,讀和寫不可以同時,因為是半雙工。

         (3) 如果你微控制器資料是間隔的,而且每次傳送的是固定的資料。請自己設定VISA 讀取的,位元組數,比如設定為 8。這樣的話,比延時讀取要靠譜的多。

       如果我們需要傳遞的資料是數值型資料呢?我們重新發送:

這是怎麼回事呢?

LabVIEW 從串列埠接收資料時要注意:
        ①假設 LabVIEW 從串列埠接收到的資料為 “1234”(正常顯示模式下),那麼這個資料在串列埠底層的時候其實是這樣的二進位制資料:00110001 00110010 00110011 00110100。只是在 LabVIEW 中,這些二進位制資料是以字串形式顯示出來的,它們的實質還是二進位制資料,這幾個二進位制資料轉換為十進位制資料分別是“49,50,51,52”,由於字串都是以ASCII 碼形式儲存在計算機中的,那麼 49,50,51,52 這幾個數在 ASCII 表中就表示是字串“1,2,3,4”。所以這幾個資料在 LabVIEW 中就顯示為字串的 1,2,3,4 了。

       如果明白這裡面的轉換關係,那麼要進行資料轉換時就很容易了,比如上面的VI中,如果LabVIEW 中接收到的是字串 “XYabcdrfg0123456789”,而原本下位機傳送的是數值型資料,只需要將 “XYabcdrfg0123456789” 字串轉換為對應的 ASCII 值就是實際上下位機傳上來的資料了。LabVIEW 中將字串轉換為對應的 ASCII 值的函式是 “字串至位元組陣列轉換” 這個函式,如下所示:

       這個時候有人要問了,如果我們想把所有的字串接收完後一次性取出來,也就是將串列埠沒有接收的資料拼接到一起,然後集體提取,怎麼辦呢?這個,可以用移位暫存器或者反饋節點,然後用連線字串拼接。我們稍微修改下程式框圖,修改部分用紅框框起來:

接下來,我們用串列埠助手給 Labview程式發生一段文字,看看它的拼接效果:

         當串列埠資源被佔用時,在 LabVIEW 中會報錯,提示串列埠號存在,但當前不能對其進行操作,同時開啟 MAX時也可以在對應的串列埠號下看到同樣的錯誤,這表示這個串列埠已經被其它程式佔用了,比如有時候打開了串列埠除錯助手來除錯串列埠,然後又想在 LabVIEW 裡面試一下,這時就會報這個錯,因為串列埠已經被串列埠除錯助手呼叫了,它不能被二個程式同時使用。解決的方法是關掉其它程式即可,串列埠除錯助手裡也可以關閉這個串列埠。還有一種情況是除錯 OK 後生成 EXE,執行 EXE 也出現這個問題,這時是因為串列埠被原來的 LabVIEW 程式開啟,再用 EXE 開啟時就會報錯,解決辦法是關掉原來的 LabVIEW 程式。最好是關掉 LabVIEW。在使用串列埠的過程中一定要關閉串列埠(使用 VISA CLOSE),否則程式在退出的時候會報錯說資料丟失。

2.2 寫入和讀取串列埠位元組

       上一節我們瞭解了基本的讀取串列埠位元組的程式,接下來我們寫一個稍微複雜點的程式,來實現即可寫入又可讀取串列埠的程式,如下所示:

執行程式,用Labview程式向串列埠除錯助手發生資料:

再用串列埠除錯助手向Labview程式發生資料:

顯然,通訊沒有問題!

這一節的兩個程式我上傳了,下載地址:下載連結

、  官方示例

      我們開啟Labview中的一個官方示例,來欣賞下官方的基本序列寫入和讀取程式,開啟程式框圖如下:

再看看對應的前面板如下所示: