ST 编程语言 快速入门


结构式文件编程语言 (Structured Text) 也称为ST语言,是IEC 61131-3标准定义的语言之一,属高阶设计语言,可以执行多种操作,例如调用功能、功能块、赋值、有条件的执行语句和重複任务等,因此ST适用于完成较複杂的运算。ST编程语言由各种元素组成,具体如下。

 

ST

註解

註解多用于註记一些文字,以提高后续代码的维护性。它并不占用任何容量与影响执行结果。撰写註解的方式共区分单行、多行与区块几种方式。

 

单行註解

  i := i + 1  // comment;

区块註解

  ADD(a (* comment *) , b);

多行註解

  (* start comment
  ...
  end comment*)
  i := i + 1;

 

名词解释

st_noun

操作符与表示式

ST语言内的操作符与许多高阶语言皆十分相似,多用于数据的处理。而由操作数与操作符组合的结构我们称之为「表示式」,它在计算之后即获得返回值。下表表列ST所有可使用的操作符,并按其优先级进行排序(由高至低)。

 

操作符 含意 优先级 适用的操作数 范例
( ) 最高优先级的括号 最高 表示式

A := 1 + 2 * 3;  // A = 7

B := (1 + 2) * 3; // B = 9

Function 函式调用   运算式、变数或常数,其数据型态主要依据函式引述的定义。 A := ADD(1,2) * 3;  // A = 9
取反   INT、DINT或REAL48 的表示式、变数或常数。

A := 4;

B := – A;     // B = -4

NOT BOOL 的表示式、变数或常数。

A := TRUE;

B := NOT A;  // B = FALSE

**   [REAL48] ** [INT] A := 2.0 ** 2;  // A = 4.0
*   INT、DINT或REAL48 的表示式、变数或常数。 A := 2 * 3;    // A = 6
/ A := 6 / 3;    // A = 2
MOD 模除   INT或DINT的表示式、变数或常数。 A := 5 MOD 2;   // A = 1
+   INT、DINT或REAL48 的表示式、变数或常数。 A := 1 + 2;   // A = 3
A := 1 – 2;   // A = -1
= 等于比较   BOOL、INT、DINT或REAL48 的表示式、变数或常数。 A := 5 = 2;   // A = FALSE
<> 不等于比较 A := 5 <> 2;   // A = TRUE
> 大于比较 A := 5 > 2;   // A = TRUE
< 小于比较 A := 5 < 2;   // A = FALSE
>= 大于或等于比较 A := 5 >= 2;   // A = TRUE
<= 小于或等于比较 A := 5 <= 2;   // A = FALSE
& 逻辑与   BOOL 的表示式、变数或常数。

// A = FALSE

A := TRUE & FALSE;

AND

// A = FALSE

A := TRUE AND FALSE;

XOR 逻辑异或   BOOL 的表示式、变数或常数。

// A = TRUE

A := TRUE XOR FALSE;

OR 逻辑或 最低 BOOL 的表示式、变数或常数。

// A = TRUE

A := TRUE OR FALSE;


语句

 

语句是构成ST程序的基本单位,每项语句的最末皆以分号符号「;」表示结束。因此,一个语句可以分成数行编写,同时也可以将多个语句编写在同一行,只需在语句结束用分号隔开即可。

 

:= 赋值语句

表示式在经运算后会获得返回值,然而如何将其值指派给指定变数,我们可以採用赋值操作符与语句来达成这件事。赋值运算式的结构以赋值操作符 「:=」为主,左边置放目标变数,然后右边则为来源变数、常数或会含返回值的表示式。

 

tip  赋值操作的目标与来源需属同样的数据型态。编译器会于运行时检查此规则并于错误时给予告警。

  A := 10;
  B := A + 7; // B = 17
  fA := INT_TO_R48(B);  // "B" Data Type is INT, "fA" Data Type is REAL48  

 

条件语句

条件语句的目的在于做决定,在ST语言中有两种条件语句可以使用,分别为IF与CASE。

 

IF

IF语句的特性为根据布林表示式的回传值(TRUE/FALSE)决定是否执行内部的语句组,是(TRUE)则执行,反之亦然。

  IF [BOOL Expression] THEN  
     <Statements>;
  END_IF ;

通常我们也会搭配ELSE来处理当布林条件式不成立(FALSE)时,执行ELSE内部的语句组。

  IF [BOOL Expression] THEN  
    <Statements>;
  ELSE  
    <Statements>;
  END_IF ;

当有多个条件的需求时则可使用ELSIF,也就是说当条件不成立(FALSE)时会再判断下个ELSIF内的布林表示式,一旦成立(TRUE)则执行对应的语句组,反之则再判断下个ELSIF或是执行ELSE语句组。

  IF [BOOL Expression] THEN  
    <Statements>;
  ELSIF [BOOL Expression] THEN  
    <Statements>;
  ELSE  
    <Statements>;
  END_IF ;

如下范例,IF语句最终会将变数a设定为4。

  i := 2 ;
  IF i = 0 THEN  
    a := 1;   //  i = 0, a = 1
  ELSIF i = 1 THEN
    a := 2;   //  i = 1, a = 2
  ELSE  
    a := 4;   // other, a = 4
  END_IF ;

 

