Описание языка ST в AgavaSCADA/AgavaPLC

Материал из docs.kb-agava.ru
Версия от 15:44, 11 августа 2026; TaushkanovKV (обсуждение | вклад) (Новая страница: «Данное описание содержит базовое руководство по созданию программ на языке <code>Structured Text<...»)
(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к навигации Перейти к поиску

Данное описание содержит базовое руководство по созданию программ на языке Structured Text (ST, IEC 61131-3) и их использованию в среде разработки Agava.

1 Дополнительные документы

Вы также можете ознакомиться с другими документами, размещенными в категории AgavaSCADA/AgavaPLC.

2 Основы синтаксиса

Программа на ST состоит из объявлений (типы, переменные, POU) и операторов. Операторы завершаются точкой с запятой. Присваивание выполняется оператором :=, сравнение на равенство — оператором =.

iCounter := iCounter + 1;
bOk := (iCounter = 10);

2.1 Комментарии

Поддерживаются три вида комментариев:

(* IEC-комментарий *)
/* C-style комментарий */
// комментарий до конца строки

3 Единицы организации программ (POU)

3.1 PROGRAM

Программа — единица, вызываемая задачей/хостом. Локальные переменные секции VAR сохраняют значения между вызовами (ретенция в рамках скана/повторных вызовов).

PROGRAM PumpCtrl
VAR
    iState : INT := 0;
END_VAR
    iState := iState + 1;
END_PROGRAM

3.2 FUNCTION

Функция — подпрограмма без собственного «состояния» между вызовами (кроме локальных экземпляров FB). Тип результата указывается после имени; результат записывается в переменную с именем функции.

FUNCTION Add : INT
VAR_INPUT
    a : INT;
    b : INT;
END_VAR
    Add := a + b;
END_FUNCTION
FUNCTION main : BOOL
VAR
    r : INT;
END_VAR
    r := Add(a := 2, b := 3);
    main := (r = 5);
END_FUNCTION

Если тип результата опущен, функция соответствует void (ничего не возвращает).

3.3 FUNCTION_BLOCK

Функциональный блок — экземплярный тип со входами/выходами и внутренним состоянием. Экземпляр объявляется в секции переменных и вызывается как процедура.

FUNCTION_BLOCK FB_Inc
VAR_INPUT
    IN : BOOL;
END_VAR
VAR_OUTPUT
    Q : BOOL;
END_VAR
VAR
    bPrev : BOOL := FALSE;
END_VAR
    Q := IN AND NOT bPrev;
    bPrev := IN;
END_FUNCTION_BLOCK
FUNCTION main : BOOL
VAR
    fb : FB_Inc;
END_VAR
    fb(IN := TRUE);
    main := fb.Q;
END_FUNCTION

Внутри FB поддерживаются методы Codesys-стиля METHOD … END_METHOD.

4 Переменные

Переменные объявляются в секциях VAR* / VAR_GLOBAL в виде:

имя {, имя} : тип [:= начальное_значение];
VAR
    a, b : INT := 0;
    sMsg : STRING := 'готово';
END_VAR

4.1 Секции переменных

Секция Назначение
VAR Локальные переменные
VAR_INPUT Входные параметры
VAR_OUTPUT Выходные параметры
VAR_IN_OUT Параметры «вход-выход» (по ссылке)
VAR_TEMP Временные локали PROGRAM (не сохраняются между вызовами)
VAR_GLOBAL Глобальные переменные compilation unit
VAR CONSTANT / VAR_GLOBAL CONSTANT Константы

Модификаторы RETAIN / PERSISTENT в текущей реализации не поддерживаются (выдаётся предупреждение; объявление обрабатывается как обычный VAR).

4.2 Типы данных

4.2.1 Логический тип

Тип ST Тип AS Значения
BOOL bool FALSE (0), TRUE (1)

4.2.2 Целочисленные типы

Тип ST Тип AS Диапазон (кратко)
SINT int8 −128 … 127
INT int16 −32 768 … 32 767
DINT int −2 147 483 648 … 2 147 483 647
LINT int64 64-битное знаковое
USINT / BYTE uint8 0 … 255
UINT / WORD uint16 0 … 65 535
UDINT / DWORD uint 0 … 4 294 967 295
ULINT / LWORD uint64 64-битное беззнаковое

4.2.3 Вещественные типы

Тип ST Тип AS
REAL float
LREAL double

Нетипизированный вещественный литерал (1.5) трактуется как REAL. Для LREAL используйте явный литерал: LREAL#3.14159.

4.2.4 Строки

Тип ST Описание
STRING / STRING(n) / STRING[n] Строка (UTF-8). С размером — ограничение длины при присваивании
WSTRING / WSTRING(n) / WSTRING[n] Широкая строка (UTF-16)

Строковые литералы заключаются в одинарные или двойные кавычки. Удвоение кавычки внутри строки экранирует её. Также поддерживаются escapes через $ (например $N).

Функции работы со строками (LEN, LEFT, RIGHT, MID, CONCAT, FIND и др.) описаны в документе Standard - стандартная библиотека.

4.2.5 Время и дата

Типы TIME, TOD (TIME_OF_DAY), DATE, DT (DATE_AND_TIME) и L-варианты представляются как int64 (семантика OSCAT: TIME/TOD — миллисекунды; DATE/DT — секунды).

Литералы:

T#50ms
T#1h30m
DATE#2025-01-01
TOD#14:03:30
DT#2025-11-19-14:03:30

4.2.6 Массивы

Объявление:

ARR : ARRAY [0..9] OF INT;
MATRIX : ARRAY [0..2, 0..2] OF REAL;

Индексация с учётом нижней границы объявления. Литерал инициализации:

A : ARRAY [0..2] OF INT := [10, 20, 30];

4.2.7 Структуры

TYPE Person :
STRUCT
    name   : STRING;
    age    : INT;
    height : REAL;
END_STRUCT
END_TYPE
VAR
    p1 : Person := (name := 'John', age := 30, height := 1.85);
END_VAR
p1.age := 31;

4.2.8 Перечисления

TYPE TrafficLight : (Red := 1, Yellow := 2, Green := 3);
END_TYPE
VAR
    light : TrafficLight := TrafficLight#Red;
END_VAR

Перечисление компилируется как целочисленный тип; доступ к значениям — через Type#Enumerator.

5 Операторы

5.1 Присваивание и сравнение

Оператор Символ Пример Операция
Присваивание := x := y Присвоить y переменной x
Равно = x = y TRUE, если x равно y
Не равно <> x <> y TRUE, если x не равно y
Меньше < x < y TRUE, если x меньше y
Больше > x > y TRUE, если x больше y
Меньше или равно <= x <= y TRUE, если x ≤ y
Больше или равно >= x >= y TRUE, если x ≥ y

5.2 Арифметические операторы

Оператор Символ Пример
Сложение
x + y
Вычитание
x − y
Умножение * x * y
Деление / x / y
Остаток MOD x MOD y

5.3 Логические и побитовые операторы

Оператор Символ Примечание
НЕ NOT Для BOOL — логическое; для целых — побитовое
И AND / & Для BOOL — логическое; для целых — побитовое
ИЛИ Для BOOL — логическое; для целых — побитовое
ИСКЛ. ИЛИ XOR Для BOOL — логическое; для целых — побитовое

Сдвиги и ротации — стандартные функции IEC: SHL, SHR, ROL, ROR (см. Standard - стандартная библиотека).

5.4 Литералы

  • Целые и вещественные: 42, 3.14, 1e-3; допускается разделитель _ в числах.
  • Базированные: 2#1010, 8#77, 16#FF.
  • Типизированные: DINT#0, REAL#1.5, BYTE#255.
  • BOOL: TRUE, FALSE.
  • Доступ к биту: dwordVar.3.

6 Условия

6.1 IF / ELSIF / ELSE

IF iState = 0 THEN
    iState := 1;
ELSIF iState = 1 THEN
    iState := 2;
ELSE
    iState := 0;
END_IF

6.2 CASE

CASE selector OF
    0:
        result := 10;
    1, 3:
        result := 20;
    4..7:
        result := 30;
ELSE
    result := 0;
END_CASE

Ветки без «проваливания» (fall-through). При пересечении диапазонов выбирается первая подходящая ветка.

7 Циклы

7.1 WHILE

i := 0;
WHILE i < 5 DO
    i := i + 1;
END_WHILE

7.2 REPEAT

i := 0;
REPEAT
    i := i + 1;
UNTIL i >= 5
END_REPEAT

Тело REPEAT выполняется хотя бы один раз.

7.3 FOR

FOR i := 0 TO 10 BY 2 DO
    sum := sum + i;
END_FOR

BY опционален (по умолчанию +1). Для обратного счёта: BY -1.

7.4 EXIT и RETURN

  • EXIT; — выход из ближайшего цикла.
  • RETURN; / RETURN expr; — выход из функции (без выражения в FUNCTION возвращается переменная результата).

Оператор CONTINUE как statement не поддерживается; пропуск итерации оформляйте через IF.

8 Вызовы функций и функциональных блоков

Позиционные и именованные аргументы:

r := Add(2, 3);
r := Add(a := 2, b := 3);

Для выходов FB/функций используется =>:

TestOUT(in1 := 15, iOut => intVal, bOut => boolVal);

Вызов экземпляра FB:

ton1 : TON;
ton1(IN := TRUE, PT := T#50ms);
ton1();   (* повторный опрос с сохранённым состоянием *)

Опущенные входы FB сохраняют предыдущие значения экземпляра (поведение IEC / CoDeSys).

Стандартные FB (TON, TOF, TP, RS, SR, CTU, …) и функции IEC описаны в Standard - стандартная библиотека.

9 Связь с AgavaScript

Тема Поведение
Файлы .st Компилируются ST-frontend
Имена IEC-функций В ST обычно в UPPER (SIN, ABS); в движке — lowercase (sin, abs)
Поля стандартных FB В UPPER (IN, Q, PT)
Host API Agava Доступен из ST без учёта регистра (GetNodeValueAsFloat, StoreMessage, …)
PROGRAM Локальный VAR сохраняется между вызовами

10 Ограничения

  • Указатели (POINTER TO, ADR, оператор ^) не поддерживаются.
  • RETAIN / PERSISTENT — не поддерживаются (warning).
  • CONTINUE как оператор цикла — не поддерживается.
  • Нельзя переопределить зарегистрированную IEC-функцию с той же сигнатурой.
  • PROGRAM нельзя использовать как экземплярный FB из другого POU.

11 Пример

FUNCTION_BLOCK FB_Counter
VAR_INPUT
    CU : BOOL;
    R  : BOOL;
END_VAR
VAR_OUTPUT
    CV : INT;
    Q  : BOOL;
END_VAR
    IF R THEN
        CV := 0;
    ELSIF CU THEN
        CV := CV + 1;
    END_IF
    Q := (CV >= 10);
END_FUNCTION_BLOCK
FUNCTION main : BOOL
VAR
    fb : FB_Counter;
    i  : INT;
END_VAR
    FOR i := 1 TO 10 DO
        fb(CU := TRUE, R := FALSE);
        fb(CU := FALSE, R := FALSE);
    END_FOR
    main := fb.Q AND (fb.CV = 10);
END_FUNCTION