結(jié)構(gòu)化文本ST編程,西門子PLC編程語言中叫SCL ,其它任何PLC控制器編程語言還是叫結(jié)構(gòu)化編程ST。
西門子SCL語言
第一章IF:條件執(zhí)行
IF 分支
IF <條件> THEN <指令>
END_IF;
如果滿足該條件,則將執(zhí)行 THEN 后編寫的指令。 如果不滿足該條件,則程序?qū)?END_IF 后的下一條指令開始繼續(xù)執(zhí)行。
IF 和 ELSE 分支
IF <條件> THEN <指令 1>
ELSE <指令 0>;
END_IF;
如果滿足該條件,則將執(zhí)行 THEN 后編寫的指令。 如果不滿足該條件,則將執(zhí)行 ELSE 后編寫的指令。 程序?qū)?END_IF 后的下一條指令開始繼續(xù)執(zhí)行。
IF、ELSIF 和 ELSE 分支
IF <條件 1> THEN <指令 1>
ELSIF <條件 2> THEN <指令 2>
ELSE <指令 0>;
END_IF;
如果滿足第一個條件(<條件 1>),則將執(zhí)行 THEN 后的指令(<指令1>)。 執(zhí)行這些指令后,程序?qū)?END_IF 后繼續(xù)執(zhí)行。
如果不滿足第一個條件,則將檢查第二個條件(<條件 2>)。如果滿足第二個條件(<條件 2>),則將執(zhí)行 THEN 后的指令(<指令2>)。 執(zhí)行這些指令后,程序?qū)?END_IF 后繼續(xù)執(zhí)行。
如果不滿足任何條件,則先執(zhí)行 ELSE 后的指令(<指令 0>),再執(zhí)行 END_IF 后的程序部分。
在 IF 指令內(nèi)可以嵌套任意多個 ELSIF 和 THEN 組合。 可以選擇對 ELSE 分支進(jìn)行編程。
IF "Tag_1" = 1
THEN "Tag_Value" := 10;
ELSIF "Tag_2" = 1
THEN "Tag_Value" := 20;
ELSIF "Tag_3" = 1
THEN "Tag_Value" := 30;
ELSE "Tag_Value" := 0;
END_IF;
IF 案例如下:
FUNCTION_BLOCK "IF"
TITLE = 'IF Statement'
//IF ... THEN ... ELSE ... END_IF
VAR_INPUT
Start : BOOL;
Manual : BOOL;
ActVal : INT;
END_VAR
VAR
Manual_FM : BOOL;
over : BOOL;
under : BOOL;
equal_to : BOOL;
Setpoint_man : INT := 1000;
Setpoint : INT;
Deviation : INT;
y_index : INT := 12;
Total : INT;
END_VAR
VAR_TEMP i : INT; END_VAR
BEGIN
//Simple IF branch
IF Start THEN Setpoint := 1200; END_IF;
IF Manual THEN
Setpoint := Setpoint_man;
Q4.0 := TRUE;
END_IF;
//Branch with THEN...ELSE
IF ActVal > Setpoint
THEN Deviation := ActVal - Setpoint;
ELSE Deviation := Setpoint - ActVal;
END_IF;
//Branch with ELSIF
IF ActVal > Setpoint
THEN over := TRUE;
under := FALSE;
equal_to := FALSE;
ELSIF ActVal < Setpoint
THEN under := TRUE;
over := FALSE;
equal_to := FALSE;
ELSE equal_to := TRUE;
over := FALSE;
under := FALSE;
END_IF;
//Edge evalaution (rising edge)
IF Manual AND NOT Manual_FM
THEN (*rising edge*);
END_IF;
Manual_FM := Manual; //Correct edge memory bit
//Counting bits set to "1"
Total := 0;
FOR i:=1 TO 32 DO
IF M[y_index,i] = TRUE
THEN Total := Total + 1;
END_IF;
END_FOR;
END_FUNCTION_BLOCK
第二章CASE:創(chuàng)建多路分支
說明:使用“創(chuàng)建多路分支”指令,可以根據(jù)數(shù)字表達(dá)式的值執(zhí)行多個指令序列中的一個。
表達(dá)式的值必須為整數(shù)。執(zhí)行該指令時,會將表達(dá)式的值與多個常數(shù)的值進(jìn)行比較。如果表達(dá)式的值等于某個常數(shù)的值,則將執(zhí)行緊跟在該常數(shù)后編寫的指令。常數(shù)可以為以下值:
· 整數(shù)(例如,5)
· 整數(shù)范圍(例如,15 到 20)
· 由整數(shù)和范圍組成的枚舉(例如,10、11、15 到 20)
CASE <表達(dá)式> OF
<常量 1>: <指令 1>
<常量 2>: <指令 2>
<常量 X>: <指令 X>; // X>= 3
ELSE <指令 0>;
END_CASE;
例子
CASE #a OF
0 :
"Tag_1":= 1;
1,3,5 :
"Tag_2":= 1;
6...10 :
"Tag_3":= 1;
16,17,20...25 :
"Tag_4":= 1;
ELSE
"Tag_5":= 1;
END_CASE;
CASE OF 案例小程序:
FUNCTION_BLOCK "CASE"
TITLE = 'CASE Statements'
VAR
Expression1 : INT;
Expression2 : INT;
Expression3 : INT;
Day_of_the_week: STRING[12];
Dat : DATE;
ID : INT;
Error_number : INT;
END_VAR
VAR_TEMP
Return_jump : INT;
END_VAR
LABEL
Subroutine; M_1; M_2; M_3; End;
END_LABEL
BEGIN
//CASE with simple waiting list
CASE Expression1 OF
1 : Q4.1 := TRUE;
2 : Q4.2 := TRUE;
3 : Q4.3 := TRUE;
END_CASE;
//CASE with value areas
CASE Expression2 OF
1,2 : Q4.4 := TRUE;
2,3 : Q4.5 := TRUE;
ELSE : QB4 := 0;
END_CASE;
//CASE with gaps in the value areas
CASE Expression3 OF
1..4 : Q5.1 := TRUE;
7..9 : Q5.2 := TRUE;
12..16 : Q5.3 := TRUE;
ELSE : QB5 := 0;
END_CASE;
//Determining the day of the week from the DATE format
CASE DINT_TO_INT(DATE_TO_DINT(Dat) MOD 7)+1 OF
1 : Day_of_the_week := 'Monday';
2 : Day_of_the_week := 'Tuesday';
3 : Day_of_the_week := 'Wednesday';
4 : Day_of_the_week := 'Thursday';
5 : Day_of_the_week := 'Friday';
6 : Day_of_the_week := 'Saturday';
7 : Day_of_the_week := 'Sunday';
END_CASE;
//Assigning an error number
CASE ID OF
0 : Error_number := 0;
1,3,5 : Error_number := ID + 128;
6..10 : Error_number := ID;
ELSE : Error_number := 16#7F;
END_CASE;
//"Subroutines"
IF I1.0 THEN Return_jump := 1; GOTO subroutine; END_IF;
M_1: (*Return jump from subroutine*);
//...
IF I1.1 THEN Return_jump := 2; GOTO subroutine; END_IF;
M_2: (*Return jump from subroutine*);
//...
IF I1.2 THEN Return_jump := 3; GOTO subroutine; END_IF;
M_3: (*Return jump from subroutine*);
//...
GOTO End; //Jump over subroutine
Subroutine: ; //Jump to subroutine
//...Statements in the subroutine
//Selection for the return jump
CASE return_jump OF
1 : GOTO M_1;
2 : GOTO M_2;
3 : GOTO M_3;
END_CASE;
//*********************************************************
End: ;
END_FUNCTION_BLOCK
第三章FOR:在計數(shù)循環(huán)中執(zhí)行
說明
使用“在計數(shù)循環(huán)中執(zhí)行”指令,重復(fù)執(zhí)行程序循環(huán),直至運行變量不在指定的取值范圍內(nèi)。
也可以嵌套程序循環(huán)。 在程序循環(huán)內(nèi),可以編寫包含其它運行變量的其它程序循環(huán)。
通過指令“復(fù)查循環(huán)條件”(CONTINUE),可以終止當(dāng)前連續(xù)運行的程序循環(huán)。通過指令“立即退出循環(huán)”(EXIT) 終止整個循環(huán)的執(zhí)行。
FOR i := 2 TO 8 BY 2
DO "a_array
:="Tag_Value"*"b_array";
END_FOR;
FOR 指令案例
FUNCTION_BLOCK "FOR"
TITLE = 'FOR Statement'
//FOR ... TO ... BY ... DO ... END_FOR
//CONTINUE ... EXIT
NAME : C28FOR
FAMILY : SCL_Book
AUTHOR : Berger
VERSION : '1.0'
VAR
index1 : INT := 4;
index2 : INT := 6;
index3 : INT := 8;
END_VAR
VAR_TEMP
Runtime_variable : INT;
i, k : INT;
END_VAR
BEGIN
//Simple FOR loop
FOR Runtime_variable := 0 TO 7 DO
M[index1,Runtime_variable] := TRUE;
END_FOR;
FOR Runtime_variable := 0 TO 15 BY 2 DO
M[index2 + Runtime_variable MOD 8, Runtime_variable] := TRUE;
END_FOR;
MD[index1] := 0;
MD[index2] := 0;
(* Set memory bits *)
FOR i := 2 TO 23 DO
M[i DIV 8,i MOD 8] := TRUE;
END_FOR;
MD[index2] := MD[index1];
//Nested FOR loops
(* Reset memory bits *)
FOR i := 0 TO 2 DO
FOR k := 0 TO 7 DO
IF (k < 2 AND i = 0) THEN CONTINUE; END_IF;
IF (i = 2 AND k > 5) THEN EXIT; END_IF;
M[i,K] := FALSE;
END_FOR;
END_FOR;
MW[index3] := INT_TO_WORD(i);
MW[index3 + 2] := INT_TO_WORD(k);
//FOR loop with step width <> 1
FOR i:=128 TO 142 BY 2 DO
MW := PIW;
END_FOR;
//Abort FOR loops
FOR Runtime_variable := 0 TO 15 DO
M[index2,Runtime_variable] := TRUE;
IF Runtime_variable = 7 THEN CONTINUE;
ELSIF Runtime_variable = 8 THEN CONTINUE;
END_IF;
IF Runtime_variable = 10 THEN EXIT; END_IF;
M[index2 + 1,Runtime_variable] := TRUE;
END_FOR;
MD[index2] := 0;
END_FUNCTION_BLOCK
第四章WHILE:滿足條件時執(zhí)行
說明
使用“滿足條件時執(zhí)行”指令可以重復(fù)執(zhí)行程序循環(huán),直至不滿足執(zhí)行條件為止。該條件是結(jié)果為布爾值(TRUE 或 FALSE)的表達(dá)式。 可以將邏輯表達(dá)式或比較表達(dá)式作為條件。
執(zhí)行該指令時,將對指定的表達(dá)式進(jìn)行運算。 如果表達(dá)式的值為 TRUE,則表示滿足該條件;如果其值為 FALSE,則表示不滿足該條件。
也可以嵌套程序循環(huán)。 在程序循環(huán)內(nèi),可以編寫包含其它運行變量的其它程序循環(huán)。
通過指令“復(fù)查循環(huán)條件”(CONTINUE),可以終止當(dāng)前連續(xù)運行的程序循環(huán)。通過指令“立即退出循環(huán)”(EXIT) 終止整個循環(huán)的執(zhí)行。 WHILE
"Tag_Value1" <>"Tag_Value2"
DO "Tag_Result"
:= "Tag_Input";
END_WHILE;
WHILE 案例
FUNCTION_BLOCK "WHILE"
TITLE = 'WHILE Statement'
//WHILE ... DO ... END_WHILE
VAR_INPUT
Data : BLOCK_DB;
END_VAR
VAR
Runtime_variable : INT;
Dat : DATE;
NextWeek : ARRAY[1..7] OF DATE;
byteindex : INT;
bitindex : INT;
END_VAR
VAR_TEMP
t_Date : DINT;
i, k : INT;
END_VAR
BEGIN
//Simple WHILE statement
i := 0;
WHILE Data.DW = 16#FFFF DO
i := i + 1;
END_WHILE;
//Finding the next date that falls at the beginning of the week
t_Date := DATE_TO_DINT(Dat);
WHILE (t_Date MOD 7)+1 <> 1 DO
t_Date := t_Date + 1;
END_WHILE;
//Saving the date information for the next week
FOR i := 1 TO 7 DO
NextWeek := DINT_TO_DATE(t_Date + i - 1);
END_FOR;
//Finding the first input bit containing "1"
i := 0; k := 0;
WHILE I[i,k] = TRUE DO k := k + 1;
IF k = 8 THEN k := 0; i := i + 1; END_IF;
IF i > i + 4 THEN EXIT; END_IF;
END_WHILE;
byteindex := i; bitindex := k;
END_FUNCTION_BLOCK
第五章EXIT:立即退出循環(huán)
說明
使用“立即退出循環(huán)”指令,可以隨時取消 FOR、WHILE 或 REPEAT 循環(huán)的執(zhí)行,而無需考慮是否滿足條件。在循環(huán)結(jié)束(END_FOR、END_WHILE 或 END_REPEAT)后繼續(xù)執(zhí)行程序。
該指令將影響其所在的程序循環(huán)。
示例
:
SCL 將以下程序代碼復(fù)制到剪貼板。
FOR i := 15 TO 1 BY -2 DO
IF (i < 5)
THEN EXIT;
END_IF;
"DB10".Test := 1;
END_FOR;
如果滿足條件 i < 5,則將取消循環(huán)執(zhí)行。 程序?qū)腅ND_FOR 后繼續(xù)執(zhí)行。
如果不滿足條件 i < 5,則執(zhí)行后續(xù)的值分配(“DB10”.Test:= 1)并開始一個新循環(huán)。 將運行變量 (i) 以 2 進(jìn)行遞減,并進(jìn)行檢查該變量的當(dāng)前值是否在程序中設(shè)定的取值范圍之內(nèi)。如果執(zhí)行變量 (i) 在取值范圍內(nèi),則將再次計算 IF 的條件。
https://mp.weixin.qq.com/s?__biz=MzIzMjQ3MjM0Ng==&mid=2247483932&idx=1&sn=80cfe82cf8f362bf8d2574489d4966b6&chksm=e8952869dfe2a17ffdccbde976c4c3ba71fb7d6e025cb054d1ee1da0701008040239dd9617d3&token=716415798&lang=zh_CN#rd