结构化文本ST编程,西门子PLC编程语言中叫SCL ,其它任何PLC控制器编程语言还是叫结构化编程ST。 西门子SCL语言
第一章IF:条件执行 IF 分支
IF <条件> THEN <指令> END_IF;
如果满足该条件,则将执行 THEN 后编写的指令。 如果不满足该条件,则程序将从 END_IF 后的下一条指令开始继续执行。 IF 和 ELSE 分支
IF <条件> THEN <指令 1> ELSE <指令 0>; END_IF;
如果满足该条件,则将执行 THEN 后编写的指令。 如果不满足该条件,则将执行 ELSE 后编写的指令。 程序将从 END_IF 后的下一条指令开始继续执行。 IF、ELSIF 和 ELSE 分支 IF <条件 1> THEN <指令 1> ELSIF <条件 2> THEN <指令 2> ELSE <指令 0>; END_IF;
如果满足第一个条件(<条件 1>),则将执行 THEN 后的指令(<指令1>)。 执行这些指令后,程序将从 END_IF 后继续执行。 如果不满足第一个条件,则将检查第二个条件(<条件 2>)。如果满足第二个条件(<条件 2>),则将执行 THEN 后的指令(<指令2>)。 执行这些指令后,程序将从 END_IF 后继续执行。 如果不满足任何条件,则先执行 ELSE 后的指令(<指令 0>),再执行 END_IF 后的程序部分。
在 IF 指令内可以嵌套任意多个 ELSIF 和 THEN 组合。 可以选择对 ELSE 分支进行编程。 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:创建多路分支
说明:使用“创建多路分支”指令,可以根据数字表达式的值执行多个指令序列中的一个。 表达式的值必须为整数。执行该指令时,会将表达式的值与多个常数的值进行比较。如果表达式的值等于某个常数的值,则将执行紧跟在该常数后编写的指令。常数可以为以下值: · 整数(例如,5)
· 整数范围(例如,15 到 20)
· 由整数和范围组成的枚举(例如,10、11、15 到 20) CASE <表达式> 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
//...Statemen
//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:在计数循环中执行 说明 使用“在计数循环中执行”指令,重复执行程序循环,直至运行变量不在指定的取值范围内。 也可以嵌套程序循环。 在程序循环内,可以编写包含其它运行变量的其它程序循环。 通过指令“复查循环条件”(CONTINUE),可以终止当前连续运行的程序循环。通过指令“立即退出循环”(EXIT) 终止整个循环的执行。
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:满足条件时执行 说明
使用“满足条件时执行”指令可以重复执行程序循环,直至不满足执行条件为止。该条件是结果为布尔值(TRUE 或 FALSE)的表达式。 可以将逻辑表达式或比较表达式作为条件。 执行该指令时,将对指定的表达式进行运算。 如果表达式的值为 TRUE,则表示满足该条件;如果其值为 FALSE,则表示不满足该条件。
也可以嵌套程序循环。 在程序循环内,可以编写包含其它运行变量的其它程序循环。 通过指令“复查循环条件”(CONTINUE),可以终止当前连续运行的程序循环。通过指令“立即退出循环”(EXIT) 终止整个循环的执行。 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:立即退出循环 说明
使用“立即退出循环”指令,可以随时取消 FOR、WHILE 或 REPEAT 循环的执行,而无需考虑是否满足条件。在循环结束(END_FOR、END_WHILE 或 END_REPEAT)后继续执行程序。
该指令将影响其所在的程序循环。 示例 :
SCL 将以下程序代码复制到剪贴板。 FOR i := 15 TO 1 BY -2 DO IF (i < 5) THEN EXIT;
END_IF;
\"DB10\".Test := 1; END_FOR;
如果满足条件 i < 5,则将取消循环执行。 程序将从END_FOR 后继续执行。 如果不满足条件 i < 5,则执行后续的值分配(“DB10”.Test:= 1)并开始一个新循环。 将运行变量 (i) 以 2 进行递减,并进行检查该变量的当前值是否在程序中设定的取值范围之内。如果执行变量 (i) 在取值范围内,则将再次计算 IF 的条件。