他在學習帶參數子程序的編寫,編寫了一個簡單的帶參數的子程序,但是發現在調用時,第一個子程序執行后,第二個子程序也會有輸出,他不知道是為什么?程序很簡單,是我們編程程序經常會用到的一個起保停電路。程序運行結果如下圖所示程序中,I0.0接通后,Q0.0輸出為1,Q0.1不應該為1的卻也為1了。(左側為主程序,右側為子程序)。
下面是我個人之見解,若有分享不當之處,望大家指正,謝謝!
為什么會出現這個情況呢?
這主要是對于子程序中變量的類型應用不正確造成的這種錯誤。子程序中有四種變量類型,分別為:
(1)輸入變量(IN):用于傳遞實際參數進入子程序運算
(2)輸入/輸出變量(IN/OUT):用于把實際參數的初始值傳遞到子程序中進行運算,運算完后把結果放回到該實際參數中,因此這個變量的實際參數不能使用常數。
(3)輸出變量(OUT):該變量分配的實參用于存儲子程序中運算完后的結果
(4) 臨時變量(TEMP):用于存儲子程序中運算的中間結果。
在這四種變量中,對子程序輸出會有影響的主要是后面兩個變量,我們主要了解后面兩個變量的時候,就可以避免帶參數子程序在重復調用時會出現相互干擾的問題。
首先,我們看輸出變量(OUT)的使用,在上面這個朋友所發表的問題中,就是因為輸出變量的問題,所以才造成了這種情況的。
我們可以來分析這個程序,在這個程序中,“啟動”、“停止”這兩個明顯建立的是輸入變量(IN)的變量類型,而“輸出”這個建立的是輸出變量(OUT)類型。我們要分析他為什么會出現干擾,得從PLC的掃描過程,及實操與形參的對應如下圖所示,箭頭方向表示數據傳遞方向。
眾所周知PLC的掃描是從上往下周期型掃描的,所以PLC在執行程序的時候,會先執行網絡1,然后在執行網絡2的程序,所以當執行網絡1的程序的時候,會把實參的狀態傳遞到子程序的形參中,所以對于網絡1的程序來講,形式參數:“#啟動:L0.0”=I0.0,“#停止:L0.1”=I0.1 而實參Q0.0=“#輸出:L0.2”
所以在執行這個子程序時,當I0.0=1,I0.1=0的時候,即按下啟動按鈕I0.0時,形參“#啟動:L0.0=1”, “#停止:L0.1=0”,執行程序后 “#輸出:L0.2=1”因Q0.0= “#輸出:L0.2”,所以Q0.0=1.。
當執行網絡2時,形式參數:“#啟動:L0.0”=I0.2,“#停止:L0.1”=I0.3 而實參Q0.1=“#輸出:L0.2”所以在執行網絡2的程序時,當I0.0=0,I0.1=1時,則:“#啟動:L0.0=0”,“#停止:L0.1=0”因“#輸出:L0.2”在上一個網絡的運行結果為1,所以當“#啟動:L0.0”與“#輸出:L0.2”進行邏輯或運算后,得到的結果為1,然后與“#停止:L0.1”的非做邏輯與運算,所以“#輸出:L0.2”還是保持為1的結果。所以輸出Q0.1=“#輸出:L0.2”=1.
通過這樣的分析,前面調用子程序的輸出狀態或在下個子程序調用中會用到,因此大家就可以理解為什么按下I0.0這個啟動按鈕后,Q0.0 和Q0.1都會有輸出了。
若需要處理這個問題應該如何處理呢?需要處理這個問題,很簡單,我們只需要把這個輸出的變量改成輸入/輸出的變量就可以了,因為輸入/輸出變量,相對于輸出變量來講,他是需要把初始值給到我們的子程序對應的形參去運算,運算完后在給出,還是以剛才的方法去分析,就算前一個網絡中,他的輸出結果“#輸出:L0.2=1”執行到下一個網絡后,因為改成輸入/輸出,會把Q0.1的初始狀態0,給到“#輸出:L0.2”,所以開始運算時是以“#啟動:L0.0”與“#輸出:L0.2”進行邏輯或運算,因兩個狀態都為0,所以運算結果為0,然后跟“#停止:L0.1的非”做邏輯與運算,輸出結果“#輸出:L0.2=0”因此Q0.1=“#輸出:L0.2”=0.所以當你把這個變量改成輸入/輸出變量的時候就不會產生干擾了。
我們再來看另外的一個帶形式參數的子程序,程序如下圖所示:
(1)變量表:
(2)子程序
(3)主程序
大家可以分析下,這個程序,在運行的過程中會不會出現干擾呢?
很明顯,你只需要掌握了前面我們所說的分析方法去分析,你會發現這個程序也是會相互干擾的。
這個程序其實跟我們前面所提到的是一樣的意思,如何去改,大家應該也知道。
若程序改成這樣后,大家覺得是否還是會出現干擾呢?
(1)變量表
(2)子程序
(3)主程序
在程序中,我們把原來開始計算的那個條件給去掉了,換成了SM0.0作為條件,大家可以自己分析下,這個程序會不會出現相互干擾的情況。