《LabVIEW工程之道》稀飯2-程序流程式控制制之循環結構
來自專欄 LabVIEW工程實踐之路1 人贊了文章
說明:本部分來自於之前的《LabVIEW實踐之路》章節,當時用的8.2版LabVIEW,用於不太熟悉的兄弟們入門時的補充。由於同《LabVIEW工程之道》思路上區別不小,所以以附加文檔(稀飯)的形式給出,吃大餐式也可以來點稀飯~~
說明+:網頁排版有問題,見諒!
強筋健骨:由程序流程的控制展開
按照通常的教程,現在一般要介紹各種數據類型,例如數字、字元串、數組與簇等等。不過從程序結構入手,在掌握流程式控制制VI的同時認識各數據類型應該更有效,畢竟如果老是把目光集中在樹木上,那很容易忘了鬱鬱蔥蔥的森林。
本章仍然通過實例來學習,依次完成For循環、While循環、條件結構、順序結構、事件結構、公式節點等LabVIEW實例。
2.1 循環結構
循環結構是任何程序設計語言都必不可少的,尤其是For循環、While循環等。以下將通過實例學習LabVIEW的循環結構以及移位寄存器的用法。
2.1.1 For循環
看一下圖,For循環的尊容很容易記。左上角N是循環體內程序執行的循環次數,內部的i是當前循環次數(第一次從0開始計數)。LabVIEW的For循環執行過程中是無法中斷跳出的,這一點必須明白。另外,雖然左上角的N用來連接總的循環次數值,但許多情況下For循環可以應用「自索引」方法,不用連接N,讓循環自動進行,這種方法在數組等類型執行For循環時非常普遍。(其實說白了也很簡單,諸如新的JAVA版本也支持數組等類型的迭代而不用先求出數組的length,別急,一會兒給幾個例子對比一下)
好的,我們先來最簡單的,同時產生1024點的隨機數(0~1之間)和一個周期的正弦波
,如圖2.1所示。
上面的例子中For循環次數為1024次,循環體內上部為隨機數產生器,下部是正弦函數值。每次循環各產生一個隨機數和
的正弦值。注意:當循環完成退出時,循環體右側,邊框上連接內外數據的小方框就起到了自動索引的作用:將你各次循環的結果按順序排列成數組進行輸出。當然,有時候我們不需要自索引輸出,那可以在索引方框上點右鍵取消的,不過想一想,取消自索引後輸出應該是什麼?我問的問題太沒有難度了,呵呵。
當然,自索引在輸入端也是可以使用的,而且會帶來意想不到的方便,尤其是同移位寄存器結合使用。閑話少說,下面我們就實現一個求一維DBL數組最大值和最小值的程序。哦,為了養成良好習慣,我們畫一下演算法的流程簡圖吧(對了,下面的流程簡圖說明一下問題幫助編程,相信你能做得更好)。如圖2.2所示,為了便於說明問題,我們假定數組非空。
我們直接給出了實現的程序,注意,圖2.3和圖2.4的兩個框圖程序都能夠得到圖2.5所示的正確結果,可能其中幾個vi、循環兩側的移位寄存器以及2.3中的條件結構有些陌生。除了這些,兩個程序有什麼不一樣嗎?
先說一下有些陌生的東西。圖2.3中在循環里應用了條件結構,條件框可對真和假兩種情況作出不同的處理,不過不要急,下一小節再講它。那麼數組在開始循環之前使用
獲得了數組長度,並賦給For循環的循環次數N,這時候在循環內部i就會從0循環遞增到N-1,於是我們使用索引數組函數
依次獲得第i個數組元素。每次獲得當前元素後,都同最大值max、最小值min進行比較,以獲得整個數組的最大最小值。當然,我們用-∞初始化max和用+∞初始化min都是為了從第一個數組元素開始就能夠正確的完成最大值、最小值的查找。這兒有一個關鍵的實現---移位寄存器,也就是循環框上的
。你可以在循環框上點右鍵,選擇「添加移位寄存器」
便會發現在循環框架的左右出現了一對。沒錯,移位寄存器是成對出現,它的工作原理是:第i次循環的輸出(右側)即是第i+1次循環的輸入(左側)。具體到圖2.3所示的程序,進入循環體時max移位寄存器初始化為-∞,而min初始化為+∞。第一次循環時數組元素3讀入,分別與max、min的值比較,結果是max、min被置為3;第二次循環時max、min的值都已經變成了3,這一次循環讀入2,比較後min的結果置為了2……。以此類推,直至循環結束。
圖2.4功能與圖2.3完全一樣,注意,為什麼For循環左上角的循環次數N並沒有賦值?因為數組進入循環體是使用了自索引(如果你連接數組和For循環體,默認就是自索引),For循環回自動從頭到尾依次獲取每一個元素的值,對我們編程節省不少力氣。另外程序用選擇函數
代替條件結構,這個函數能夠用於大多數雙值選擇的情況,但必須是相同類型(如從兩個整型、兩個字元串……中根據真假選擇),上方輸入提供邏輯真時的輸出,下方輸入則提供邏輯假時的輸出,中間則是判別邏輯(真或假)。
肯定有學過LabVIEW的小盆友會說,數組最大值、最小值有專門的VI可以調用,不用這麼麻煩。沒錯,數組函數里數組最大值與最小值函數
能夠直接完成此功能,並且給出最大值、最小值出現的位置。我們舉例是為了學習,並且你也可以繼續完善我們的例子實現更多的功能。
如果我們在程序運行前無法知道循環次數怎麼辦?或者需要中途可以中斷跳出的循環時?當然是While循環了。
2.1.2 While循環
While循環特徵也很明顯
,除了內部的當前循環次數i同For循環相同外,由於通常用於無法預知循環次數的循環,所以內部的
是用來連接跳出循環的條件:輸入為真時結束循環。如果你在上點右鍵,可以選擇輸入為真時繼續循環(即輸入為假時結束循環),圖標變為。
好的,我們先來實現一個簡單的While循環:求0+1+2+…+n的值,置於n是多少,我們就讓它隨機吧,直到我們點擊退出按鈕時再停止。最終需要顯示n的值和求和的值。程序框圖和前面板如圖2.6所示。
使用While循環有幾個問題需要注意:
1、 計數i從0開始,While循環至少會運行一次。而For循環如果循環次數N設為0(或空數組自索引),則一次也不會循環。
2、 合理循環終止方式。如果是通過內部條件觸發(如循環3000次後自動停止等),則要注意演算法不要有問題;如果是通過點擊按鈕退出,那要注意按鈕的機械動作(後面會講)和循環條件類型。
3、 While循環裡面盡量不要出現While循環的嵌套。While循環裡面還有While循環很容易導致死循環,而且幾乎所有的問題都有不適用嵌套的解決方法。
4、 While循環內要根據情況設置延時。許多While循環是需要一直運行來進行事件處理,如果不加延時會全速循環,耗費大量系統資源。而許多情況下,幾十甚至幾百個毫秒的延時不會對程序的功能和人機交互帶來任何問題。
許多東西需要在實踐中總結和改進,並且經驗也不是適用於一切場合的。
那麼我們再來實現一個While循環的例子:使用While循環繪製圖表,我們用到While循環、隨機數發生函數、波形圖表(chart)、延時函數,如圖2.7。
通過調整延時的毫秒倍數,你能很輕鬆的控制循環的速度。但注意的是,這種定時方式不是一種精確的方法,不能用於非常精密的需求中。
還有一點必須強調一下,While循環(包括For循環等)中如果存在並行執行的框圖程序,那麼只有等到所有程序都執行完一次循環後,才能進入下一次循環的執行。如果出現有快有慢的程序段,那對不起了,等著吧,這裡的規矩就是不拋棄不放棄!圖2.8很好的說明了問題。
在2.8的While循環中,兩個紅框是並行的程序,其中一個用來處理各種計算等任務,另一個用來檢測按鈕狀態決定是否退出。由於檢測狀態非常簡單,所以瞬時便執行完,而計算任務則需要耗費一秒多時間,所以如果在這期間按鈕狀態變為了真,對不起,當時是不能退出程序的,等到這一次循環的計算任務也完成了,程序進入下一次循環時才能退出。同樣,三個紫色框內是低一層的並行任務,由於其中的For循環最耗費時間,從前面板執行結果可以看出,當最下面的顯示「While循環i值」執行完顯示到3時,For循環還在努力中,顯示為2。所以並行是好東西,但要用好。我曾看到過有人編寫的採集程序大致每秒鐘循環50次;但由於把一些網路查詢反饋等比較耗時的操作放到了採集循環中,就導致了採集程序一直等著其執行完成後才能繼續下一次循環,經常會緩衝溢出報錯和丟失數據。(那怎麼辦?後面會說的,別急)
推薦閱讀:
※如何利用labview實現在一張圖中檢測出車牌的號碼?
※怎麼對下面的程序提高運算速度?
※LabVIEW2018發布,帶來了Python支持
※Labview+Arduino+ADXL345數據採集
TAG:LabVIEW |