西門子300 編程多個問題解答之七(131-150)
131:S7-300/400 PLC支持哪些尋址方式?
1)直接尋址
1.直接地址:例如I0.0,Q1.7,PIW256,PQW512,MD20,T15,C16,DB1.DBB10,L10.0等
2.符號尋址:例如qq,ww.aa等
2)間接尋址
1.存儲器間接尋址:16位指針,例如OPN DB[MW2] 32位指針,例如A I[MD0]
2.寄存器間接尋址:32位指針,例如A I[AR1,P#0.0],A [AR1,P#0.0]
132:如何使用指針?
指針用來指向一個地址。使用這種尋址方式的優(yōu)點在于可以在程序運行過程中實現(xiàn)變址。指針用于存儲器間接尋址
程序中用于存儲器間接尋址的語句包含一個指令、一個地址標識符、以及一個偏移量(偏移量必須在方括號內(nèi)給出)。
下面給出一個雙字格式的指針的例子:
L P#8.7 把指針值裝載到累加器1
T I[MD2] 把指針值傳送到MD2
A I[MD2] 查詢I8.7的信號狀態(tài)
= Q[MD2] 給輸出位Q8.7賦值
存儲區(qū)域內(nèi)部尋址及交叉尋址:程序中采用這些尋址方式的語句包含一個指令以及下列內(nèi)容:地址標識符、地址寄存器標識符、偏移量。地址
寄存器(AR1、AR2)及偏移量必須寫在方括號內(nèi)。
存儲區(qū)域內(nèi)部尋址例程:指針不包含指示存儲區(qū)域的信息:
L P#8.7 把指針值裝載到累加器1
LAR1 把指針從累加器1裝載到AR1
A I[AR1,P#0.0] 查詢I8.7的信號狀態(tài)
= Q[AR1,P#1.1] 給輸出位Q10.0賦值
偏移量0.0不起作用。輸出Q10.0 等于8.7 (AR1) 加偏移量1.1。結(jié)果是10.0 ,而不是9.8。
存儲區(qū)域交叉尋址例程:在存儲區(qū)域交叉尋址中,指針中包含指示存儲區(qū)域的信息(例子中為 I 和 Q)。
L P#I8.7 把指針值及存儲區(qū)域標識裝載到累加器1
LAR1 把存儲區(qū)域I 和地址8.7裝載到AR1
L P#Q8.7 把指針值和地址標識符裝載到累加器1
LAR2 把存儲區(qū)域Q和地址8.7裝載到AR2
A [AR1,P#0.0] 查詢輸入位I8.7的信號狀態(tài)
= [AR2,P#1.1] 給輸出位Q10.0賦值
偏移量0.0不起作用。輸出Q10.0 等于8.7 (AR2) 加偏移量1.1。結(jié)果是10.0 ,而不是9.8,
133.如何用一個變量作索引實現(xiàn)在一個域中讀一個元素或?qū)懸粋€元素?
一個域(數(shù)據(jù)類型為ARRAY)是幾個相同數(shù)據(jù)元素的連接。在源代碼中一個單空間域的聲明執(zhí)行如下:
My_Array: ARRAY[4..11] OF INT;
它標識了一個數(shù)據(jù)類型為“INTEGER”的8(=11-4+1)元素單空間域。
為了訪問域中的一個元素,輸入域名并在方括號中輸入希望訪問的元素的號碼,比如:My_Array[6]。
在S7-SCL (結(jié)構(gòu)化控制語言- 符合IEC 1131-3 的結(jié)構(gòu)化文本)可以使用變量做索引:
i:INT:=46
My_Array[i]:=0
在FBD/LAD/STL中,索引必須是個常量,因此限制了可使用的域的范圍。
134:怎樣訪問復(fù)合數(shù)據(jù)類型數(shù)組單元的變量?
復(fù)合數(shù)據(jù)類型數(shù)組單元中的變量只有通過單獨的函數(shù)才能訪問。作為傳送參數(shù)這個函數(shù)擁有期望的數(shù)組數(shù)量并以數(shù)組[0]作為起始地址。對此函數(shù)的要求是數(shù)組置于一個數(shù)據(jù)塊中并且數(shù)組[0]不被當前數(shù)據(jù)使用。這就決定了從參數(shù)傳送來的地址并將指定的數(shù)組拷貝到作為處理區(qū)的數(shù)組[0]。接下來可對數(shù)組進行符號處理。然后它被拷貝回原始的數(shù)組號。
首先用這些參數(shù)定義并計算數(shù)組[0]的地址和要處理的數(shù)組數(shù)量。將這些值保存在函數(shù)的臨時變量內(nèi)。
L P##Field_Start // 輸入地址域[0]
LAR1
L D [AR1,P#0.0] // 把這些地址保存在類型為ANY的臨時變量中
T LD 0 // temp 'firststruc' = LD 0-9
T LD 10 // temp 'sourcestruc' = LD 10-19
L D [AR1,P#4.0]
T LD 4
T LD 14
L W [AR1,P#8.0]
T LW 8
T LW 18
L LD 16 // 定義期望數(shù)組的地址
LAR1
L #Indices
L LW 12
*I
SLD 3
+AR1
TAR1 LD 16
然后用SFC20 (BLKMOV)將要處理的數(shù)組拷貝到數(shù)組[0]。就可以根據(jù)應(yīng)用需求,對索引數(shù)組通過符號訪問。然后用SFC20 (BLKMOV)將數(shù)組[0]拷貝回原始區(qū)域。
135:能否在STEP 7中使用間接尋址編寫循環(huán)程序?
可以,間接尋址允許尋址地址在程序運行期間才可以確定的操作數(shù)。這意味著,程序的一部分可以重復(fù)執(zhí)行。在每個運行周期內(nèi),循環(huán)編程為所使用的操作數(shù)分配不同的地址。
136:ANY指針類型的參數(shù)如何被傳送出塊邊界?
下面的例子解釋了系統(tǒng)功能塊SFC50“RD_LGADR”(讀模塊邏輯地址)內(nèi)參數(shù)的確定。例如,為功能塊FB1編程可分為下面幾個步驟:
?聲明一個IN變量“test”和一個TEMP變量“test2”,類型都為ANY(圖1)。
?將SFC50的參數(shù)“PEADDR”傳送到變量“test2”。
?通過為ANY指針“test”賦值,將數(shù)據(jù)傳送到臨時變量“test2”中。
語句L P##test首先將地址裝載到Accu1,然后通過LAR1語句裝載到地址寄存器AR1中(可能是LAR1 P##test的簡化格式)。通過寄存器間接尋址將ANY指針(10 字節(jié)長)中的地址信息讀出:
代碼注釋
0 L W[AR1,P#0.0] 讀出當前Accu1中參數(shù)數(shù)據(jù)類型的代碼。
2 L W[AR1,P#2.0] 讀出Accu1中的重復(fù)因數(shù)。重復(fù)因數(shù)表明通過參數(shù)類型ANY傳遞的數(shù)據(jù)類型的大小。
4 L W[AR1,P#4.0] 讀數(shù)據(jù)塊的號或者從ANY指針中讀出“0”(這個對應(yīng)于ANY指針的第 4 到第 5 字節(jié))。
6 L D[AR1, P#6.0] 將區(qū)域指針讀入Accu1。
每次讀地址寄存器AR1之后,數(shù)據(jù)被保存或者緩存(如T LW 0)在臨時變量“test2”中(ANY指針)。按照Network 1中的語句順序,傳送到功能塊FB1 的ANY指針被復(fù)制到臨時變量“test2”中。
137:怎樣通過交叉區(qū)域寄存器間接尋址訪問功能塊的本地數(shù)據(jù)或者功能?
這里必須預(yù)先定義本地數(shù)據(jù)。您可以使用下列語句訪問FB或FC的本地數(shù)據(jù):
對于存儲器間接指針尋址,本地變量必須聲明為臨時變量(temp):
L P##Lokalvariable
LAR1
L W[AR1,P#X.x]
此處不能使用變量類型“Input”、“Output”和“In_Out”,將被語法檢查視為非法。
138:怎樣編程間接訪問一個ARRAY類型變量的元素?
一個位、字節(jié)或者字符域的尺寸是按照字節(jié)限制排列的——在所有其它情況下是按照字對齊的。表T6-1中給出了一個域的存儲示例。操作系統(tǒng)計算域中單個元素末端位置的位地址。域被分配到從下一個字地址(或字節(jié)地址)。下一個數(shù)據(jù)類型從下一個整字開始(或者整字節(jié)).
聲明部分:
在聲明部分,必須定義一個與將被間接尋址的ARRAY有著同一結(jié)構(gòu)的ARRAY。不一定非要將ARRAY聲明為IN-OUT變量;也可以聲明為TEMP、IN或OUT變量。
網(wǎng)絡(luò):
域?qū)挾?OFFSET)在網(wǎng)絡(luò)中定義。ARRAY中的單個元素的最小常規(guī)數(shù)據(jù)寬度是一個字節(jié);即使在兩個變量之間定義一個BOOL。有必要確定相關(guān)的域的寬度和確定下一個期望域的起始地址。可使用下面的算法:
地址(指數(shù)):b = 元素長度*(指數(shù) - 1)
創(chuàng)建具有不同數(shù)據(jù)類型的結(jié)構(gòu)時,必須注意,在特定的環(huán)境下可能會自動插入填充字節(jié)。
保存ARRAY數(shù)據(jù)類型:
示例:ARRAY [1..2,1..3] OF 整數(shù)將生成下列域:
多維域是按照順序保存的。在本例中整數(shù) [1,1]后面是整數(shù) [1,2],整數(shù) [1,3]后面是整數(shù)[2,1]。
139:STEP 7 以哪種格式存儲POINTER參數(shù)類型?
STEP 7以 6 個字節(jié)保存POINTER參數(shù)。表4-1顯示了用于保存POINTER參數(shù)類型的內(nèi)存區(qū)域以及每個字節(jié)中保存的數(shù)據(jù)。i POINTER參數(shù)類型保存了下列信息:
DB號(如果DB中沒有保存任何數(shù)據(jù)時為0)。
CPU中的內(nèi)存區(qū)域(表格中列出了不同內(nèi)存區(qū)域的十六進制代碼)。
數(shù)據(jù)的地址(按照Byte.Bit格式)。
如果將形式參數(shù)聲明為POINTER參數(shù)類型,則只需要指定內(nèi)存區(qū)域和地址。STEP 7自動將輸入項目的格式轉(zhuǎn)換為指針格式。
140:如何間接訪問I/O地址區(qū)域?
下面演示了一個間接訪問PA區(qū)域的例子。您具有對輸出模塊只寫訪問和對輸入模塊只讀訪問的權(quán)利
FUNCTION_BLOCK FB 2
TITLE =
VERSION : 0.1
VAR_INPUT
TargetAddress : DWORD := DW#16#FF; //Target address by PA address range
OutputValue : DWORD ; //Output value
P_Typ : BOOL ; //1=PE range, 0=PA range
END_VAR
VAR_OUTPUT
InputValue : DWORD ; //Input value
END_VAR
VAR_TEMP
TargetTmp : DWORD ;
END_VAR
BEGIN
NETWORK
TITLE =
U #P_Typ;
SPB PEA;
L #TargetAddress;
T #TargetTmp; //Load target address in the tempor鋜e store
SLD 3; //Calculate the formate of pointer Byte.Bit
T #TargetTmp; //Initialisation of temp variable with target address in L-Stack
L #OutputValue; //Load output value
T PAD [#TargetTmp]; //Transfere output value to target address
SPA End;
PEA: L #TargetAddress;
T #TargetTmp; //Load target address in the tempor鋜e store
SLD 3; //Calculate the formate of pointer Byte.Bit
T #TargetTmp; //Initialisation of temp variable with target address in L-Stack
L PED [#TargetTmp]; //Load output value
T #OutputValue; //Transfere output value to target address
End: CLR ;
END_FUNCTION_BLOCK
141:應(yīng)用軟件冗余當一個長度錯誤出現(xiàn)導(dǎo)致CPU處于STOP模式應(yīng)該作些什么?
當在OB100中設(shè)置軟件冗余功能塊FC100時,必須注意下列情況:參數(shù)IEC_NO 的背景數(shù)據(jù)塊必須至少有兩個字的長度,同樣應(yīng)用于冗余用戶程序的參數(shù)DB_NO的數(shù)據(jù)塊也必須時這樣。
142:在S7程序中,有許多FC、FB塊, 我怎樣對其中的一些塊進行保護, 而其它的塊可以是開放的呢?
1) Step7中, 可以先任意打開一塊如OB1, 在"file"中選擇"Generate Source"或快捷方式"Ctrl+T",彈出一個畫面,填寫"object name"如"tt",然后按OK確認,就會再彈出另一個畫面,左邊是你的程序中所有的塊,如果你需要保護哪些塊, 就把這些塊移到右邊,如FB1、FB2等等, 然后退出所有的程序塊,再進入SIMATIC Manager中。
2) 在S7 Program Sources找到文件tt,雙擊tt打開,在第四行中加入"Know_How_Protect", 然后編譯, 無錯后存盤。這樣FB1、FB2就被保護住,如想去掉保護,在tt中去掉"Know_How_Protect"編譯存盤即可。
注意: 千萬不要丟失或刪除源文件(如tt), 否則程序被保護, 用戶可以另存到其它目錄中,或Export Source到硬盤中,再刪除源文件,這樣別人只能看到未保護的塊。
143:SFB41,SFB42,SFB43和FB41,FB42,FB43的區(qū)別?
SFB41(CONT_C),SFB42(CONT_S),SFB43(PULSEGEN)塊和FB41(CONT_C),FB42(CONT_S),FB43(PULSEGEN)的區(qū)別:SFB41,42,43與FB41,42,43的參數(shù)設(shè)置是一樣的。SFB41,42,43只能用于CPU314IFM;FB41,42,43可用于CPU313以上的CPU(除CPU314IFM),因為SFB41,42,43集成于CPU314IFM中,而在普通CPU中沒有這些塊。
144:如何在多例兼容功能塊中找到變量地址?
在多例兼容功能塊中,為塊參數(shù)和靜態(tài)本地數(shù)據(jù)加載與地址寄存器AR2有關(guān)的絕對地址。如果要在情景數(shù)據(jù)塊中找到變量的絕對地址,則必須把域內(nèi)指針(只是AR2的地址)加載到變量地址。
樣例:
TAR2 //將地址寄存器加載到累加器AC1(偏移量)
UD DW#16#00FF_FFFF // 關(guān)閉區(qū)域ID
L P##variable //加載變量地址
+D // 增加偏移量和變量地址
LAR1 // 保存地址寄存器AR1中的結(jié)果
這樣可在AR1中獲得絕對地址以進行進一步處理。
當功能塊作為本地實例調(diào)用時,總要使用該方法。比如,在一個功能塊中創(chuàng)建可做為類型“FB”的靜態(tài)變量的功能塊。這樣所調(diào)用的情景數(shù)據(jù)塊的數(shù)據(jù)偏移量就存儲到情景數(shù)據(jù)塊中。單個實例的偏移量在AR2中。如果不調(diào)用作為本地實例的功能塊,則可以結(jié)束計算。值‘0’就在地址寄存器中。
注意事項:如果改變程序中的地址寄存器AR2,那么也改變了變量的偏移量地址。因此就不能保證再對變量進行正確訪問。在這種情況下,必須預(yù)先保存AR2,并在對程序動作完之后將其復(fù)位為初始狀態(tài)。
樣例:
TAR2 // 在累加器中加載偏移量地址
T #save // 比如,靜態(tài)本地數(shù)據(jù)域 0中的變量
L DID 0 // 地址絕對是由DI加載的beds<Y
L AR2 // 核對
145:怎樣才能訪問上一函數(shù)的本地數(shù)據(jù)?
如要訪問以前的本地數(shù)據(jù)(“V-e > L”數(shù)據(jù)),可以傳送一自創(chuàng)建ANY指針或絕對地址到被調(diào)用的FC。如果傳送的是自創(chuàng)建ANY指針,區(qū)域指針會指向其本地數(shù)據(jù),而這是無意義的。> 因此“V”區(qū)域碼必須置于ANY指針中。此碼必須準確傳送。當指定絕對地址時可由編譯器完成此工作。
常規(guī)程序結(jié)構(gòu):
以ANY指針或絕對(地址)方式傳送:
LAR1 P##target //本地定義的ANY變量初始地址
L W#16#87 //為“V”區(qū)域載入碼
T LB[AR1,P#6.0] //傳送到ANY變量
CALL FCxy
source1: = #target //傳送自創(chuàng)建的ANY指針
source2: = P#L 0.0 BYTE 8 //傳送完全L數(shù)據(jù)區(qū)
絕對尋址與通過ANY指針尋址的區(qū)別:
下圖顯示了絕對尋址與通過自創(chuàng)建ANY指針尋址間的區(qū)別。在這種情況下“87”碼不傳送,因此ANY指針指向其本地區(qū)域。
146:怎樣在DB內(nèi)進行間接尋址?
請參照:
在DB內(nèi)進行間接尋址例子
147:下面是一個在STEP7軟件中實現(xiàn)簡單指針尋址的例子程序,您可以參考它的結(jié)構(gòu)實現(xiàn)您的指針尋址功能?
siemens指針尋址例子_cpu315
148:絕對地址和符號尋址的定義和區(qū)別是什么?
在STEP 7程序中要用到I/O信號、位寄存器、計數(shù)器、定時器、數(shù)據(jù)塊及功能塊。在程序中可以采用直接地址,或者更便于讀程序的符號尋址,例如Motor_A_On,或采用你的公司或行業(yè)常用的代碼。這樣在你的用戶程序中就可以通過符號來尋址。
絕對地址:絕對地址由地址標識符和存儲器的位置組成,例如Q1.0,I1.1,M2.0, FB21等。
符號地址:如果為絕對地址指定一個符號名,程序會更便于閱讀和查錯。
STEP 7 可以自動將符號名翻譯成所需的絕對地址。如果要用符號名存取ARRAY、STRUCT、數(shù)據(jù)塊、局部數(shù)據(jù)、邏輯塊、以及用戶自定義數(shù)據(jù)類型,必須首先為絕對地址指定一個符號名。
例如,可以為Q0.0 指定一個符號名MOTOR_ON,然后在程序中將MOTOR_ON作為一個地址使用。使用符號地址更容易將您的過程控制項目中的元件與程序中的元件相對應(yīng)。
注意:在符號名中不允許使用兩個連續(xù)的下劃線,例如MOTOR__ON。
編程支持:LAD、FBD、STL中地址、參數(shù)、塊名可用絕對地址或符號表示。
用菜單命令View > Display > Symbolic Representation,可以切換絕對地址和符號地址
為了使用符號地址編程更加容易,可以同時顯示絕對地址和符號名。使用菜單命令 View > Display > Symbol Information來激活。這就意味著STL語句的注釋包含了更多的信息。不能在該界面下進行修改,只能在符號表(symbol table)或變量聲明表(variable declaration table)中進行修改。
149:S7-300/400系統(tǒng)存儲區(qū)域共有多少種?
S7 CPU的系統(tǒng)存儲區(qū)域分為下表中列出的地址區(qū)域。在程序中可以根據(jù)相應(yīng)的地址直接讀取數(shù)據(jù)。
150:如何把一個DATE_AND_TIME變量轉(zhuǎn)換為STRING變量?
為了以日期/時間字符串(STRING)形式顯示DATE_AND_TIME變量,必須DATE_AND_TIME 變量的專用字節(jié)轉(zhuǎn)換為相應(yīng)的CHAR字符。
讀取DATE_AND_TIME 變量的專用字節(jié)并從這兩位數(shù)所在ASCII碼中創(chuàng)建專用位。將確定了的CHAR字符存儲在字符串的期望位置。
示例:
L 字節(jié)年
SLD 12
SRW 4
SRD 8
L W#16#3030
+ I
T 數(shù)字字符年
也可以用相反順序?qū)⒁粋€STRING格式的日期/時間字符串轉(zhuǎn)換為一個DATE_AND_TIME變量
文章版權(quán)歸西部工控xbgk所有,未經(jīng)許可不得轉(zhuǎn)載。