ST 結構化文本教學:語法、IF/CASE/FOR,什麼時候該取代階梯圖
結構化文本(Structured Text, ST)是 IEC 61131-3 定義的文字式 PLC 語言,語法接近 Pascal。它不是要取代階梯圖——而是補上階梯圖做不好的那一半。
一、一個例子就懂為什麼需要 ST
需求:三個溫度感測器,取平均值,超過設定值就開冷卻。
用 ST:
avgTemp := (T1 + T2 + T3) / 3.0;
IF avgTemp > setPoint + 2.0 THEN
cooling := TRUE;
ELSIF avgTemp < setPoint - 2.0 THEN
cooling := FALSE;
END_IF;
六行,而且一眼就看懂在幹嘛(順便還做了 2 度的遲滯,避免頻繁啟停)。
用階梯圖: 要用 ADD 指令兩次、DIV 指令一次、暫存到 D 暫存器、再用比較指令 >、< 各一階……大概二十階,而且改一個數字就要重新對照一遍暫存器編號。
判斷原則很簡單:
· 開關、互鎖、時序邏輯 → 階梯圖(電氣人員好懂,現場好除錯,可以線上監看導通狀態)
· 數學運算、迴圈、陣列、狀態機 → ST(寫得快,改得快,看得懂)
實務上混用是常態,不是妥協。IEC 61131-3 定義多種語言就是這個用意。
· 開關、互鎖、時序邏輯 → 階梯圖(電氣人員好懂,現場好除錯,可以線上監看導通狀態)
· 數學運算、迴圈、陣列、狀態機 → ST(寫得快,改得快,看得懂)
實務上混用是常態,不是妥協。IEC 61131-3 定義多種語言就是這個用意。
二、基本語法
賦值與運算子
x := 10; // 賦值用 := (不是 =) y := x + 5 * 2; // 一般四則運算 flag := (a > b) AND NOT c; // 布林運算 // 比較運算子 = <> > < >= <= // 注意「不等於」是 <> 不是 != // 布林運算子 AND OR XOR NOT // 用英文字,不是 && ||
三個新手必踩的坑
1.
2. 整數除法會截斷。
3. 每一句結尾都要分號
1.
:= 是賦值,= 是比較。 寫錯編譯器通常會擋,但邏輯裡混用會很痛苦。2. 整數除法會截斷。
7 / 2 如果兩邊都是 INT,結果是 3 不是 3.5。要小數請確保至少一邊是 REAL:7.0 / 2。溫度、pH、流量這類計算最常在這裡出錯。3. 每一句結尾都要分號
;,END_IF; 也要。
資料型別
| 型別 | 範圍 / 用途 |
|---|---|
BOOL | TRUE / FALSE |
INT | 16 位元整數,-32768 ~ 32767 |
DINT | 32 位元整數(計數、積算用這個) |
REAL | 32 位元浮點數(溫度、pH、流量) |
TIME | 時間,寫法 T#5S、T#1M30S |
STRING | 字串(通訊、HMI 訊息) |
INT 溢位是真的會發生的事
用 INT 做累計運轉時數或流量積算,32767 之後會翻成負數。曾經有現場的累計流量跑到一半變負的,查半天才發現是型別選錯。累計類一律用 DINT 或 REAL。
用 INT 做累計運轉時數或流量積算,32767 之後會翻成負數。曾經有現場的累計流量跑到一半變負的,查半天才發現是型別選錯。累計類一律用 DINT 或 REAL。
三、控制流程
IF / ELSIF / ELSE
IF level < 30.0 THEN
pump := TRUE;
ELSIF level > 80.0 THEN
pump := FALSE;
END_IF;
// 注意:30~80 之間兩個條件都不成立 → pump 維持原值
// 這就是遲滯(hysteresis),是刻意的,不是漏寫
CASE — 寫狀態機的最佳工具
這是 ST 最有價值的用途之一。加藥程序、CIP 清洗、批次製程,用 CASE 寫會非常清楚:
CASE step OF
0: // 待機
IF startCmd THEN
step := 10;
END_IF;
10: // 進水
inletValve := TRUE;
IF levelHigh THEN
inletValve := FALSE;
stepTimer(IN := FALSE); // 計時器復歸
step := 20;
END_IF;
20: // 加藥並攪拌 5 分鐘
dosingPump := TRUE;
mixer := TRUE;
stepTimer(IN := TRUE, PT := T#5M);
IF stepTimer.Q THEN
dosingPump := FALSE;
step := 30;
END_IF;
30: // 沉澱靜置 10 分鐘(攪拌停)
mixer := FALSE;
stepTimer(IN := TRUE, PT := T#10M);
IF stepTimer.Q THEN
step := 40;
END_IF;
40: // 排水
drainValve := TRUE;
IF levelLow THEN
drainValve := FALSE;
step := 0; // 回到待機,完成一批
END_IF;
END_CASE;
// 急停:任何步驟都立即中斷
IF eStop OR fault THEN
inletValve := FALSE;
drainValve := FALSE;
dosingPump := FALSE;
mixer := FALSE;
step := 0;
END_IF;
為什麼 CASE 狀態機這麼好用?
每個步驟做什麼、什麼條件才進到下一步,一眼就看得出來。要插入新步驟(例如「加藥前先確認 pH」),只要新增一個 case、改兩個跳轉編號就好。
同樣的東西用階梯圖寫,是一堆 SET/RST 的旗標互相跳來跳去,三個月後你自己都看不懂。
步驟編號建議留間隔(0, 10, 20, 30…),之後要插步驟時才不用重編號。這是現場經驗。
每個步驟做什麼、什麼條件才進到下一步,一眼就看得出來。要插入新步驟(例如「加藥前先確認 pH」),只要新增一個 case、改兩個跳轉編號就好。
同樣的東西用階梯圖寫,是一堆 SET/RST 的旗標互相跳來跳去,三個月後你自己都看不懂。
步驟編號建議留間隔(0, 10, 20, 30…),之後要插步驟時才不用重編號。這是現場經驗。
FOR 迴圈
// 32 個感測器找最大值
maxVal := 0.0;
FOR i := 0 TO 31 DO
IF sensors[i] > maxVal THEN
maxVal := sensors[i];
END_IF;
END_FOR;
迴圈次數必須有上限,而且要小
PLC 的掃描週期有看門狗(Watchdog)限制,通常幾十到幾百毫秒。一個跑太久的迴圈會讓 PLC 直接停機報錯——這在產線上就是停產事故。
所以:絕不要用 WHILE 迴圈等待外部條件(例如「WHILE NOT 閥門到位 DO」),那會直接觸發看門狗。等待條件要用狀態機,讓每次掃描檢查一次就離開。
這是 PLC 和一般程式設計最根本的思維差異:PLC 程式必須在每次掃描內跑完,不能停在那裡等。
PLC 的掃描週期有看門狗(Watchdog)限制,通常幾十到幾百毫秒。一個跑太久的迴圈會讓 PLC 直接停機報錯——這在產線上就是停產事故。
所以:絕不要用 WHILE 迴圈等待外部條件(例如「WHILE NOT 閥門到位 DO」),那會直接觸發看門狗。等待條件要用狀態機,讓每次掃描檢查一次就離開。
這是 PLC 和一般程式設計最根本的思維差異:PLC 程式必須在每次掃描內跑完,不能停在那裡等。
四、實用範例:PID 之外的簡易溫控
不是每個場合都要 PID。很多環控場景用「遲滯 + 最短運轉時間」就夠了,而且更穩定:
// 溫度控制,含遲滯與壓縮機保護
minOffTimer(IN := NOT cooling, PT := T#3M); // 停機後至少 3 分鐘才准再啟動
IF temp > setPoint + 1.0 AND minOffTimer.Q THEN
cooling := TRUE;
ELSIF temp < setPoint - 1.0 THEN
cooling := FALSE;
END_IF;
那個 minOffTimer 是壓縮機的命。少了它,壓縮機會短循環,壽命大幅縮短——這在冷凍、空調、養殖水冷系統都是硬性要求。
五、廠牌差異
| 廠牌 | 名稱 | 備註 |
|---|---|---|
| 西門子 | SCL | TIA Portal 內建,支援度最完整 |
| 三菱 | ST | GX Works3 支援 |
| CODESYS 系 | ST | 最貼近 IEC 標準 |
| 台達 / 歐姆龍 | ST | 中高階機種支援,低階機種可能不支援 |
各家都自稱符合 IEC 61131-3,但不能直接複製貼上
函式庫名稱、計時器實例的宣告方式、字串處理函式,各家都有差異。跨廠牌移植時,核心邏輯可以沿用,但 I/O 對應與函式呼叫一定要重寫並實機測試。
別相信任何說「一鍵轉換各廠牌」的工具——包括 AI。AI 可以幫你把邏輯翻過去(省掉八成的打字),但編譯與實機驗證這關,永遠是人的責任。
函式庫名稱、計時器實例的宣告方式、字串處理函式,各家都有差異。跨廠牌移植時,核心邏輯可以沿用,但 I/O 對應與函式呼叫一定要重寫並實機測試。
別相信任何說「一鍵轉換各廠牌」的工具——包括 AI。AI 可以幫你把邏輯翻過去(省掉八成的打字),但編譯與實機驗證這關,永遠是人的責任。
小結
- ST 補的是階梯圖的短板:運算、迴圈、狀態機
:=賦值、<>不等於、整數除法會截斷、累計用 DINT- CASE 狀態機是寫批次/程序控制的最佳解
- 絕不用 WHILE 等外部條件——會觸發看門狗停機
- 互鎖與安全邏輯留在階梯圖:現場人員要看得懂、要能線上監看
AI 產生的 PLC 程式,到底能不能信?
我們建了一套 20 題基準測試,題目全部來自真實案場,並且公開了完整結果——包含難看的那幾項: 編譯通過率 80~95%、品牌指令混用 0%、整體全對 55~65%。
還有一個對我們自己不利的發現:AI review 幫得上找出可疑點,但 finding 本身也會誤報、必須經規則層與測試結果校正;它更不能可靠地「修好」程式。
→ 我們把 AI 寫 PLC 的準確率量出來了:20 題基準測試
我們建了一套 20 題基準測試,題目全部來自真實案場,並且公開了完整結果——包含難看的那幾項: 編譯通過率 80~95%、品牌指令混用 0%、整體全對 55~65%。
還有一個對我們自己不利的發現:AI review 幫得上找出可疑點,但 finding 本身也會誤報、必須經規則層與測試結果校正;它更不能可靠地「修好」程式。
→ 我們把 AI 寫 PLC 的準確率量出來了:20 題基準測試
用中文描述程序,直接產生 ST 狀態機
描述你的加藥程序、CIP 流程或批次控制,AI 產生完整 CASE 狀態機,含急停處理與計時器。可下載為西門子 SCL 外部原始檔。
免費試用 AI PLC 工具 →免費會員每月 15 點 · 不需信用卡 · 產生失敗不扣點
易歐特科技有限公司 · 工業自動化 PLC 程式設計與環控系統整合 · 複雜專案可委託開發