路則明
(濟南中正金碼科技有限公司,山東濟南 250101)
Smart PLC提供的程序構架包含:主程序、子例程和中斷程序。
因為SBR子例程在形式上類似FB塊,為了實現FB塊編程,我們需要從SBR找到突破口。為此,我們研究一下子例程所對應的變量表。下面是某個子例程的變量表:
變量類型為IN的變量共6個:
Act、Feedback、Button_reset、Time_100ms、Pointer和SN。它們對應的數據類型分別為BOOL、BOOL、BOOL、INT、DWORD、DWORD。
變量類型為IN_OUT的變量共1個:
Alarm,其數據類型為BOOL。
變量類型為TEMP的變量共5個:
Time_count、Act_previous、SN_32x、Clock_strobe和Act_latched,它們的數據類型均為DWORD。
可以看出,變量類型有IN、OUT、IN_OUT和TEMP類型。其中,TEMP是臨時變量。我們知道,PLC是掃描執行的,當PLC再次掃描執行到該SBR時,上次調用中計算得到的存在于TEMP變量中的結果將全部丟失,這就給我們用FB塊編程帶來了困難。
1500是西門子的中型PLC,與smart的變量表相比,其FB塊中的變量類型多了最關鍵的一種:靜態變量Static。此種變量的特點:FB在每次掃描周期的調用過程開始,其值能夠保持為上次調用過程中計算的結果。
DB中的Static型變量,保證了運算結果的正確性。
三菱Q系列PLC,則是預先在“自動分配軟元件設置”界面設定好需要的寄存器等資源。編程中調用FB塊時,GX WORKS2軟件自動給該FB塊分配所需的軟元件即全局變量,無須人工指定。
該PLC不支持背景數據塊,也不支持由系統自動分配FB塊所需要的全局變量資源。
首先,我們以SBR為依托,把程序語句編寫在SBR內,而SBR的某個IN型形參則由全局變量指針賦值。在SBR中,我們用傳入的全局變量指針開辟出一塊全局數據區,SBR內程序的運行所需要的變量資源由此全局數據區、IN型、IN_OUT型、OUT型變量組成。
下面我們通過一個例子看具體實現:
在圖1中,“Function_報警”就是一個FB塊,它對應的變量表如前述第1節所示。

圖1 FB塊調用
假如有3個氣缸,每個氣缸在末端都安裝有磁性開關,程序中需要通過磁開的狀態來確定氣缸是否運動到位,若沒有運動到位則報警。用上述FB塊來實現本功能,在主程序中可以按圖1形式來調用。其中:
Act:氣缸伸出時的Q輸出點;
Feedback:伸出到位磁開對應的I輸入點;
Time_100ms:報警時間預設值。若氣缸從伸出開始直到伸出到位用時2000ms,則此值可設定為22,因本FB塊內部的時基是100ms,表示經過22×100=2200ms后,還沒檢測到Feedback對應的磁開則報警。
Alarm:報警標志位。
Button_reset:復位按鈕,用于復位該報警。
下面分析其余的2個IN型變量Pointer和SN及5個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,表示調用本FB塊所需要的序號。可求出其余TMEP型變量所對應的指針,例如,經過乘法運算*D后,SN_32x的值為32;經過第一個加法運算+D語句后,Time_count的值則為&VB132;以此類推,Act_previous的值為&VB134;Clock_strobe的值為 &VB135;Act_latched的值為&VB136。
程序段(1)的作用:本程序段用于初始化臨時變量即TEMP型變量,為TEMP型變量分配指向PLC全局變量的指針。這就保證了主程序中每次掃描執行該FB塊的調用程序時,FB塊中臨時變量的值并不是隨機的,而是上次掃描執行所計算的結果。
下面的程序段(2)是Time_count的使用:
(2) LDB= *#Act_latched, 1
A 時鐘_100ms
LPS
AB= *#Clock_strobe, 0
AB= *#Act_previous, 1
+I 1, *#Time_count
LPP
MOVB 1, *#Clock_strobe
其中,“時鐘_100ms”是定時器T33,它和定時器T34構成周期為100ms的方波。當Act_latched的值為1時,通過加法指令+I,Time_count存儲的是氣缸開始動作后以100ms為時基的計數器值。
可以看出,如果沒有前述(1)中的初始化,Time_count不指向全局變量的話,我們就無法得到正確的計數器值。
在程序段(1)中,*D語句的功能實際上是通過 SN*32來計算出相應FB塊用的全局變量的指針偏移。假如我們還要在主程序中調用“Function_報警”FB塊兩次,而Pointer為 &VB100保持不變,則在調用它們時,SN分別賦值為2和3,那么對應的FB塊中的Time_count的值則為 &VB166和&VB198。也就是說,每次調用,用PLC中不同塊區的全局寄存器VB作為相應FB塊的資源,保證了多次調用的運行結果正確。
在SBR子例程的入口參數中,增加兩個IN型形參Pointer和SN,調用時把全局寄存器VBxxx的地址指針即&VBxxx傳遞給Pointer,并用不同的SN作為塊調用的序列號,就能實現類似中型PLC所具有FB塊編程的功能。