CASE

条件语句的另一种选择为CASE语句,但不同于IF语句,它的条件是採用数字表示式,因此很适用于某些用途。

  CASE [numeric expression] OF 
  [result1]: <Statements> 
  [resultN]: <Statemtents>
  ELSE 
    <Statements>
  END_CASE;

一个简单的CASE语句范例如下:

  STEP := 3;
  CASE STEP OF
  1: a := a+1;
  2: a := a+2;
  3: a := a+3;
  ELSE
      a := 0;
  END_CASE;

 

循环语句

执行循环是编程过程中常见的方式,举凡资料搬移、数值累加…等情境下都会运用到循环语句。

根据条件或计数,循环内的语句组将有机会重複运行直到条件或计数次数达指定条件

在ST语言裡分别提供 FOR、WHILE与REPEAT三种循环语句。当条件成立时FOR与WHILE将重複运行内部语句组,但与其相反的REPEAT则是一但条件成立即停止循环。

 

FOR

具体的指定预循环次数是FOR语句的特点。把一变数当计数使用,该计数当未达指定值时将持续执行内部的语句组。

  FOR count := initial_value TO final_value BY increment DO
    <statement>;
  END_FOR;

initial_value : 计数变数的初始值。

final_value :计数终点值,当计数变数超出该值时则停止循环。

increment : 每次迭代时的累加值。 在省略 BY 关键字时,编译器会自动将 increment 设为 1 , 也因此计数变数将在每次循环时累加1。

  FOR i := 0 TO 10 DO
    sum := sum + i;
  END_FOR;
  // sum = 55

tip多数情境下,我们应避免于FOR语句内中串改计数变数的数值,以防止造成不可预期的的循环次数。

 

WHILE

当布林条件成立(TRUE)时WHILE语句将不断的执行内部的语句组,直到条件不成立(FALSE)离开循环。

  WHILE [boolean expression] DO
    <statement>;
  END_WHILE;

简单的使用方式如下

  i := 0;
  WHILE i <= 10 DO
    sum := sum + i;
    i := i + 1;
  END_WHILE;

 

REPEAT

REPEAT正好与WHILE相反,循环会一值持续到布林条件成立(TRUE)即停止。

  REPEAT
      <statement>;
  UNTIL [boolean expression]
  END_REPEAT;

 

其他语句

 

EXIT 

不管循环语句是否已满足结束条件,EXIT语句可用于中断循环过程。

 

tip如果 EXIT 坐落于于多层的循环语句内,则退出循环仅發生在第一个遇到的循环语句(向外寻找)。

  FOR i := 1 TO 3 DO
    FOR j := 1 TO 5 DO
       IF FLAG THEN 
         EXIT; 
       END_IF;
       SUM := SUM + j;
    END_FOR;
  END_FOR;

 

RETURN

提供从函式、功能块或程序的出口。如下范例,函式将在某条件成立时立即返回,因此在RETURN后的代码将不再执行。

  FOR i := 0 TO 360 DO
    IF FLAG THEN 
       RETURN; 
    END_IF;  
    X := a * COS(i);
    Y := b * SIN(i);
  END_FOR;

 

 


tip以下内容属ServoMotion扩充支援的部分,可能与IEC61131-3规格略有不同tip

 


调用 (Funtion/物件)

透过调用语句来呼叫函式或物件功能。

 

a. 函式支援命名空间

命名空间又称函式库名称,在同个命名空间下不允许有重複的函式名称,换言之,如果有想保留相同命名的函式需求,可将他们分别定义在不同的命名空间。

  ASD:SET_MODE(X_AXIS, PATH);
  ASD:JOG(X_AXIS, 200, 200, 100000);

tip函式的调用需依指定规则撰写 : [函式库名称]:[函式名称](引述1,引述2, … ,引述n);  ,但调用基本函式库中的函式则是能省略库名称 ,如下:

  a := BASIC:SIN(0);
  a := SIN(0);

 

b. 支援Multi-Output

填入函式引述时请注意,由于函式支援多个VAR_OUTPUT参数,调用上可以针对VAR_OUTPUT的参数选择全填或全省略,而函式表示式本身的回传值是第一个VAR_OUTPUT参数。

  //DIV([input1],[inpout2],[output1],[output2])
  DIV(5, 3, 商, 馀);           //取得'商'与'馀'
  商 := DIV(5, 3);             //取得'商',忽略'馀'
  result := DIV(5, 3, 商, 馀); //取得'商'与'馀',且result = 商

tip 填写引述时由左至右的顺序排列为 : VAR_INPUT → VAR_IN_OUT → VAR_OUTPUT,务必依照该顺序方能正确传入参数至函式。

 

使用 MSM语言

部分情境下也许是效能、习惯与功能支援度等考量,你可在高阶语言(ST)中穿插低阶的MSM语言,如下演示:

nINC := Var1 * 10000 + Var2;
MSM(" SELECT X_AXIS"); //SELECT指令操作 
MSM(" PINC nINC");     //PINC指令操作
MSM("LABEL1:");        //标籤LABEL1

tip依据MSM语言的规则,每行代码的起头若有含空白符号则表示为指令(Instruction),反之则为标籤(Label)。

发表评论