ГОСТ Р МЭК 61131-3-2016. Национальный стандарт Российской Федерации. Контроллеры программируемые. Часть 3. Языки программирования
6.5 Переменные
6.5.1 Объявление и инициализация переменных
6.5.1.1 Общие положения
Переменные предоставляют средства идентификации объектов данных, содержание которых может изменяться. Например, данные, связанные с входами, выходами или памятью программируемого контроллера.
В отличие от литералов, которые являются внешним представлением данных, переменные могут изменять свое значение с течением времени.
6.5.1.2 Объявление
Переменные объявляются внутри одной из секций переменных.
Переменные можно объявлять, используя:
- элементарный тип данных; или
- предварительно определенный пользователем тип; или
- тип указателя; или
- прямо определенный пользователем тип.
Возможны следующие виды переменной:
- одноэлементная переменная, то есть переменная, тип которой либо:
- элементарный тип данных; или
- определенное пользователем перечисление или тип-диапазон; или
- определенный пользователем тип, происхождение которого,
определяемое рекурсивно, прослеживается до элементарного типа, типа
перечисления или типа-диапазона;
- многоэлементная переменная, то есть переменная, которая
представляет массив ARRAY или структуру STRUCT;
- указатель, то есть переменную, которая ссылается на другую
переменную или экземпляр функционального блока.
Объявление переменной состоит из следующих элементов:
- списка имен объявляемых переменных;
- символа двоеточия ":";
- типа данных с необязательной инициализации, специфичной для различных видов переменных.
Пример -
TYPE
myType: ARRAY [1..9] OF INT; // предварительно определенный пользователем тип
END_TYPE
VAR
myVar1, myVar1a: INT; // две переменные, используя элементарный тип
myVar2: myType; // используя предварительно определенный пользователем тип
myVar3: ARRAY [1..8] OF REAL; // используя прямо определенный пользователем тип
END_VAR
6.5.1.3 Инициализация переменных
Неявным начальным значением переменной (переменных) являются:
1 Неявное начальное значение (значения) лежащих в основе элементарных типов данных, как определено в таблице 10.
2 NULL, если переменная является указателем.
3 Определенное пользователем значение (значения) назначенного типа данных.
Это значение факультативно может быть определено использованием оператора присваивания ":=" в определении типа TYPE, как показано в таблице 11.
4 Пользователем значение (значения) переменной.
Это значение факультативно может быть определено использованием оператора присваивания ":=" в объявлении переменной VAR (см. таблицу 14).
Определенное пользователем значение может быть литералом (например, -123, 1.55, "abc") или константным выражением (например, 12*24).
Начальные значения не могут задаваться в объявлениях VAR_EXTERNAL.
Начальные значения могут также определяться с использованием определяемого экземпляром свойства инициализации, предоставляемого конструкцией VAR_CONFIG...END_VAR. Определяемые экземпляром начальные значения всегда замещают специфические для типа начальные значения.
Таблица 13
Определение переменных
Номер | Описание | Пример | Объяснение |
1 | Переменная элементарного типа данных | VAR MYBIT: BOOL; OKAY: STRING[10]; VALVE_POS AT %QW28: INT; END_VAR | Распределяет бит памяти логической переменной MYBIT Распределяет память для хранения строки с максимальной длиной 10 символов |
2 | Переменная с определенным пользователем типом данных | VAR myVAR: myType; END_VAR | Описание переменных с пользовательским типом данных |
3 | Массив | VAR BITS: ARRAY[0..7] OF BOOL; TBT: ARRAY [1..2, 1..3] OF INT; OUTA AT %QW6: ARRAY[0..9] OF INT; END_VAR |
|
4 | Указатель | VAR myRefInt: REF_TO INT; END_VAR | Определение переменной, являющейся указателем |
Таблица 14
Инициализация переменных
Номер | Описание | Пример | Объяснение |
1 | Инициализация переменной с элементарным типом данных | VAR MYBIT: BOOL := 1; OKAY: STRING[10] := 'OK'; VALVE_POS AT %QW28: INT:= 100; END_VAR | Распределяет бит памяти логической переменной MYBIT с начальным значением от 1. Распределяет память для хранения строки с максимальной длиной десяти символов После инициализации строка имеет длину 2 и содержит двухбайтовую последовательность символов "OK" (десятичные 79 и 75, соответственно), в порядке, подходящем для печати символьной строки |
2 | Инициализация переменной с определенным пользователем типом данных | TYPE myType: ... END_TYPE VAR myVAR: myType:= ... // инициализация END_VAR | Объявление определенного пользователем типа с инициализацией и без инициализации Описание с предварительной инициализацией переменной с определенным пользователем типом данных |
3 | Массив | VAR BITS: ARRAY[0..7] OF BOOL :=[1,1,0,0,0,1,0,0]; TBT: ARRAY [1..2, 1..3] OF INT := [9,8,3(10),6]; OUTARY AT %QW6: ARRAY[0..9] OF INT := [10(1)]; END_VAR | Распределяет 8 битов памяти для хранения начальных значений BITS[0]:= 1, BITS[1]:= 1,..., BITS[6]:= 0, BITS[7]:= 0. Распределяет целый массив TBT размером 2*3 с начальными значениями TBT[1,1]:= 9, TBT[1,2]:= 8, TBT[1,3]:= 10, TBT[2,1]:= 10, TBT[2,2]:= 10, TBT[2,3]:= 6. |
4 | Объявление и инициализация констант | VAR CONSTANT PI: REAL:= 3.141592; PI2: REAL:= 2.0*PI; END_VAR | Константа Символическая константа PI |
5 | Инициализация с использованием константных выражений | VAR PIx2: REAL:= 2.0 * 3.1416; END_VAR | Использует константное выражение |
6 | Инициализация указателя | VAR myRefInt: REF_TO INT := REF(myINT); END_VAR | Инициализирует переменную-указатель myRefInt ссылкой на переменную myINT. |
6.5.2 Секции переменных
6.5.2.1 Общие положения
Каждая декларация программного компонента (POU), то есть функционального блока, функции или программы и, дополнительно, метода, начинается частями от нуля или более объявлений, которые определяют имена, типы (и, если необходимо, физическое или логическое расположение и инициализацию) переменных, используемых в организационной единице.
Часть деклараций программного компонента POU может содержать различные секции VAR, в зависимости от вида программного компонента POU.
Переменные могут объявляться в различных текстовых конструкциях VAR ... END_VAR, включающих квалификаторы, такие как RETAIN или PUBLIC, при необходимости. Квалификаторы секций переменных кратко приведены на рисунке 7.
Ключевое слово | Использование переменной |
Секции VAR: зависящие от типа программного компонента POU (функция, функциональный блок, программа) или метода | |
VAR | Внутренние по отношению к объекту (функция, функциональный и т.д.). |
VAR_INPUT | Предоставленные извне, не модифицируются внутри объекта. |
VAR_OUTPUT | Предоставляемых объектом для внешних объектов. |
VAR_IN_OUT | Предоставляются внешними объектами, могут модифицироваться внутри объекта, предоставляться для внешнего объекта. |
VAR_EXTERNAL | Предоставляемые конфигурацией через VAR_GLOBAL. |
VAR_GLOBAL | Объявление глобальной переменной. |
VAR_ACCESS | Объявление пути доступа. |
VAR_TEMP | Временное хранилище для переменных в функциональных блоках, методах и программах. |
VAR_CONFIG | Специфическая для экземпляра инициализация и назначение расположения. |
(END_VAR) | Заканчивает описанные выше секции VAR. |
Квалификаторы: могут следовать за описанными выше ключевыми словами | |
RETAIN | Сохраняемые переменные. |
NON_RETAIN | Несохраняемые переменные. |
PROTECTED | Доступ только изнутри собственного объекта и его производных объектов (неявно). |
PUBLIC | Разрешен доступ из всех объектов. |
PRIVATE | Доступ только из собственно объекта. |
INTERNAL | Доступ только внутри одного пространства имен. |
CONSTANT <a> | Константа (неизменяемая переменная). |
Примечание - Использование данных ключевых слов является свойством программного компонента и элемента конфигурации, в котором они используются.
--------------------------------
<a> Экземпляры функциональных блоков не объявляются в секциях переменных с квалификатором CONSTANT.
Рисунок 7 - Ключевые слова объявлений переменных (сводка)
- VAR
Переменные, объявленные в секции VAR ... END_VAR сохраняются от одного вызова программы или экземпляра функционального блока до другого.
В пределах функций, переменные, объявленные в этой секции, не сохраняются между вызовами функций.
- VAR_TEMP
В пределах программных компонент, переменные могут объявляться только секции VAR_TEMP...END_VAR.
Для функций и методов ключевые слова VAR и VAR_TEMP эквивалентны.
Данные переменные распределяются и инициализируются специфическими для типа неявными значениями, и не сохраняются между вызовами.
- VAR_INPUT, VAR_OUTPUT и VAR_IN_OUT
Переменные, объявленные в данных секциях, являются формальными параметрами функций, типов функциональных блоков и методов.
- VAR_GLOBAL и VAR_EXTERNAL
Переменные, объявленные в секции VAR_GLOBAL, могут использоваться в других программных компонентах, если они повторно объявлены там в секции VAR_EXTERNAL.
На рисунке 8 показано использование ключевых слов VAR_GLOBAL, VAR_EXTERNAL и CONSTANT.
Объявление в элементе, содержащем переменную | Объявление в элементе, использующем переменную | Разрешено? | ||
VAR_GLOBAL X | VAR_EXTERNAL | CONSTANT | X | Да |
VAR_GLOBAL X | VAR_EXTERNAL | X | Да | |
VAR_GLOBAL CONSTANT X | VAR_EXTERNAL | CONSTANT | X | Да |
VAR_GLOBAL CONSTANT X | VAR_EXTERNAL | X | П/п | |
Примечание - Использование секции VAR_EXTERNAL в содержащемся элементе может приводить к непредвиденному поведению. Например, когда значение внешней переменной изменяется другим содержащимся элементом в одном и том же содержащемся элементе. |
Рисунок 8 - Использование VAR_GLOBAL, VAR_EXTERNAL
и CONSTANT (правила)
- VAR_ACCESS
Доступ к переменным, объявленным в секции VAR_ACCESS, может производиться с использованием пути доступа, заданного в объявлении.
- VAR_CONFIG
Конструкция VAR_CONFIG...END_VAR предоставляет средства для назначения специфического для экземпляра размещения символически представленных переменных, используя символ "*" или для присвоения специфических для экземпляра начальных значений символически представленным переменным, или и для того и для другого.
6.5.2.2 Область действия объявлений
Область действия (диапазон применимости) деклараций, содержащихся в разделе деклараций, является локальной для программных компонент, в которых данный раздел деклараций содержится. То есть объявленные переменные не будут доступны для других программных компонентов, за исключением явных параметров, передаваемых через переменные, которые объявлены как входы и выходы этих компонент.
Исключением из данного правила являются переменные, объявленные как глобальные. Такие переменные доступны для программных компонент только через объявление VAR_EXTERNAL. Тип переменных, объявленных в блоке VAR_EXTERNAL, должен быть согласован с типом, объявленным в блоке VAR_GLOBAL, связанных программ, конфигурации и ресурсе.
Ошибка возникает, если:
- какая-либо программная компонента пытается изменить значение переменной, которая была объявлена с квалификатором CONSTANT или в секции VAR_INPUT;
- переменная, объявленная как VAR_GLOBAL CONSTANT, в элементе конфигурации или программном компоненте ("содержащем элементе") используется в объявлении VAR_EXTERNAL (без квалификатора CONSTANT) любого элемента, содержащегося в пределах охватывающего элемента, как показано ниже.
Максимальное число переменных, допустимых в блоке объявления переменных, определяется разработчиком.
6.5.3 Переменные типа ARRAY переменной длины
Массивы переменной длины могут использоваться только как:
- входные, выходные или входные-выходные переменные функций и методов;
- входные-выходные переменные функциональных блоков.
Число размерностей массива и фактических и формальных параметров должны быть одинаковыми. Они определяются, используя символ звездочки как спецификацию неопределенного диапазона для границ индекса.
Массивы переменной длины предоставляют программам, функциям, функциональным блокам и методам средства использовать массивы с различными диапазонами индекса.
Для работы с массивами переменной длины предоставляются следующие стандартные функции (см. таблицу 15).
Таблица 15
Переменные типа ARRAY переменной длины
Номер | Описание | Пример |
1 | Декларация с использованием * ARRAY [*,*,...] OF тип данных | VAR_IN_OUT A: ARRAY [*, *] OF INT; END_VAR; |
Стандартные функции LOWER_BOUND и UPPER_BOUND | ||
2a | Графическое представление | Получить нижнюю границу массива:
Получить верхнюю границу массива:
|
2b | Текстовое представление | Получить нижнюю границу 2-го измерения массива A: low2:= LOWER_BOUND (A, 2); Получить верхнюю границу 2-го измерения массива A: up2:= UPPER_BOUND (A, 2); |
Пример 1
A1: ARRAY [1..10] OF INT:= [10(1)];
A2: ARRAY [1..20, -2..2] OF INT:= [20(5(1))];
// в соответствии с инициализацией массива, см. 6.4.4.5.2
LOWER_BOUND (A1, 1) 1
UPPER_BOUND (A1, 1) 10
LOWER_BOUND (A2, 1) 1
UPPER_BOUND (A2, 1) 20
LOWER_BOUND (A2, 2) -2
UPPER_BOUND (A2, 2) 2
LOWER_BOUND (A2, 0) ошибка
LOWER_BOUND (A2, 3) ошибка
Пример 2 - Суммирование массивов
FUNCTION SUM: INT;
VAR_IN_OUT A: ARRAY [*] OF INT; END_VAR;
VAR i, sum2: DINT; END_VAR;
sum2:= 0;
FOR i:= LOWER_BOUND(A,1) TO UPPER_BOUND(A,1)
sum2:= sum2 + A[i]; END_FOR;
SUM:= sum2; END_FUNCTION
// SUM (A1) 10
// SUM (A2[2]) 5
Пример 3 - Умножение матриц
FUNCTION MATRIX_MUL
VAR_INPUT
A: ARRAY [*, *] OF INT;
B: ARRAY [*, *] OF INT;
END_VAR;
VAR_OUTPUT C: ARRAY [*] OF INT; END_VAR;
VAR i, j, k, s: INT; END_VAR;
FOR i:= LOWER_BOUND(A, 1) TO UPPER_BOUND(A, 1)
FOR j:= LOWER_BOUND(B, 2) TO UPPER_BOUND(B, 2)
s:= 0;
FOR k:= LOWER_BOUND(A,2) TO UPPER_BOUND(A, 2)
s:= s + A[i,k] * B[k,j];
END_FOR;
C[i,j]:= s;
END_FOR;
END_FOR;
END_FUNCTION
// Использование:
VAR
A: ARRAY [1..5, 1..3] OF INT;
B: ARRAY [1..3, 1..4] OF INT;
C: ARRAY [1..5, 1..4] OF INT;
END_VAR
MATRIX_MUL (A, B, C);
6.5.4 Константные переменные
Константные переменные - это переменные, определенные в секции переменных, которая содержит ключевое слово CONSTANT. Применяются правила, определенные для выражений.
Пример - Константные переменные
VAR CONSTANT
PI: REAL:= 3.141592;
TwoPi: REAL:= 2.0*Pi;
END_VAR
6.5.5 Прямо представленные переменные (%)
6.5.5.1 Общие положения
Прямое представление одноэлементной переменной обеспечивается специальным символом, сформированных конкатенацией следующих элементов:
- знак процента "%"; и
- префиксы расположения I, Q или M; и
- префикс размера X (или никакого), B, W, D или L; и
- одно или более (см. ниже иерархическую адресацию) целых без знака, разделенных точками ".".
Пример -
%MW1.7.9
%ID12.6
%QL20
Разработчик определяет соответствие между прямым представлением переменной и физическим или логическим расположением адресуемой единицы в памяти на входе или на выходе.
Примечание - Использование прямо представленных переменных в телах функций, типов функциональных блоков, методов и типов программ ограничивает возможность многократного использования типов данных программных компонентов. Например, в системах программируемых контроллеров, где физические входы и выходы используются для различных целей.
Использование прямо представленных переменных разрешено в теле функций, функциональных блоках, программах, методах и в конфигурациях и ресурсе.
В таблице 16 представлены свойства прямо представленных переменных.
Таблица 16
Прямо представленные переменные
Номер | Описание | Пример | Объяснение | |
| Расположение (примечание 1) |
|
| |
1 | Расположение на входе | I | %IW215 | Входное слово 215 |
2 | Расположение на выходе | Q | %QB7 | Выходной байт 7 |
3 | Расположение в памяти | M | %MD48 | Двойное слово по адресу памяти 48 |
| Размер |
|
| |
4a | Размер одного байта | X | %IX1 | Тип входных данных BOOL |
4b | Размер одного байта | Отсутствует | %I1 | Тип входных данных BOOL |
5 | Размер байта (8 битов) | B | %IB2 | Тип входных данных BYTE |
6 | Размер слова (16 битов) | W | %IW3 | Тип входных данных WORD |
7 | Размер двойного слова (32 бита) | D | %ID4 | Тип входных данных DWORD |
8 | Размер длинного слова (64 бита) | L | %IL5 | Тип входных данных LWORD |
| Адресация |
|
| |
9 | Простая адресация | %IX1 | %IB0 | Один уровень |
10 | Иерархическая адресация с использованием "." | %QX7.5 | %QX7.5 %MW1.7.9 | Определенная разработчиком, например: два уровня, диапазоны 0..7; три уровня, диапазоны 1..16 |
11 | Частично определенные переменные с использованием "*" (примечание 2) | %M* |
| |
Примечание 1 - Национальные организации по стандартизации могут публиковать таблицы переводов этих префиксов. Примечание 2 - Для использования символа звездочки "*" в этой таблице требуется наличие свойства VAR_CONFIG и наоборот. |
Использование прямо представленных переменных в теле программных компонентов и методов является не рекомендуемой функциональной возможностью.
6.5.5.2 Прямо представленные переменные - иерархическая адресация
Когда простое прямое представление (одного уровня) расширяется дополнительными цифровыми полями, разделенными точками, оно интерпретируется как иерархический физический или логический адрес. Самое левое поле представляет верхний уровень иерархии, уровень понижается при переходе вправо.
Пример - Иерархический адрес
%IW2.5.7.1
Например, данная переменная представляет первый "канал" (слово) седьмого "модуля" на пятом "стеллаже" второй "шины ввода/вывода" этой системы программируемого контроллера. Максимальное число уровней иерархической адресации определяется разработчиком.
Использование иерархической адресации (для разрешения доступа программы из одной системы программируемого контроллера к данным другого программируемого контроллера) считается расширением языка, специфическим для разработчика.
6.5.5.3 Объявление прямо представленных переменных (AT)
Объявлению прямо представленных переменных в соответствии с таблицей 16 (например, %IW6) может даваться символическое имя, используя ключевое слово AT.
Переменным с определенными пользователем типами данных (например, массиву) может быть назначен "абсолютный" адрес в памяти, используя AT. Расположение переменной определяет начальный адрес памяти и не требует размера, равного или превышающего размер данного прямого представления (то есть допустимы пустая память и перекрытие).
Пример - Использование прямого представления
VAR INP_0 AT %I0.0: BOOL; AT %IB12: REAL; | Имя и тип для входа |
PA_VAR AT %IB200: PA_VALUE; | Имя и определенный пользователем тип для размещения входа, начиная с %IB200 |
OUTARY AT %QW6: ARRAY[0..9] OF INT; END_VAR | Массив из 10 целых для размещения в смежных выходных адресах, начиная с %QW6 |
Для всех видов переменных, определенных в таблице 13, явное (определенное пользователем) расположение в памяти может быть объявлено, используя ключевое слово AT в сочетании с прямо представленными переменными (например, %MW10).
Если в одном или нескольких объявлениях это свойство не поддерживается, это должно быть указано в декларации соответствия разработчика.
Примечание - Инициализация входов системы (например, %IW10) определяется Разработчиком.
6.5.5.4 Прямо представленные переменные - частично определенные с использованием "*"
Запись с символом звездочки "*" может использоваться в назначениях адреса внутри программ и типов функциональных блоков для обозначения еще не полностью определенного расположения для прямо представленных переменных.
Пример - VAR C2 AT %Q*: BYTE; END_VAR | Назначает еще не расположенный выходной байт переменной типа битовой строки C2, длиной 1 байт. |
В случае, когда прямо представленная переменная используется для назначения расположения внутренней переменной в части объявления программы, типа функционального блока, на месте префикса размера и целого со знаком может использоваться звездочка "*" для указания того, что прямое представление еще не полностью определено.
Переменные такого типа не могут использоваться в секциях VAR_INPUT и VAR_IN_OUT.
Использование этого свойства требует, чтобы положение структурированной переменной, объявленной таким образом, было полностью определено внутри конструкции VAR_CONFIG...END_VAR конфигурации для каждого экземпляра содержащего типа.
Ошибка возникает, если отсутствует какая-либо полная спецификация в конструкции VAR_CONFIG...END_VAR для какой-либо неполной спецификации адреса, выраженной символом "*" в любом экземпляре программы или функционального блока, который содержит такие неполные спецификации.
6.5.6 Сохраняемые переменные (RETAIN, NON_RETAIN)
6.5.6.1 Общие положения
Когда элемент конфигурации (ресурс или конфигурация) "запускается", как "теплый рестарт" или "холодный рестарт" в соответствии с МЭК 61131-1, каждая переменная, связанная с элементом конфигурации и ее программами, имеет значение, зависящее от операции запуска элемента конфигурации и объявления свойств переменной в части сохранения.
Свойства в части сохранения могут объявлять переменные, содержащиеся в секциях переменных VAR_INPUT, VAR_OUTPUT и VAR функциональных блоков и программ, сохраняемыми или несохраняемыми, используя квалификаторы RETAIN or NON_RETAIN, представленные на рисунке 7. Использование этих ключевых слов необязательно.
На рисунке 9 показан алгоритм назначения начальных значений переменным.
Рисунок 9 - Алгоритм назначения начального значения
переменной (правила)
1 Если тип рестарта - "теплый рестарт", как определено в МЭК 61131-1, то начальные значения всех переменных в секции переменных с квалификатором RETAIN будут сохраненными значениями. Данные значения - значения переменных в момент остановки ресурса или конфигурации.
2 Если тип рестарта - "теплый рестарт", то начальные значения всех переменных в секции переменных с квалификатором NON_RETAIN инициализируются.
3 Если тип рестарта - "теплый рестарт", и квалификаторы RETAIN и NON_RETAIN не отсутствуют, то начальные значения определяются разработчиком.
4 Если тип рестарта - "холодный рестарт", начальные значения переменных в секции VAR с квалификаторами RETAIN и NON_RETAIN инициализируются, как описано ниже.
6.5.6.2 Инициализация
Переменные инициализируются, используя определенные пользователем значения, специфические для переменной.
Если никакого значения для инициализации переменной явно не определено, используется определенное пользователем начальное значение, специфическое для переменной. Если ничего не определено, используется специфическое для типа неявное начальное значение, определенное в таблице 10.
Затем применяются следующие правила:
- переменные, которые представляют входы системы программируемого контроллера, как определено в МЭК 61131-1, инициализируются специфическим для разработчика способом;
- квалификаторы RETAIN и NON_RETAIN могут использоваться для переменных, объявленных в статических секциях VAR, VAR_INPUT, VAR_OUTPUT и VAR_GLOBAL, но не в секции VAR_IN_OUT;
- разрешено использование квалификаторов RETAIN и NON_RETAIN в объявлениях экземпляров функционального блока, класса и программы. Поэтому, все переменные образца обрабатываются как RETAIN или NON_RETAIN, за исключением следующего:
- переменная явно объявлена, как RETAIN или NON_RETAIN в объявлении функционального блока, класса или типа программы;
- переменная является типом функционального блока или классом. В этом случае применяется декларация сохранения используемого типа функционального блока или класса.
Разрешено использование квалификаторов RETAIN и NON_RETAIN для экземпляров типов структурированных данных. Поэтому, все элементы структуры, а также все элементы вложенных структур обрабатываются как RETAIN или NON_RETAIN.
Пример -
VAR RETAIN
AT %QW5: WORD:= 16#FF00;
OUTARY AT %QW6: ARRAY[0..9] OF INT:= [10(1)];
BITS: ARRAY[0..7] OF BOOL:= [1,1,0,0,0,1,0,0];
END_VAR
VAR NON_RETAIN
BITS: ARRAY[0..7] OF BOOL;
VALVE_POS AT %QW28: INT:= 100;
END_VAR