第三篇 帶參數子程序的參數傳遞過程
一份程序中建立多個子程序,每個子程序完成相對比較獨立的功能。而子程序也是圍繞主程序的要求,并且還根據主程序給出的條件完成這個要求。此時主程序和子程序之間或者說子程序和它下級的子程序之間,就必然有一些數據的交流。下面將介紹一下這種參數的傳遞。
再提一下變量表,子程序里面的變量表,這是最重要的上下級程序之間數據傳遞的方式,但不是唯一的方式。主程序把將要給子程序的數值擺放在一個或一片約定的全局地址,然后子程序讀取這些全局的地址……這種做法作為傳遞參數,最簡單不過。但是,這里不討論這樣的傳遞方式。
現在隨便做一個子程序,觀察一下在主程序中調用時候的外觀。
圖1
圖2
如圖1所示是在主程序里面調用SBR_0的情況,還有一個常見的計數器指令。如圖2所示是SBR_0中變量表所填入的變量設置。
圖1中一個標注SBR_0的指令塊跟計數器指令外觀很相似。但是各自的接口和參數都不同。它們都有觸點接口和數據接口。現在看看子程序的調用,主程序通過什么渠道把參數傳遞到子程序。
SBR_0左邊上方開始有兩個連接著開關觸點的接口。
【EN】有能流表示執行這個子程序。沒有能流的話將從子程序門口經過,不進入子程序。一個子程序就算沒有任何參數都會有這個接口的。
【點輸入1】下邊也是一個能流型的接口,表示這里有一個開關量的能流輸入。
當鼠標指向這個指令塊的時候,會彈出一個框,如圖3所示。這里說明了所有參數的變量類型(in;in/out;out)和數據類型(b;B;W;D)。
圖 3
【字輸入】從彈框得知這是一個字型的輸入參數。這里接口必須填寫一個字型的變量或者常數。
【點輸入2】這也是一個布爾量的輸入參數,但是因為有其余類型的參數分割,導致沒有從開始處連續排列布爾量的輸入參數,所以這個布爾量輸入也顯示為數據接口形式。
【字節入出】從彈框得知這是一個輸入輸出雙向的參數,需要填入一個字節型的變量。
【字輸出】這個參數在右側,位置上已經表明這是一個輸出型的參數。
綜上所述,輸入型的參數將安排在左側的最上方,并且如果上方有連續的開關量,都會以能流的形式連接這個參數。接下來是數據型的輸入參數接口。然后下方是雙向的參數接口。右邊一律是數據接口形式連接所有輸出參數。
上級程序就是通過這樣的接口把子程序所需的參數傳入到子程序的,再進入到子程序里面。接下來看看子程序方面,得到的參數將會是如何出現的。
觀察上面圖2這個變量表。自從建立了這個變量表開始,子程序里面的L地址的前面部分就已經成為了子程序參數的載體。L地址從第一個字節開始,往后安排IN參數;IN/OUT參數;OUT參數。按照字節為最小占用單位來安排能流接口的參數,從L0.0開始向更高位連續安排,EN不占用地址。對于布爾量,一個布爾量點占用整個字節,八個以內的連續布爾量點也占用一個字節。下一個非布爾量參數或者不同類型變量(IN、IN/OUT、OUT)從下一個字節開始安排。所以【點輸入1】參數分配到L0.0,【字輸入】參數分配到LW1。【字節入出】參數分配到LB4。然后子程序使用上級傳遞的參數就只要讀取這些L地址就可以得到。
外面的情況了解了,里面的情況也了解了,參數傳遞……沒說完,還有最不為人知的一部分。
——中間的過程。
中間過程就像一份快遞的工作,在上級下級程序之間搬運數據。只要子程序被調用,那么快遞就會把指定的數據傳送到子程序內。子程序結束后,快遞又會把指定的參數傳送到上級程序的接口。要是沒有接口參數自然沒有這個崗位。
作為用戶程序,只要上級程序把參數放置到位,又在子程序里面存取對應的L地址,中間怎么從上級傳達到下級是無需做任何事情的。這個過程由系統代勞了。但不等于不用理解這個過程。你不知道的事情可能恰恰就在這里。做以下的程序實驗一下。
圖4
建立三個子程序,各自就只有變量表填寫了一行參數,如圖4所示。子程序里面無任何用戶程序。主程序編輯這樣的調用邏輯。把程序下載到PLC,看看執行會怎樣?
PLC運行后,由于程序存在QB0和M0.0,沒有任何用到的其他地址了,所以我們的焦點就關注著這兩個地方,而QB0更是最容易看見。此時輸出點還是熄滅的。用狀態表把M0.0寫入1,與此同時QB0也顯示2#10010000(注意硬件的燈高位在右側,書寫二進制高位在左側。)然后把M0.0寫入0,此時QB0變成顯示2#11001100。我們再次把M0.0寫入1之后QB0再次顯示2#10010000 。
為什么輸出點會有這樣的三種狀態呢?用戶程序完全沒有對輸出點做過邏輯和賦值,而子程序里面也沒有任何程序。能夠有動作的只能是系統的動作了。究竟會是什么時候使輸出點得到了一些值?程序里面唯一跟QB0有點關系的就是SBR2子程序了。為什么SBR0、SBR1兩個子程序的值會到了SBR2子程序里面去的?那么就要理一理參數傳遞的中間過程了。
運行初期,網絡1不接通,網絡2沒產生邊沿信號。前兩個子程序都沒有調用。唯獨第三個子程序SBR2一直在調用。
接通M0.0,SBR0得到了執行。在進入子程序后,運行子程序用戶指令之前,系統把引腳上的IN參數值復制到了LB0。然后執行子程序的用戶程序,由于沒有程序可運行,退出了子程序。
網絡2沒有執行子程序。網絡3一直在執行。SBR2子程序沒有輸入參數,沒有子程序內容,離開子程序之前,系統必須要給一個值到輸出參數。系統的這個動作不會因為程序中有沒有內容或者說程序執行的怎么樣,而不去做這個傳送,它是必然會做這個動作的。那么這個時候,LB0到底是一個什么值呢?我們就要追溯到這個LB0最后賦值的是什么地方。之前由于執行SBR0輸入參數使LB0曾經有過2#10010000這個值。這個值由于遵從多重賦值的原因,這個值在當時產生,一直擱置到現在,被SBR2撈上來了,然后就給了QB0。當M0.0恢復到0時,SBR1前的上升沿發生了,調用了一次。就這一次,把LB0寫入了2#11001100。在沒有什么地方再給LB0寫入值的情況下,LB0將不會改變。(當一個子程序不調用的時候,并不會由此使得某些線圈、某些地址自動復位為零,但是仍有不少的人有這樣的錯覺。)大家也可以參考M0.0,編程軟件寫入了的值可以一直保持住的。你沒有去更改它,還有誰去修改它?所以把一個值寫入到某地址之后,就可以一直保持住,SBR2也就可以輸出2#11001100這個值。
手冊并沒有說明局部儲存區的值是從何而來,手冊上面有一段話,如圖5所示。
圖 5
我有一個觀點,當手冊沒有清楚說明的情況下,我會假設一種較為合理的假設,然后在日后的編程中一直證實這個假設,并使用這種假設,同時一直關注著這個問題。假如一直使用都沒有明確顯示這種假設不成立,將認為這是真的,繼續使用。我總覺得PLC只會按照有限的法則以固定的方法實施一些運算。既然一個假設一直沒有被推翻,那么這個假設可能永遠也不會被推翻。
-
數據
+關注
關注
8文章
7002瀏覽量
88943 -
參數
+關注
關注
11文章
1829瀏覽量
32195 -
程序
+關注
關注
117文章
3785瀏覽量
81004
原文標題:使用S7-200 SMART 編寫一個自己的指令-3
文章出處:【微信號:從零學PLC,微信公眾號:從零學PLC】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論