sz518104
级别: 家园常客
精华主题: 0
发帖数量: 915 个
工控威望: 788 点
下载积分: 17726 分
在线时间: 382(小时)
注册时间: 2009-01-05
最后登录: 2024-01-19
查看sz518104的 主题 / 回贴
楼主  发表于: 2018-11-20 08:57

结构化文本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

//...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:在计数循环中执行
说明
使用“在计数循环中执行”指令,重复执行程序循环,直至运行变量不在指定的取值范围内。
也可以嵌套程序循环。 在程序循环内,可以编写包含其它运行变量的其它程序循环。
通过指令“复查循环条件”(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 的条件。

https://mp.weixin.qq.com/s?__biz=MzIzMjQ3MjM0Ng==&mid=2247483932&idx=1&sn=80cfe82cf8f362bf8d2574489d4966b6&chksm=e8952869dfe2a17ffdccbde976c4c3ba71fb7d6e025cb054d1ee1da0701008040239dd9617d3&token=716415798&lang=zh_CN#rd