西門子S7 SCL語言學習手記
1、 SCL程式可以在CPU314及其以上的S7(包括400)中運作。
2、 SCL程式建立在”S7 Program”-”Sources”下面。
S7-Program
-Blocks(e.g. FB,OB)
-Sources(e.g.SCL source file)
-Symbols
3、 程式結構
FB: FUNCTION_BLOCK fb_name
END_FUNCTION_BLOCK
FC: FUNCTION fc_name:function type
END_FUNCTION
OB: ORGANIZATION_BLOCK ob_name
END_ORGANIZATION_BLOCK
DB: DATA_BLOCK db_name
END_DATA_BLOCK
UDT TYPE udt_name
END_TYPE
4、 屬性定義和程式注釋
例如:
FUNCTION_BLOCK FB10
//This is a block comment.
TITLE = ’Mean_Value’
VERSION : ’2.1’
KNOW_HOW_PROTECT
AUTHOR : AUT_1
5、 變量定義
Data Syntax FB FC OB DB UDT
Constants CONST
declaration list
END_CONST X X X
Labels LABEL
declaration list
END_LABEL X X X
Temporary Variables VAR_TEMP declaration list
END_VAR X X X
X X X
Static variables VAR
declaration list
END_VAR
X X X X X
Input parameters VAR_INPUT
declaration list
END_VAR
X X
Output parameters VAR_OUTPUT
declaration list
END_VAR
X X
In/out parameters VAR_IN_OUT
declaration list
END_VAR
X X
6、FC結構
FUNCTION FC11: REAL//如果不需要傳回值,用VOID關鍵字
VAR_INPUT
x1: REAL ;
x2: REAL ;
x3: REAL ;
x4: REAL ;
END_VAR
VAR_OUTPUT
Q2: REAL ;
END_VAR
BEGIN
// Return value from function
FC11:= SQRT( (x2 - x1)**2 + (x4 - x3) **2 ) ;
Q2:= x1 ;
END_FUNCTION
7、自己寫了一個簡單的程式
OB1:
FC1用SCL編寫:
FUNCTION fc1:INT
VAR_INPUT
a:INT;
END_VAR
begin
fc1:=a+10;
end_FUNCTION
運作後:每次m0.0從0變1,就調用FC1一次,mw18裡面的資料加10。
問題:SCL如何調用其他SCL以及用LAD等編寫的程式?
寫一個有循環、判斷等基本語句組成的程式。
參數使用問題?(直接使用實際位址?參數傳遞問題)
如何線上調試SCL程式(debug)
1、 在SCL裡面調用LAD或者STL寫的塊
先用STL或者LAD建立一個FC2:
定義一個輸入參數:in1(int型);一個輸出參數:out1(int型)
語句表如下:
L #in1
L #in1
+I
T #out1
NOP 0
在下面寫的SCL裡面調用FC2:
FUNCTION fc1:INT
VAR_INPUT
a:INT;
END_VAR
VAR_TEMP
b:INT;
end_var
begin
//fc1:=a+10;
fc2(in1:=a,out1:=b);
fc1:=b;
end_FUNCTION
2、在SCL裡面調用其他SCL寫的塊
FUNCTION fc1:INT
VAR_INPUT
a:INT;
END_VAR
VAR_TEMP
b:INT;
end_var
BEGIN
fc3(in1:=a,out1:=b);//調用fc3
fc1:=b;
end_FUNCTION
FUNCTION fc3:void//無傳回值
VAR_INPUT
in1:INT;
END_VAR
VAR_OUTPUT
out1:INT;
end_var
begin
out1:=in1+10;
end_FUNCTION
3、一個帶有循環、判斷等基本語句的程式
FUNCTION fc4:VOID
VAR_INPUT
in1:BOOL;
in2:INT;
END_VAR
VAR_OUTPUT
out1:BOOL;
out3:BOOL;
out2:INT;
END_VAR
VAR//定義一個靜态變量,用來存儲塊調用之間的資料
temp1:BOOL;
END_VAR
VAR_TEMP
temp2:INT;
END_VAR
BEGIN
IF in1=false AND temp1=true THEN//檢驗下跳沿
out1:=true;
ELSE
out1:=false;
END_IF;
IF in1=true AND temp1=false THEN//檢驗上跳沿
out3:=true;
ELSE
out3:=false;
END_IF;
temp1:=in1;
FOR temp2:=1 TO 10 BY 2 DO//省略了關鍵字by,就預設加1
out2:=in2+out2;
END_FOR;
END_FUNCTION
4、SCL中直接使用絕對位址
FUNCTION fc1:VOID
BEGIN
in1:=in1+10;//in1在符号表裡面已經定義為int型,存儲區為mw0
IF m0.0=false then//這裡直接引用實際位址
m0.0:=true;
ELSE
m0.0:=false;
END_IF;
end_FUNCTION
5、如何線上調試SCL程式
注:僅400可以設定斷點(breakpoint)以及單步執行
學習基本完畢!已經了解了編寫SCL程式的基本方法!
在資料轉換方面,SCL和LAD有一些差別,SCL的資料轉換有兩種類型:
? Implicit資料轉換,即如果資料類型不比對,Scl會自動進行預設的資料轉換
Classes Conversion Order
Any_bit Bool>byte>Word>Dword
Any_num INT>DINT>Real
例如兩個數相加,一個是int型,一個是real型,則在編譯的時候int型資料會被系統轉換為real型再進行運算,結果隻能存放在real型中。
? Explicit 資料轉換
由使用者程式用相應的功能塊進行資料轉換。
而LAD沒有Implicit資料轉換,參與運算的兩個數必須類型一緻。
如果給變量指派,比如:mw0:=a1;(這裡a1是定義好的int型的臨時變量),則編譯會提示出錯“錯誤的資料類型“,這是因為編譯器不認為mw0是一個有效的int型變量,除非在符号表裡面定義了一個符号比如f11為mw0,int型,則f11:=a1;可以編譯通過;
另外DB塊的使用與LAD/STL也有所不同,在LAD或者STL裡面如果要按照db裡面定義的符号名來調用db裡面的變量,則必須事先給db定義一個名字,然後寫成"DB1_IN".P1(db1_in是事先定義好的db的符号名,p1則是db1中的dbw0存儲區)。而在scl中,則可以寫成:db1.p1(事先無效定義db的符号名)或者db1_in.p1都可以
DATE_AND_TIME類型的資料不能直接指派(編譯不會報錯),可以按照資料結構分解指派:
DATE_AND_TIME是按照下面的結構:
1BYTE YEAR
1BYTE MONTH
1BYTE DAY
1BYTE HOUR
1BYTE MINUTE
1BYTE SECOND
1BYTE MSD(MOST SIGNIFICANT DECADE) OF MS
1BYTE MSD(LEAST SIGNIFICANT DECADE) OF MS
1BYTE WEEKDAY
OB塊的temp變量,Help裡面說:“To execute, each OB alwaysrequires 20 bytes of local data for the operating system. You mustdeclare an array for this with an identifier.”
實際上為了程式設計友善,可以手動定義變量而不用系統模闆定義的20byte的array(數組)。因為有些變量不是byte類型的。手動定義變量必須主意必須把所有變量定義完成,否則會因為變量定義的不夠造成temp資料區不夠大,就不能傳回任何結果!!!
關于FC和FB的差別
對于需要在運作過程中需要“記住”的中間變量,可采用靜态變量。但是由于FC的每個靜态變量是固定的位址存儲,那麼FC每次被調用都是讀寫同一個靜态變量,如果FC在一次循環中被多次調用,則靜态變量在每次循環中被多次讀寫;而FB的靜态變量則是由指定的DB存儲是以每個被調用的FB都有其獨立的存儲空間,則如果FB在一次循環中被多次調用,其靜态變量也隻是被讀寫一次。