- 零起點學西門子S7-300/400 PLC
- 李方園
- 3892字
- 2020-11-21 15:45:35
3.2 STL編程常見指令
3.2.1 裝入指令、傳送指令在尋址中的編程
裝入(Load,L)指令將源操作數裝入累加器1,而累加器1原有的數據移入累加器2。
裝入指令可以對字節(8位)、字(16位)、雙字(32位)數據迸行操作。
傳送(Transfer,T)指令將累加器1中的內容寫入目的存儲區中,累加器1的內容不變。
1.立即尋址的裝入與傳送指令
立即尋址的操作數直接在指令中。
【實例】 使用立即尋址的例子。
L-35 //將16位十進制常數-35裝入累加器1的低字ACCU1-L
L L#5 //將32位常數5裝入累加器1
L B#16#5A //將8位十六進制常數裝入累加器1最低字節ACCU1-LL
L W#16#3E4F //將16位十六進制常數裝入累加器1的低字ACCU1-L
L DW#16#567A3DC8 //將32位十六進制常數裝入累加器1
L 2#0001_1001_1110_0010 //將16位二進制常數裝入累加器1的低字ACCU1-L
L 25.38 //將32位浮點數常數(25.38)裝入累加器1
L ‘ABCD’ //將4個字符裝入累加器1
L TOD#12:30:3.0 //將32位實時時間常數裝入累加器1
L D#2004-2-3 //將16位日期常數裝入累加器1的低字ACCU1-L
L C#50 //將16位計數器常數裝入累加器1的低字ACCU1-L
L T#1M20S //將16位定時器常數裝入累加器1的低字ACCU1-L
L S5T#2S //將16位定時器常數裝入累加器1的低字ACCU1-L
L P#M5.6 //將指向M5.6的指針裝入累加器1
L B#(100,12,50,8) //裝入4字節無符號常數
2.直接尋址的裝入與傳送指令
直接尋址在指令中直接給出存儲器或寄存器的區域、長度和位置,例如用MW200指定位存儲區中的字,地址為200。
【實例】 直接尋址的程序實例:
A I0.0 //輸入位I0.0的“與”(AND)操作
L MB10 //將8位存儲器字節裝入累加器1最低的字節ACCU1-LL
L DIW15 //將16位背景數據字裝入累加器1的低字ACCU1-L
L LD22 //將32位局域數據雙字裝入累加器1
T QB10 //將ACCU1-LL中的數據傳送到過程映像輸出字節QB10
T MW14 //將ACCU1-L中的數據傳送到存儲器字MW14
T DBD2 //將ACCU1中的數據傳送到數據雙字DBD2
3.寄存器間接尋址
在存儲器間接尋址指令中,給出一個作地址指針的存儲器,該存儲器的內容是操作數所在存儲單元的地址。在循環程序中經常使用存儲器間接尋址。
地址指針可以是字或雙字,定時器(T)、計數器(C)、數據塊(DB)、功能塊(FB)和功能(FC)的編號范圍小于65535,使用字指針就夠了。
其他地址則要使用雙字指針,如果要用雙字格式的指針訪問一個字、宇節或雙字存儲器,必須保證指針的位編號為0,例如P#Q20.0。
L QB[DBD 10] //將輸出字節裝入累加器1,輸出字節的地址指針在數據雙字
//DBD10中;如果DBD10的值為2#00000000000000000000
//000000100000,裝入的是QB4
A M[LD 4] //對存儲器位作“與”運算,地址指針在數據雙字LD4中。如果
//LD4的值為2#00000000000000000000000000100011,
//則是對M4.3進行操作
存儲器間接尋址的雙字指針格式如圖3-17所示,共有兩種。
圖3-17 存儲器間接尋址的雙字指針格式
其中第0~2位(xxx)為被尋址地址中位的編號(0~7),第3~18位為被尋址地址的字節的編號(0~65535)。第24~26位(rrr)為被尋址地址的區域標識號,第31位x=0為區域內的間接尋址,第31位x=1為區域間的間接尋址。
第一種地址指針格式存儲區的類型在指令中給出,例如L DBB[AR1,P#6.0]。在某一存儲區內尋址。第24~26位(rrr)應為0。
第二種地址指針格式的第24~26位還包含存儲區域標識符rrr,為區域間寄存器間接尋址。表3-2為寄存器間接尋址的區域標識位
如果要用寄存器指針訪問一個字節、字或雙字,必須保證指針中的位地址編號為0。
指針常數#P5.0對應的二進制數為2#0000 0000 0000 0000 0000 0000 0010 1000。
【實例】 區域內間接尋址的例子。
L P#5.0 //將間接尋址的指針裝入累加器1
LAR1 //將累加器1中的內容送到地址寄存器1
表3-2 寄存器間接尋址的區域標識位
A M[AR1,P#2.3] //AR1中的P#5.0加偏移量P#2.3,實際上是對M7.3進行操作
= Q[AR1,P#0.2] //邏輯運算的結果送Q5.2
L DBW[AR1,P#18.0] //將DBW23裝入累加器1
【實例】 區域間間接尋址的例子。
L P#M6.0 //將存儲器位M6.0的雙字指針裝入累加器1
LAR1 //將累加器1中的內容送到地址寄存器1
T W[AR1,P#50.0] //將累加器1的內容傳送到存儲器字MW56
P#M6.0對應的二進制數為2#1000 0011 0000 0000 0000 0000 0011 0000。因為地址指針P#M6.0中已經包含有區域信息,使用間接尋址的指令T W[AR1,P#50]中沒有必要再用地址標識符M。
4.地址寄存器的裝入與傳送指令
用地址寄存器的裝入與傳送指令可以不經過累加器1,與地址寄存器AR1和AR2交換數據。
【實例】 應用地址寄存器AR1和AR2的實例。
LAR1 DBD20 //將數據雙字DBD20中的指針裝入AR1
LAR2 LD180 //將局域數據雙字LD180中的指針裝入AR2
LAR1 P#M10.2 //將帶存儲區標識符的32位指針常數裝入AR1
LAR2 P#24.0 //將不帶存儲區標識符32位指針常數裝入AR2
TAR1 DBD20 //AR1中的內容傳送到數據雙字DBD20
TAR2 MD24 //AR2中的內容傳送到存儲器雙字MD24
3.2.2 比較指令
表3-3為比較指令的STL表達方式,表中“?”可以是“==”,“<>”,“>”,“<”“>=”,“<=”。
用于比較累加器1與累加器2中的數據大小,被比較的兩個數的數據類型應該相同。如果比較的條件滿足,則RLO為1,否則為0。狀態字中的CC0和CC1位用來表示兩個數的大于、小于和等于關系(見表3-4)。
【實例】 比較兩個浮點數的例子:
表3-3 比較指令
表3-4 指令執行后的CC1和CC0
L MD4 //MD4中的浮點數裝入累加器1
L 2.345E+02 //浮點數常數裝入累加器1,MD4裝入累加器2
>R//比較累加器1和累加器2的值
=Q4.2//如果MD4>2.345E+02,則Q4.2為1
3.2.3 數據轉換指令
表3-5所示為數據轉換指令,其中3位BCD碼和7位BCD碼的格式如圖3-18所示。
表3-5 數據轉換指令
【實例】 雙整數轉換為BCD碼的例子。
A I0.2 //如果I0.2為1
L MD10 //將MD10中的雙整數裝入累加器1
DTB //將累加器1中的數據轉換為BCD碼,結果仍在累加器1中
圖3-18 BCD碼格式
a)3位BCD碼的格式 b)7位BCD碼的格式
JO OVER //運算結果超出允許范圍(OV=1)則跳轉到標號OVER處
T MD20 //將轉換結果傳送到MD20
A M4.0
R M4.0 //復位溢出標志
JU NEXT //無條件跳轉到標號NEXT處
OVER:AN M4.0
S M4.0 //置位溢出標志
NEXT:……
【實例】 將101英寸(in)轉換為以厘米(cm)為單位的整數,送到MW0中。
L 101 //將16位常數101(65H)裝入累加器1
ITD //轉換為32位雙整數
DTR //轉換為浮點數101.0
L 2.54 //浮點數常數2.54裝入累加器1,累加器1的內容裝入累加器2
*R //101.0乘以2.54,轉換為256.54厘米
RND //四舍五入轉換為整數257(101H)
T MW30
3.2.4 取反與求補指令
表3-6所示為取反與求補指令的STL表達方式。
表3-6 取反與求補指令
【實例】 求補應用例子。
L MD20 //將32位雙整數裝入累加器1
NEGD //求補
T MD30 //運算結果傳送到MD30
3.2.5 數學運算指令
表3-7為整數數學運算指令的STL表達式,表3-8為浮點數數學運算的STL表達式。圖3-19所示為數學運算的累加器變化。需要注意的是,語句表中“*I”指令的運算結果為32位整數,梯形圖中MUL_I指令的運算結果為16位整數。
表3-7 整數數學運算指令
表3-8 浮點數數學指令
【實例】 用浮點數對數指令和指數指令求5的立方。
計算公式:53=EXP(3*LN(5))=125
L L#5
DTR
LN
L 3.0
*R
EXP
RND
T MW40
圖3-19 數學運算的累加器變化
3.2.6 移位與循環指令
表3-9為移位指令,它對累加器1中的數操作,結果在累加器1中。需要注意的是:用指令中的參數<number>來指定移位位數,16位移位指令為0~15,32位移位指令為0~32。如果<number>等于0,移位指令被當作NOP(空操作)指令來處理;如果指令沒有參數<number>,移位位數放在累加器2的最低字節中(0~255),而如果移位位數等于0,移位指令被當作NOP(空操作)指令來處理。一旦有符號字的移位位數>16時,移位后被移位的數的各位全部變成了符號位。
表3-9 移位指令
【實例】 整數移位應用(結果見表3-10)。
L MW4 //將MW4的內容裝入累加器1的低字中
SSI 6 //累加器1低字中的有符號數右移6位,結果仍在累加器1的低字中
T MW8 //累加器1低字中的運算結果傳送到MW8中
3.2.7 字邏輯運算指令
表3-11為字邏輯運算指令的STL表達方式。表3-12給出了累加器1和累加器2進行字邏輯運算后的結果。
表3-10 整數右移6位前后的數據
表3-11 字邏輯運算指令的STL表達方式
表3-12 字邏輯運算的結果
【實例】 字或運算應用。
L QW10 //QW10的內容裝入累加器1的低字中
L W#16#000F //累加器1的內容裝入累加器2,W#16#000F裝入累加器1的低字中
OW //累加器1低字與W#16#000F逐位相或,結果在累加器1的低字中
T QW10 //累加器1低字中的運算結果傳送到QW10中
3.2.8 累加器指令
表3-13為累加器指令,也是在STL編程中應用最為廣泛的一個指令之一,其中圖3-20所示演示了入棧和出棧執行前后的變化。
【實例】 用語句表程序實現浮點數運算(DBD0+DBD4)/(DBD8-DBD12)。
L DBD0 //DBD0中的浮點數裝入累加器1
L DBD4 //累加器1的內容裝入累加器2,DBD4中的浮點數裝入累加器1
+R //累加器1,2中的浮點數相加,結果保存在累加器1中
L DBD8 //累加器1的內容裝入累加器2,DBD8中的浮點數裝入累加器1
ENT //累加器3的內容裝入累加器4,累加器2的中間結果裝入累加器3
L DBD12 //累加器1的內容裝入累加器2,DBD12中的浮點數裝入累加器1
-R/ /累加器2的內容減去累加器1的內容,結果保存在累加器1中
LEAVE //累加器3的內容裝入累加器2,累加器4的中間結果裝入累加器3
/R //累加器2的(DBD0+DBD4)除以累加器1的(DBD8-DBD12)
T DBD16 //累加器1中的運算結果傳送到DBD16
表3-13 累加器指令
圖3-20 入棧和出棧執行前后的變化
a)入棧指令執行前后 b)出棧指令執行前后
3.2.9 邏輯控制指令
表3-14所示為邏輯控制指令的STL表達方式,很多邏輯控制指令在梯形圖中不一定會有,這一點需要讀者注意。邏輯控制跳轉中,只能在同一邏輯塊內跳轉;同一個跳轉目的地址只能出現一次;跳轉或循環指令的操作數為地址標號,標號由最多4個字符組成,第一個字符必須是字母,其余的可以是字母或數字。
這里對LOOP特別說明如下:循環指令LOOP<jump label>用ACCU 1-L作循環計數器,每次執行LOOP指令時ACCU 1-L的值減1,若減1后ACCU 1-L非0,將跳轉到<jump label>指定的標號處。
表3-14 邏輯控制指令
【實例】 IW8與MW12的異或結果如果為0,將M4.0復位,非0則將M4.0置位。
L IW8 //IW8的內容裝入累加器1的低字
L MW12 //累加器1的內容裝入累加器2,MW12的內容裝入累加器1
XOW //累加器1,2低字的內容逐位異或
JN NOZE //如果累加器1的內容非0,則跳轉到標號NOZE處
R M4.0
JU NEXT
NOZE:AN M4.0
S M4.0
NEXT:NOP 0
【實例】 用循環指令求5!(5的階乘)。
L L#1 //32位整數常數裝入累加器1,置階乘的初值
T MD20 //累加器1的內容傳送到MD20,保存階乘的初值
L 5 //循環次數裝入累加器的低字中
BACK:T MW10 //累加器1低字的內容保存到循環計數器MW10
L MD20 //取階乘值
*D //MD20與MW10的內容相乘
T MD20 //乘積送MD20
L MW10 //循環計數器內容裝入累加器1
LOOP BACK //累加器1低字的內容減1,減1后非0,跳到標號BACK
……//循環結束后,恢復線性掃描
3.2.10 程序控制指令
程序控制指令見表3-15。
表3-15 程序控制指令
3.2.11 數據塊指令
數據塊指令見表3-16。
表3-16 數據塊指令
【實例】 數據塊指令應用。
OPN DB10 //打開數據塊DB10作為共享數據塊
L DBW35 //將打開的DB10中的數據字DBW35裝入累加器1的低字中
T MW12 //累加器1低字的內容裝入MW12
OPN DI20 //打開作為背景數據塊的數據塊DB20
L DIB35 //DB20.DIB35裝入累加器1的最低字節中
T DBB27 //累加器1最低字節傳送到DB10.DBB27