路則明
(濟(jì)南中正金碼科技有限公司,山東濟(jì)南 250101)
Smart PLC提供的程序構(gòu)架包含:主程序、子例程和中斷程序。
因?yàn)镾BR子例程在形式上類似FB塊,為了實(shí)現(xiàn)FB塊編程,我們需要從SBR找到突破口。為此,我們研究一下子例程所對(duì)應(yīng)的變量表。下面是某個(gè)子例程的變量表:
變量類型為IN的變量共6個(gè):
Act、Feedback、Button_reset、Time_100ms、Pointer和SN。它們對(duì)應(yīng)的數(shù)據(jù)類型分別為BOOL、BOOL、BOOL、INT、DWORD、DWORD。
變量類型為IN_OUT的變量共1個(gè):
Alarm,其數(shù)據(jù)類型為BOOL。
變量類型為TEMP的變量共5個(gè):
Time_count、Act_previous、SN_32x、Clock_strobe和Act_latched,它們的數(shù)據(jù)類型均為DWORD。
可以看出,變量類型有IN、OUT、IN_OUT和TEMP類型。其中,TEMP是臨時(shí)變量。我們知道,PLC是掃描執(zhí)行的,當(dāng)PLC再次掃描執(zhí)行到該SBR時(shí),上次調(diào)用中計(jì)算得到的存在于TEMP變量中的結(jié)果將全部丟失,這就給我們用FB塊編程帶來(lái)了困難。
1500是西門子的中型PLC,與smart的變量表相比,其FB塊中的變量類型多了最關(guān)鍵的一種:靜態(tài)變量Static。此種變量的特點(diǎn):FB在每次掃描周期的調(diào)用過程開始,其值能夠保持為上次調(diào)用過程中計(jì)算的結(jié)果。
DB中的Static型變量,保證了運(yùn)算結(jié)果的正確性。
三菱Q系列PLC,則是預(yù)先在“自動(dòng)分配軟元件設(shè)置”界面設(shè)定好需要的寄存器等資源。編程中調(diào)用FB塊時(shí),GX WORKS2軟件自動(dòng)給該FB塊分配所需的軟元件即全局變量,無(wú)須人工指定。
該P(yáng)LC不支持背景數(shù)據(jù)塊,也不支持由系統(tǒng)自動(dòng)分配FB塊所需要的全局變量資源。
首先,我們以SBR為依托,把程序語(yǔ)句編寫在SBR內(nèi),而SBR的某個(gè)IN型形參則由全局變量指針賦值。在SBR中,我們用傳入的全局變量指針開辟出一塊全局?jǐn)?shù)據(jù)區(qū),SBR內(nèi)程序的運(yùn)行所需要的變量資源由此全局?jǐn)?shù)據(jù)區(qū)、IN型、IN_OUT型、OUT型變量組成。
下面我們通過一個(gè)例子看具體實(shí)現(xiàn):
在圖1中,“Function_報(bào)警”就是一個(gè)FB塊,它對(duì)應(yīng)的變量表如前述第1節(jié)所示。
圖1 FB塊調(diào)用
假如有3個(gè)氣缸,每個(gè)氣缸在末端都安裝有磁性開關(guān),程序中需要通過磁開的狀態(tài)來(lái)確定氣缸是否運(yùn)動(dòng)到位,若沒有運(yùn)動(dòng)到位則報(bào)警。用上述FB塊來(lái)實(shí)現(xiàn)本功能,在主程序中可以按圖1形式來(lái)調(diào)用。其中:
Act:氣缸伸出時(shí)的Q輸出點(diǎn);
Feedback:伸出到位磁開對(duì)應(yīng)的I輸入點(diǎn);
Time_100ms:報(bào)警時(shí)間預(yù)設(shè)值。若氣缸從伸出開始直到伸出到位用時(shí)2000ms,則此值可設(shè)定為22,因本FB塊內(nèi)部的時(shí)基是100ms,表示經(jīng)過22×100=2200ms后,還沒檢測(cè)到Feedback對(duì)應(yīng)的磁開則報(bào)警。
Alarm:報(bào)警標(biāo)志位。
Button_reset:復(fù)位按鈕,用于復(fù)位該報(bào)警。
下面分析其余的2個(gè)IN型變量Pointer和SN及5個(gè)TEMP型變量Time_count、Act_previous、SN_32x、Clock_strobe和Act_latched在程序中的使用,首先看下面程序段(1):
(1)LD Always_On
MOVD #SN, #SN_32x
*D +32, #SN_32x
MOVD #SN_32x, #Time_count
+D #Pointer, #Time_count
MOVD +2, #Act_previous
+D #Time_count, #Act_previous
MOVD +3, #Clock_strobe
+D #Time_count, #Clock_strobe
MOVD +4, #Act_latched
+D #Time_count, #Act_latched
其中,Pointer為 &VB100,即寄存器VB100的指針。SN為1,表示調(diào)用本FB塊所需要的序號(hào)??汕蟪銎溆郥MEP型變量所對(duì)應(yīng)的指針,例如,經(jīng)過乘法運(yùn)算*D后,SN_32x的值為32;經(jīng)過第一個(gè)加法運(yùn)算+D語(yǔ)句后,Time_count的值則為&VB132;以此類推,Act_previous的值為&VB134;Clock_strobe的值為 &VB135;Act_latched的值為&VB136。
程序段(1)的作用:本程序段用于初始化臨時(shí)變量即TEMP型變量,為TEMP型變量分配指向PLC全局變量的指針。這就保證了主程序中每次掃描執(zhí)行該FB塊的調(diào)用程序時(shí),F(xiàn)B塊中臨時(shí)變量的值并不是隨機(jī)的,而是上次掃描執(zhí)行所計(jì)算的結(jié)果。
下面的程序段(2)是Time_count的使用:
(2) LDB= *#Act_latched, 1
A 時(shí)鐘_100ms
LPS
AB= *#Clock_strobe, 0
AB= *#Act_previous, 1
+I 1, *#Time_count
LPP
MOVB 1, *#Clock_strobe
其中,“時(shí)鐘_100ms”是定時(shí)器T33,它和定時(shí)器T34構(gòu)成周期為100ms的方波。當(dāng)Act_latched的值為1時(shí),通過加法指令+I,Time_count存儲(chǔ)的是氣缸開始動(dòng)作后以100ms為時(shí)基的計(jì)數(shù)器值。
可以看出,如果沒有前述(1)中的初始化,Time_count不指向全局變量的話,我們就無(wú)法得到正確的計(jì)數(shù)器值。
在程序段(1)中,*D語(yǔ)句的功能實(shí)際上是通過 SN*32來(lái)計(jì)算出相應(yīng)FB塊用的全局變量的指針偏移。假如我們還要在主程序中調(diào)用“Function_報(bào)警”FB塊兩次,而Pointer為 &VB100保持不變,則在調(diào)用它們時(shí),SN分別賦值為2和3,那么對(duì)應(yīng)的FB塊中的Time_count的值則為 &VB166和&VB198。也就是說,每次調(diào)用,用PLC中不同塊區(qū)的全局寄存器VB作為相應(yīng)FB塊的資源,保證了多次調(diào)用的運(yùn)行結(jié)果正確。
在SBR子例程的入口參數(shù)中,增加兩個(gè)IN型形參Pointer和SN,調(diào)用時(shí)把全局寄存器VBxxx的地址指針即&VBxxx傳遞給Pointer,并用不同的SN作為塊調(diào)用的序列號(hào),就能實(shí)現(xiàn)類似中型PLC所具有FB塊編程的功能。