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)。

4 thoughts on “ST編程語言

  • 2019-06-18 at 09:38:13
    Permalink

    2. 麻煩提供程式碼以及宣告的BOOL變數
    3. 麻煩提供完整程式碼

    Reply
  • 2019-06-17 at 14:28:45
    Permalink

    1.MC_OPT是MSM基本指令,並非函式庫,剛測試一直都存在。
    5.剛測試新增函式庫沒發現問題,要新增資料夾必須先將函式庫切換成編輯模式(若函式庫有密碼需先輸入密碼)

    Reply
  • 2019-06-17 at 12:16:06
    Permalink

    1.函式庫裡面找不到MC_OPT的指令
    2.ST裡面如果我建立一個BOOL結構後,放在if 判斷式裡面編譯會錯誤
    3.在ST裡面,打上 A := B AND (C = FALSE); 這樣編譯也不會過(我忘記C是不是結構了)
    4.不能新增自訂的函示庫,不能新增自訂的函示庫,按右鍵”新增資料夾”是反白無法點選

    Reply
    • 2019-06-17 at 14:31:26
      Permalink

      剛測試:
      1.MC_OPT是MSM基本指令,一直都存在。
      4.新增函式庫測試正常,需切換成”編輯模式”(函式庫若有設定密碼需先輸入密碼)才可新增資料夾。

      Reply

發表迴響