本文非常詳細的講述了LabVIEW中While迴圈的特點和使用時需要注意的問題,其有別於C語言的特點,值得我們深入體會。

——————————————————————————————————————————————————————————

一些初學LV的網友們近期發給我的郵件中多次談到WHILE迴圈的一些問題,這些問題雖然很常見,但是是根本性的問題,原因在於這些問題之所以不容易理解,是因為剛剛接觸LV,很難理解或者經常忽視了“資料流”的問題。

首先簡要回顧一下WHILE迴圈的基本概念和特點,然後重點回復網友們有關WHILE迴圈的問題。

幾乎所有有關LV的書籍中都把WHILE結構與C語言的DO WHILE迴圈相提並論 ,其實二者之間是存在很大差別的,其根本區別在於LV是基於資料流驅動的,而C語言則不是。

DO WHILE迴圈可以保證迴圈至少執行一次,LV中的WHILE結構也是如此,這是二者之間的共同點。C語言中的WHILE結構如下所示:

do{

// do sth

}while(condition)

我們需要特別注意的是,C語言中DO WHILE迴圈判斷迴圈條件是在迴圈中所有語句執行之後,簡單地說就是“先執行,後判斷”,LABVIEW中的迴圈結構則不然,這導致了很多LV初學者很難理解LV中WHILE迴圈的一些特殊現象。

1、可以同時執行多個WHILE迴圈結構。

同時執行多個WHILE迴圈結構在C語言中是比較麻煩的,必須開闢多個執行緒,而LABVIEW是自動多執行緒的。LABVIEW不僅可以同時並行執行多個WHILE結構,甚至在每個while迴圈中可以同時執行多個數據流程。

多了同時執行的WHILE迴圈可以分成兩類:

一類是一個VI中多個同時執行的WHILE迴圈。多個WHILE迴圈在同一程式框圖中。

另一類是每個子VI擁有各自的WHILE迴圈,此時多個WHILE迴圈同時工作相當於WINDOWS的多視窗執行。

2、每個迴圈中必須增加延時函式,釋放系統控制權。

如果在迴圈中沒有延時類函式,將導致WHILE迴圈獨佔CPU,CPU佔用率很快達到100%。

3、僅執行一次的WHILE迴圈+未初始化的移位暫存器。這就是著名的LV2(功能)全域性變數。

--------------------------------------------------------------------------------------------------------------------------------

下面解釋一下網友的問題:

問題一、WHIEL迴圈中,假如等待函式設定為10秒(10000),在2秒時按下停止按鈕,過了8秒迴圈仍然不能停止,這是為什麼。

我們先看看C語言中,DO WHILE迴圈+延時函式的情形。

do{

//do sth

Sleep(10000);//有些編譯器使用Delay()函式,效果相同,目的延時

while(!Stop)

上面的程式中,程式必須保證從開始延時至結束延時為10秒中,其中任意時刻停止為TRUE,WHILE迴圈實際工作時間為10秒。

LV中類似的程式框圖如下圖所示:

無論我們在迴圈啟動10秒內任意時刻按下STOP按鈕,WHILE迴圈經歷的時間都是20秒。很顯然這不是一個簡單的DO WHILE迴圈,C語言中,同樣的情況WHILE迴圈僅執行了一次,而LV中的WHILE迴圈卻執行了2次,導致兩次呼叫WAIT函式,延時20秒。

二者之間的區別在於檢查迴圈條件的時刻。C語言中的DO WHILE迴圈之在迴圈結束時檢查迴圈條件的,LV中的WHILE迴圈則不然。在迴圈開始時,等待函式與檢查STOP按鈕的值是同時發生的。

LV是資料流驅動的,一段框圖的執行與否在於它的輸入端子是有資料流動進來。迴圈開始時,由於WHILE迴圈條件端子上,STOP按鈕的值直接流入,所以開始時就判斷結束條件。由於開始時STOP為FALSE,此時決定了本次迴圈結束後,還要進行下一次迴圈。在讀取結束條件的同時,WAIT函式開始延時10秒。

在延時10秒過程中,我們按下了停止按鈕。STOP按鈕需要LV回讀時,才會自動恢復,我們可以看到,在10秒結束前,STOP一直處於按下狀態。

WAIT函式等待10秒完成後,此時進入第二個迴圈,同樣檢查結束條件,此時停止按鈕按下,下一個迴圈不再執行,但是此時等待函式第二次執行,等待10秒。兩次執行等待函式,導致最後延時20秒鐘。

回過頭來,我們能否使LV中的WHILE迴圈真正像C語言中的DO WHILE一樣執行那,我們只要改變LV中WHILE迴圈讀取結束條件的時刻就可以實現了,如下圖所示。

我們只要在10秒內按下停止按鈕,則迴圈經歷的時間為10秒,同上面C語言的DO WHILE迴圈功能完全相同了。原因在於我通過順序結構,強行改變了讀取STOP的時刻,即等待結束後讀取結束條件。由於此時STOP為TRUE,所以下一次迴圈不再執行,退出。

上面我解釋了延時為什麼執行了兩次的問題,實際上我們根本就不需要一個長時間延時的WHILE迴圈。對於一個幾秒、幾分鐘、甚至幾個小時才執行一次的需求,根本不需要建立一個獨立的WHILE迴圈。

比如每分鐘執行一次的程式,一個WHILE迴圈的延時為100毫秒,則可以對這個迴圈進行計數,當迴圈次數為60*10的整數倍時,就是經歷了每個分鐘的時刻。

問題二:為什麼在WHILE迴圈中使用事件結構時,停止按鈕需要按兩次才能結束?

這個問題的出現實際上原因於問題一相同。

事件結構的特點是:一旦執行則處於等待狀態。一旦有事件發生,則響應事件後,結束事件結構。

首次迴圈開始時,由於STOP為FALSE,開始時判斷迴圈條件,則下次依然要進行迴圈。本次迴圈執行中,事件結構處於等待事件中。

迴圈執行過程中,按下STOP.則事件結構響應事件後立即結束,同時迴圈結束條件為TRUE,不再進入下一個迴圈。但是如同問題一一樣,我們依然要執行第二次迴圈,因此,事件結構處於等待中,再按下STOP,又產生新的值變化事件,迴圈結束。

解決這個問題有兩個方法:

一、如同問題一一樣,強行規定讀取STOP的時刻,把STOP放置在STOP值變化事件分支中。

二:使用TIMEOUT超時事件,TIMETOUT導致事件不斷髮生,因此可以自動觸發事件結構,結束迴圈。

推薦使用把讀取STOP放置在STOP值變化事件分支中。

上面我詳細第介紹了WIHILE迴圈結構中的兩個常見問題,希望能解釋的清楚。

.