5、網友問答之深入理解WHILE循環-----------labview編程寶典

請支持我敬佩的作者,原帖地址:http://www.eefocus.com/csxcs366/blog/11-01/202294_e0684.html

一些初學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循環結構中的兩個常見問題,希望能解釋的清楚。

 

發佈了9 篇原創文章 · 獲贊 9 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章