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