БИБЛИОТЕКА НОРМАТИВНЫХ ДОКУМЕНТОВ

ГОСТ Р МЭК 61131-3-2016. Национальный стандарт Российской Федерации. Контроллеры программируемые. Часть 3. Языки программирования

6.4 Типы данных

6.4.1 Общие положения

Тип данных - это классификация, которая определяет возможные значения для литералов и переменных, операции, которые можно выполнять и способ хранения значений.

6.4.2 Элементарные типы данных (BOOL, INT, REAL, STRING и т.д.)

6.4.2.1 Спецификация элементарных типов данных

Настоящий стандарт устанавливает набор (предопределенных) элементарных типов данных.

Элементарные типы данных, ключевое слова для каждого типа данных, число битов на элемент данных и диапазон значений для каждого элементарного типа данных приведены в таблице 10.

 

Таблица 10

 

Элементарные типы данных

 

Номер

Описание

Ключевое слово

Неявное начальное значение

Длина (бит) <a>

1

Логический

BOOL

0, FALSE

1 <h>

2

Короткое целое

SINT

0

8 <c>

3

Целое

INT

0

16 <c>

4

Двойное целое

DINT

0

32 <c>

5

Длинное целое

LINT

0

64 <c>

6

Короткое целое без знака

USINT

0

8 <d>

7

Целое без знака

UINT

0

16 <d>

8

Двойное целое без знака

UDINT

0

32 <d>

9

Двойное целое без знака

ULINT

0

64 <d>

10

Действительные числа

REAL

0.0

32 <e>

11

Длинные целые

LREAL

0.0

64 <f>

12a

Продолжительность времени

TIME

T#0s

-- <b>

12b

Продолжительность времени

LTIME

LTIME#0s

64 <m>, <q>

13a

Дата (отдельно)

DATE

Примечание

-- <b>

13b

Длинная дата (отдельно)

LDATE

LDATE#1970-01-01

64 <n>

14a

Время суток (отдельно)

TIME_OF_DAY или TOD

TOD#00:00:00

-- <b>

14b

Время суток (отдельно)

LTIME_OF_DAY или LTOD

LTOD#00:00:00

64 <o>, <q>

15a

Дата и время суток

DATE_AND_TIME или DT

Примечание

-- <b>

15b

Дата и время суток

LDATE_AND_TIME или LDT

LDT#1970-01-01-00:00:00

64 <p>, <q>

14a

Время суток (отдельно)

TIME_OF_DAY или TOD

TOD#00:00:00

-- <b>

14b

Время суток (отдельно)

LTIME_OF_DAY или LTOD

LTOD#00:00:00

64 <o>, q>

15a

Дата и время суток

DATE_AND_TIME или DT

Примечание

-- <b>

15b

Дата и время суток

LDATE_AND_TIME или LDT

LDT#1970-01-01-00:00:00

64 <p>, <q>

16a

Строка однобайтовых символов переменной длины

STRING

" (пустая)

8 <i>, <g>, <k>, <l>

16b

Строка двухбайтовых символов переменной длины

WSTRING

" (пустая)

16 <i>, <g>, <k>, <l>

17a

Однобайтовый символ

CHAR

'$00'

8 <g>, <l>

17b

Двухбайтовый символ

WCHAR

"$0000"

16 <g>, <l>

18

Битовая строка длины 8

BYTE

16#00

8 <j>, <g>

19

Битовая строка длины 16

WORD

16#0000

16 <j>, <g>

20

Битовая строка длины 32

DWORD

16#0000_0000

32 <j>, <g>

21

Битовая строка длины 64

LWORD

16#0000_0000_0000_0000

64 <j>, <g>

Примечание - Определяется разработчиком, так как специальное стартовое значение отлично от 0001-01-01.

 

--------------------------------

<a> Значения в данной колонке интерпретируются как описано в подстрочных примечаниях к таблице.

<b> Диапазон значений и точность представления в данных типах данных определяются разработчиком.

<c> Диапазон значений переменных данного типа данных от -(2N-1) до (2N-1) - 1.

<d> Диапазон значений переменных данного типа данных от 0 до (2N) - 1.

<e> Диапазон значений переменных данного типа данных определяется в МЭК 60559 для основного формата с плавающей точкой одинарной точности. Результаты арифметических команд с ненормализованными значениями, бесконечным значением и нечисловыми значениями определяются разработчиком.

<f> Значение переменных данного типа данных определяется в МЭК 60559 для основного формата с плавающей точкой двойной точности. Результаты арифметических команд с ненормализованными значениями, бесконечным значением и нечисловыми значениями определяются разработчиком.

<g> Числовой диапазон значений не применяется к данному типу данных.

<h> Возможные значения переменных этого типа данных: 0 и 1, соответствующие ключевым словам FALSE и TRUE соответственно.

<i> Значение N указывает на число битов или символов для этого типа данных.

<j> Значение N указывает на число битов в битовой строке для этого типа данных.

<k> Допустимая переменных типов STRING и WSTRING определяется разработчиком.

<l> Типов CHAR, STRING, WCHAR и WSTRING используется кодировка по ИСО/МЭК 10646 (см. 6.3.3).

<m> Тип данных LTIME является 64-битовым целым числом со знаком, значение задается в наносекундах.

<n> Тип данных LDATE является 64-битовым целым числом со знаком, значение задается в наносекундах, с начальной датой 1970-01-01.

<p> Тип данных LTOD является 64-битовым целым числом со знаком, значение задается в наносекундах, начальное время с полуночи TOD#00:00:00.

<q> Точность обновления значений данного формата времени определяется разработчиком; то есть значение указывается в наносекундах, но оно может обновляться через микросекунду или миллисекунду.

 

6.4.2.2 Элементарные строковые типы данных (STRING, WSTRING)

Максимальная поддерживаемая длина элементов типа STRING и WSTRING задается разработчиком и определяет максимальную длину STRING и WSTRING, которая поддерживается средствами программирования и отладки.

Явная максимальная длина определяется максимальной длиной (которая не должна превышать поддерживаемое максимальное значение, определенное разработчиком), приведенной в скобках в соответствующем объявлении данных.

Доступ к отдельным символам строки в элементах данных CHAR или WCHAR осуществляется указанием в квадратных скобках позиции символа в строке, начиная с позиции 1.

Ошибка возникает, если к строкам двухбайтовых символов осуществляется доступ с использованием однобайтовых символов или если к строкам однобайтовых символов осуществляется доступ с использованием двухбайтовых символов.

Пример 1 - Типы STRING, WSTRING и CHAR, WCHAR

a) Объявление

VAR

String1: STRING[10]:= 'ABCD';

String2: STRING[10]:= ";

aWStrings: ARRAY [0..1] OF WSTRING:= ["1234", "5678"];

Char1: CHAR;

WChar1: WCHAR;

END_VAR

b) Использование типов STRING и CHAR

Char1:= String1[2]; // эквивалентно Char1:= 'B';

String1[3]:= Char1; // приводит к String1:= 'ABBD'

String1[4]:= 'B'; // приводит к String1:= 'ABBB'

String1[1]:= String1[4]; // приводит к String1:= 'BBBB'

String2:= String1[2]; (* приводит к String1:= 'BBBB'

если было выполнено неявное преобразование CHAR_TO_STRING*)

c) Использование типов WSTRING и WCHAR

WChar1:= aWStrings[1][2]; // эквивалентно WChar1:= 'B';

aWStrings[1][3]:= WChar1; // приводит к aWStrings[1]:= "5668"

aWStrings[1][4]:= "6"; // приводит к aWStrings[1]:= "5666"

WStrings[1][1]:= aWStrings[1][4]; // приводит к String1:= "6666"

aWStrings[0]:= aWStrings[1][4]; (* приводит aWStrings[0]:= "6";

если было выполнено неявное преобразование WCHAR_TO_WSTRING*)

d) Эквивалентные функции (см. 6.6.2.5.11)

Char1:= String1[2];

эквивалентно

Char1:= STRING_TO_CHAR(Mid(IN:= String1, L:= 1, P:= 2));

aWStrings[1][3]:= WChar1;

эквивалентно

REPLACE(IN1:= aWStrings[1], IN2:= WChar1, L:= 1, P:= 3);

e) Случаи ошибки

Char1:= String1[2]; // смешивание типов WCHAR,

STRING String1[2]:= String2;

// требует неявного преобразования STRING_TO_CHAR, которое не разрешено

Примечание - Типы данных для отдельных символов (CHAR и WCHAR) могут содержать только один символ. Строки могут содержать несколько символов; поэтому строки могут содержать дополнительную информацию для управления, которая не нужна для отдельных символов.

 

Пример 2 - Если тип STR10 объявлен как

TYPE STR10: STRING[10]:='ABCDEF'; END_TYPE,

то максимальная длина STR10 равна 10 символам, начальное значение по умолчанию равно 'ABCDEF', и начальная длина элементов данных типа STR10 равна шести символам.

6.4.3 Родовые типы данных

В дополнение к элементарным типам данных, приведенным в таблице 10, в спецификации входных и выходных переменных стандартных функций и функциональных блоков можно использовать иерархию родовых типов данных, показанных на рисунке 5. Родовые типы данных определяются по префиксу "ANY".

При использовании родовых типов данных следует соблюдать следующие правила:

1 Родовой тип прямо порожденного типа является таким же, как родовой тип элементарного типа, из которого он порожден.

2 Порожденным типом типа-диапазона является ANY_INT.

Родовым типом всех других порожденных типов, приведенных в таблице 11, является ANY_DERIVED.

Использование родовых типов данных в определенных пользователем программных компонентов находится вне области действия настоящего стандарта.

 

Родовые типы данных

Родовые типы данных

Группы элементарных типов данных

ANY

g)

 

ANY_DERIVED

ANY_ELEMENTARY

 

ANY_MAGNITUDE

 

ANY_NUM

 

ANY_REAL

h)

REAL, LREAL

ANY_INT

ANY_UNSIGNED

USINT, UINT, UDINT, ULINT

 

ANY_SIGNED

SINT, INT, DINT, LINT

 

ANY_DURATION

 

TIME, LTIME

ANY_BIT

 

BOOL, BYTE, WORD, DWORD, LWORD

ANY_CHARS

 

 

 

ANY_STRING

 

STRING, WSTRING

ANY_CHAR

 

CHAR, WCHAR

ANY_DATE

 

DATE_AND_TIME, LDT, DATE, TIME_OF_DAY, LTOD

 

Рисунок 5 - Иерархия родовых типов данных

 

6.4.4 Определенные пользователем типы данных

6.4.4.1 Объявление (TYPE)

6.4.4.1.1 Общие положения

Назначение определенных пользователем типов данных - это их использование в объявлении других типов данных и в объявлениях переменных.

Определенный пользователем тип данных может использоваться везде, где может использоваться базовый тип.

Определенные пользователем типы данных объявляются, используя текстовую конструкцию TYPE...END_TYPE. Объявление типа состоит из следующих элементов:

- имя типа;

- символ двоеточия ":";

- объявление собственно типа, как определено в следующих предложениях.

Пример - Объявление типа

TYPE

myDatatype1: <объявление типа с необязательной инициализацией>;

END_TYPE

6.4.4.1.2 Инициализация

Определенные пользователем типы данных могут быть инициализированы определенными пользователем значениями. Такая инициализация имеет приоритет над неявным начальным значением.

Определенная пользователем инициализация следует за объявлением типа и начинается оператором присваивания ":=", за которым следует начальное значение (значения).

Могут использоваться литералы (например, -123, 1.55, "abc") или константные выражения (например, 12*24). Используемые начальные значения должны иметь совместимый тип, то есть тот же самый тип или тип, который может быть конвертирован, используя неявное преобразование типа.

Для инициализации типов данных следует применять правила, приведенные на рисунке 6.

 

Родовой тип данных

Инициализировано литералом

Результат

ANY_UNSIGNED

Неотрицательный целый литерал или неотрицательное константное выражение

Неотрицательное целое значение

ANY_SIGNED

Целый литерал или константное выражение

Целое значение

ANY_REAL

Числовой литерал или константное выражение

Числовое значение

ANY_BIT

Целый литерал без знака или константное выражение без знака

Целое значение без знака

ANY_STRING

Битово-строковый литерал

Строковое значение

ANY_DATE

Литерал даты и времени суток

Значение даты и времени суток

ANY_DURATION

Литерал продолжительности времени

Значение продолжительности времени

 

Рисунок 6 - Инициализация литералами и константными

выражениями (правила)

 

В таблице 11 определены свойства объявления типов данных и их инициализации, определенных пользователем.

 

Таблица 11

 

Объявление определенных пользователем типов данных и их

инициализации

 

Номер

Описание

Пример

Объяснение

1a

1b

Перечислимые типы данных

TYPE

ANALOG_SIGNAL_RANGE:

(BIPOLAR_10V,

UNIPOLAR_10V, UNIPOLAR_1_5V,

UNIPOLAR_0_5V, UNIPOLAR_4_20_MA,

UNIPOLAR_0_20_MA)

 

:= UNIPOLAR_1_5V;

END_TYPE

Инициализация

2a

2b

Типы данных с именованными значениями

TYPE

Colors: DWORD

(Red := 16#00FF0000,

Green:= 16#0000FF00,

Blue := 16#000000FF,

White:= Red OR Green OR Blue,

Black:= Red AND Green AND Blue)

 

:= Green;

END_TYPE

Инициализация

3a

3b

Тип - диапазоны

TYPE

ANALOG_DATA: INT(-4095 .. 4095):= 0;

END_TYPE

 

4a

4b

Типы данных - массивы

TYPE ANALOG_16_INPUT_DATA:

ARRAY [1.. 16] OF ANALOG_DATA

ANALOG_DATA

см. выше.

:= [8(-4095), 8(4095)];

END_TYPE

Инициализация

5a

5b

Типы функциональных блоков и классы как элементы массива

TYPE

TONs: ARRAY[1..50] OF TON

:= [50(PT:=T#100ms)];

END_TYPE

Инициализация функционального блока TON как элемента массива

6a

6b

Структурированный тип данных

TYPE ANALOG_CHANNEL_CONFIGURATION:

STRUCT

RANGE: ANALOG_SIGNAL_RANGE;

MIN_SCALE: ANALOG_DATA:= -4095;

MAX_SCALE: ANALOG_DATA:=4095;

END_STRUCT;

END_TYPE

см. выше

ANALOG_SIGNAL_RANGE

7a

7b

Типы функциональных блоков и классы как элементы структуры

TYPE

Cooler: STRUCT

Temp: INT;

Cooling: TOF:= (PT:=T#100ms);

END_TYPE

Функциональный блок TOF как элемент структуры

8a

8b

Структурированный тип данных с относительной адресацией AT

TYPE

Com1_data: STRUCT

Явное расположение без перекрытия

head

AT %B0:

INT;

length

AT %B2:

USINT:= 26;

flag1

AT %X3.0:

BOOL;

end

AT %B25:

BYTE;

END_STRUCT;

END_TYPE

9a

Структурированный тип данных с относительной адресацией AT и OVERLAP

TYPE

Com2_data: STRUCT OVERLAP

Явное расположение с перекрытием

head

AT %B0:

INT;

length

AT %B2:

USINT;

flag2

AT %X3.3:

BOOL;

data1

AT %B5:

BYTE;

data2

AT %B5:

REAL;

end

AT %B19:

BYTE;

END_STRUCT;

END_TYPE

10a

10b

Прямо представленные элементы структуры - частично определенные, используя "*"

TYPE

HW_COMP: STRUCT;

IN AT %I*: BOOL;

OUT_VAR AT %Q*: WORD:= 200;

ITNL_VAR: REAL:= 123.0; // not located

END_STRUCT;

END_TYPE

Присваивает компоненты структуры еще не локализованным входным и выходным переменным, см. примечание 2

11a

11b

Прямо производный тип данных

TYPE

CNT: UINT;

FREQ: REAL:= 50.0; ANALOG_CHANNEL_CONFIG:

Инициализация

ANALOG_CHANNEL_CONFIGURATION

:= (MIN_SCALE:= 0, MAX_SCALE:= 4000);

END_TYPE

Новая инициализация

12

Инициализация с использованием константных выражений

TYPE

PIx2: REAL:= 2 * 3.1416;

END_TYPE

Использует константное выражение

Примечание 1 - Возможно объявление типа данных без инициализации (свойство "a") или с инициализацией (свойство "b"). Если поддерживается свойство "a", тип данных инициализируется с неявным начальным значением. Если поддерживается свойство "b", тип данных инициализируется с данным значением или неявным начальным значением, если начальное значение не дано.

Примечание 2 - Переменные с прямо представленными элементами - частично определенными, используя "*", не могут использоваться в секциях VAR_INPUT или VAR_IN_OUT.

 

6.4.4.2 Перечислимый тип данных

6.4.4.2.1 Общие положения

Объявление перечислимого типа данных означает, что каждый элемент данных этого типа может принимать только значения, указанные в соответствующем перечне идентификатора, как показано в таблице 11.

Перечень перечисления определяет упорядоченное множество перечислимых значений, начиная с первого идентификатора и оканчивая последним.

Различные перечислимые типы данных могут использовать одинаковые идентификаторы для перечислимых значений. Максимально допустимое число перечислимых значений определяется разработчиком.

Для обеспечения уникальной идентификации при использовании в конкретном контексте, перечислимые литералы могут уточняться префиксом, состоящим из имени ассоциированного типа данных и символа номера "#", аналогично типизированным литералам. В перечне перечисления префиксы не используются.

Происходит ошибка, если в перечислимом литерале недостаточно информации для однозначного определения его значения (см. пример ниже).

Пример - Перечислимый тип данных

TYPE

Traffic_light: (Red, Amber, Green);

Painting_colors: (Red, Yellow, Green, Blue):= Blue;

END_TYPE

VAR

My_Traffic_light: Traffic_light:= Red;

END_VAR

IF My_Traffic_light = Traffic_light#Amber THEN ... // OK

IF My_Traffic_light = Traffic_light#Red THEN ... // OK

IF My_Traffic_light = Amber THEN ... // OK - идентификатор Amber уникален

IF My_Traffic_light = Red THEN ... // ОШИБКА - идентификатор Red не является уникальным

6.4.4.2.2 Инициализация

Неявное начальное значение перечислимого типа данных - первый идентификатор в связанном перечне перечисления.

Пользователь может инициализировать тип данных определенным пользователем значением из перечня перечислимых значений данного типа. Такая инициализация имеет приоритет.

Как показано в таблице 11 для ANALOG_SIGNAL_RANGE, определенное пользователем начальное значение перечислимого типа данных - это присвоенное значение UNIPOLAR_1_5V.

Определенное пользователем присваивание начального значения типа данных является свойством в таблице 11.

6.4.4.3 Тип данных с именованными значениями

6.4.4.3.1 Общие положения

Связанным с перечислимым типом данных, где перечислимые идентификаторы не заданы пользователем, является перечислимый тип данных с именованными значениями. Объявление определяет тип данных и присваивает значения именованных переменных, как показано в таблице 11.

Объявление именованных значений не ограничивает диапазон значений переменных этого типа, то есть переменной могут быть присвоены другие константы, или значение может определяться вычислением.

Для обеспечения уникальной идентификации при использовании в конкретном контексте, именованные значения могут уточняться префиксом, состоящим из имени ассоциированного типа данных и символа номера "#", аналогично типизированным литералам.

В перечне объявления префиксы не используются. Происходит ошибка, если в перечислимом литерале недостаточно информации для однозначного определения его значения (см. пример).

Пример - Тип данных с именованными значениями

TYPE

    Traffic_light: INT (Red:= 1, Amber:= 2, Green:= 3):= Green;

    Painting_colors: INT (Red:= 1, Yellow:= 2, Green:= 3, Blue:= 4):= Blue;

END_TYPE

 

VAR

    My_Traffic_light: Traffic_light;

END_VAR

 

My_Traffic_light:= 27; // Присваивание константы IF

My_Traffic_light = Amber THEN ...// Присваивание выражения

                                 // Примечание - Это невозможно для перечислимых значений

My_Traffic_light:= Traffic_light#Red + 1;

 

    IF My_Traffic_light   = 123 THEN...                       // OK

    IF My_Traffic_light   = Traffic_light#Amber     THEN ...  // OK

    IF My_Traffic_light   = Traffic_light#Red       THEN ...  // OK

    IF My_Traffic_light   = Amber THEN ...                    // OK - идентификатор Amber

    уникален

    IF My_Traffic_light   = Red THEN ...                      // ОШИБКА - идентификатор

    Red не является уникальным

6.4.4.3.2 Инициализация

Неявное значение для типа данных с именованными значениями - это первый элемент данных в перечне перечисления. В приведенном выше примере для Traffic_light таким элементом является Red.

Пользователь может инициализировать тип данных определенным пользователем значением. Инициализация не ограничивается именованными значениями - может использоваться любое значение из диапазона базового типа. Такая инициализация имеет приоритет.

В пример, определенным пользователем начальным значением перечислимого типа для Traffic_light является Green.

Определенное пользователем присваивание начального значения типа данных является свойством в таблице 11.

6.4.4.4 Тип-диапазон

6.4.4.4.1 Общие положения

Декларацией типа-диапазона определено, что значение любого элемента данных этого типа может принимать значения между указанными верхними и нижними пределами (включительно), как показано в таблице 11.

Пределы в типе-диапазоне должны быть литералами или константными выражениями.

Пример -

TYPE

ANALOG_DATA: INT(-4095 .. 4095):= 0;

END_TYPE

6.4.4.4.2 Инициализация

Неявные начальные значения для типов данных с диапазоном - это первый (нижний) предел диапазона.

Пользователь может инициализировать тип данных определенным пользователем значением из диапазона. Такая инициализация имеет приоритет.

Например, как показано в примере, приведенном в таблице 11, неявное начальное значение элементов типа ANALOG_DATA равно -4095, в то время, как при явной инициализации, неявное начальное значение равно нулю (как объявлено).

6.4.4.5 Типы данных - массивы

6.4.4.5.1 Общие положения

Объявление типа данных - массива определяет, что должно быть выделено достаточное количество памяти для каждого элемента этого типа, чтобы хранить все данные, которые могут быть индексированы указанным поддиапазоном (поддиапазонами) индексов, как показано в таблице 11.

Массив - это совокупность элементов данных одинакового типа. В качестве типа элемента массива могут использоваться элементарные и определенные пользователем типы данных, типы функциональных блоков и классы. На данную совокупность элементов данных ссылаются с помощью одного или более индексов, заключенных в квадратные скобки и разделенных запятыми. Если значение индекса выходит за пределы, указанные в объявлении массива, возникает ошибка.

Примечание - Для вычисляемых индексов такая ошибка может быть обнаружена только во время выполнения.

 

Максимальное число индексов массива, максимальный размер массива и максимальный диапазон значений индекса определяются разработчиком.

Пределы в диапазона индекса должны быть литералами или константными выражениями. Массивы переменной длины определены в 6.5.3.

В языке ST индекс является выражением, производящим значение, соответствующее одному из подтипов родового типа ANY_INT.

Форма индексов в языке IL и графических языках, определенных в разделе 8, ограничена одноэлементными переменными или целыми литералами.

Пример -

a) Объявление массива

VAR myANALOG_16: ARRAY [1..16] OF ANALOG_DATA;

    := [8(-4095), 8(4095)];     // определенные пользователем начальные значения

END_VAR

b) Использование переменных массива в языке ST может быть следующим:

OUTARY[6,SYM]:= INARY[0] + INARY[7] - INARY[i] * %IW62.

6.4.4.5.2 Инициализация

Неявное начальное значение каждого элемента массива - это начальное значение, определенное для типа данных элементов массива.

Пользователь может инициализировать тип массива значением, определенным пользователем. Такая инициализация имеет приоритет.

Определенное пользователем начальное значение массива назначается в форме списка, в котором могут использоваться скобки для обозначения повторений.

Во время инициализации типов данных - массивов, самый правый индекс массива изменяется быстрее остальных при наполнении массива из списка начальных значений.

Пример - Инициализация массива

A: ARRAY [0..5] OF INT:= [2(1, 2, 3)]

эквивалентно последовательности инициализации 1, 2, 3, 1, 2, 3.

Если число начальных значений, данных в перечне инициализации превышает число входов массива, лишние (самые правые начальные значения будут отброшены. Если число начальных значений меньше, чем число входов массива, оставшиеся входы массива будут заполнены неявными начальными значениями для соответствующего типа данных. В любом случае, пользователь будет предупрежден об этой ситуации во время подготовки программы для выполнения.

Определенное пользователем присваивание начального значения типа данных является свойством в таблице 11.

6.4.4.6 Структурированный тип данных

6.4.4.6.1 Общие положения

Объявление структурированного типа данных (STRUCT) указывает, что этот тип данных содержит совокупность подэлементов определенных типов, к которым можно осуществлять доступ под определенным именем, как показано в таблице 11.

Элемент структурированного типа данных представляется двумя или более идентификаторами, разделенными точкой ".".

Первый идентификатор представляет имя структурированного элемента, а последующие идентификаторы представляют последовательность имен элементов для доступа к конкретному элементу данных в структуре данных.

В качестве типа элемента структуры могут использоваться элементарные и определенные пользователем типы данных, типы функциональных блоков и классы.

Например, элемент типа данных ANALOG_CHANNEL_CONFIGURATION, объявленный таблице 11, будет содержать подэлемент RANGE типа ANALOG_SIGNAL_RANGE, подэлемент MIN_SCALE типа ANALOG_DATA и подэлемент MAX_SCALE типа ANALOG_DATA.

Максимальное число элементов структуры, максимальное количество данных, которое может содержаться в структуре и максимальное число вложенных уровней адресации структурного элемента определяются разработчиком.

Две структурированных переменных являются совместимыми по присваиванию, только если они имеют одинаковый тип данных.

Пример - Объявление и использование структурированного типа данных и структурированной переменной.

a) Объявление структурированного типа данных

TYPE

   ANALOG_SIGNAL_RANGE: (BIPOLAR_10V,

                           UNIPOLAR_10V);

   ANALOG_DATA: INT (-4095 .. 4095);

   ANALOG_CHANNEL_CONFIGURATION:

     STRUCT

       RANGE:       ANALOG_SIGNAL_RANGE;

       MIN_SCALE: ANALOG_DATA:

       MAX_SCALE: ANALOG_DATA;

     END_STRUCT;

END_TYPE

b) Объявление структурированной переменной

VAR

    MODULE_CONFIG:ANALOG_CHANNEL_CONFIGURATION;

    MODULE_8_CONF:      ARRAY [1..8] OF ANALOG_CHANNEL_CONFIGURATION;

END_VAR

c) Использование переменных массива в языке ST:

MODULE_CONFIG.MIN_SCALE:= -2047;

MODULE_8_CONF[5].RANGE:= BIPOLAR_10V.

6.4.4.6.2 Инициализация

Неявные значения компонентов структуры даются их индивидуальными типами данных.

Пользователь может инициализировать компоненты структуры значениями, определенными пользователем. Такая инициализация имеет приоритет.

Пользователь может также инициализировать ранее определенную структуру, используя перечень присваиваний компонентам структуры. Данная инициализация имеет более высокий приоритет, чем неявная инициализация и инициализация компонентов.

Пример - Инициализация структуры

a) Объявление с инициализацией структурированного типа данных

TYPE

    ANALOG_SIGNAL_RANGE:

           (BIPOLAR_10V,

           UNIPOLAR_10V):= UNIPOLAR_10V;

    ANALOG_DATA: INT (-4095 ..4095);

    ANALOG_CHANNEL_CONFIGURATION;

STRUCT

       RANGE:       ANALOG_SIGNAL_RANGE;

       MIN_SCALE: ANALOG_DATA:= -4095;

       MAX_SCALE: ANALOG_DATA:= -4096;

END_STRUCT;

    ANALOG_8BI_CONFIGURATION:

      ARRAY [1..8] OF ANALOG_CHANNEL_CONFIGURATION

        := [8((RANGE:= BIPOLAR_10V))];

END_TYPE

b) Объявление с инициализацией структурированной переменной

VAR

    MODULE_CONFIG:ANALOG_CHANNEL_CONFIGURATION

     := (RANGE:= BIPOLAR_10V, MIN_SCALE:= -1023);

    MODULE_8_SMALL: ANALOG_8BI_CONFIGURATION

     := [8 ((MIN_SCALE:= -2047, MAX_SCALE:= 2048))];

END_VAR

6.4.4.7 Относительное положение элементов структурированных типов данных (AT)

6.4.4.7.1 Общие положения

Положения (адреса) элементов структурированного типа могут быть определены относительно начала структуры.

В этом случае, за именем компонента этой структуры следует ключевое слово AT и относительный адрес.

Объявление может содержать разрывы в расположении памяти.

Относительный адрес состоит из символа процента "%", определителя битового или байтового адреса. Байтовый адрес - это целый литерал без знака, обозначающий смещение в байтах. Битовый адрес состоит из смещения в байтах, следующего символа точки "." и смещения в битах, являющегося целым литералом без знака в диапазоне от 0 до 7. В относительном адресе не допускаются пробельные символы.

Компоненты структуры не должны перекрываться в расположении памяти, за исключением ситуации, когда в объявлении имеется ключевое слово OVERLAP.

Перекрытие строк находится вне области применения настоящего стандарта.

Примечание - Отсчет битового смещения начинается от самого правого бита с 0. Отсчет битового смещения начинается от начала структуры с 0.

 

Пример - Относительные адреса и перекрытие в структуре

TYPE

    Com1_data: STRUCT

head    AT %B0:     INT;      // в положении 0

length  AT %B2:     USINT=26; // в положении 2

flag1   AT %X3.0:   BOOL;     // в положении 3.0

end     AT %B25:    BYTE;     // в положении 25, оставляя разрыв

    END_STRUCT;

 

    Com2_data: STRUCT OVERLAP

head    AT %B0:     INT;    // в положении 0

length  AT %B2:     USINT;  // в положении 2

flag2   AT %X3.3:   BOOL;   // в положении 3.3

data1   AT %B5:     BYTE;   // в положении 5, перекрывается

data2   AT %B5:     REAL;   // в положении от 5 до 8

end     AT %B19:    BYTE;   // по адресу 19, оставляя разрыв

    END_STRUCT;

 

Com_data: STRUCT OVERLAP // C1 и C2 перекрываются

    C1 at %B0: Com1_data:

    C2 at %B0: Com2_data;

  END_STRUCT;

END_TYPE

6.4.4.7.2 Инициализация

Структуры с перекрытием не могут явно инициализироваться.

6.4.4.8 Прямо представленные компоненты структуры - частично определенные с использованием "*"

Символ звездочки "*" в таблице 11 может использоваться, чтобы обозначить еще не полностью определенные адреса для прямо представленных компонентов структуры.

Пример - Присваивание компонентов структуры еще не локализованным входным и выходным переменным.

TYPE

  HW_COMP: STRUCT;

    IN       AT %I*; BOOL;

    VAL      AT %I*; DWORD;

    OUT      AT %Q*: BOOL; OUT_VAR         AT %Q*: WORD;

    ITNL_VAR: REAL; // еще не локализован END_STRUCT;

END_TYPE

В случае, когда прямо представленный компонент структуры используется для назначения расположения в части объявлений программы, типа функционального блока или класса, на месте префикса размера и целого со знаком может использоваться звездочка "*" для указания того, что прямое представление еще не полностью определено.

Использование этого свойства требует, чтобы положение структурированной переменной, объявленной таким образом, было полностью определено внутри конструкции VAR_CONFIG...END_VAR конфигурации для каждого экземпляра охватывающего типа.

Переменные такого типа не могут использоваться в секциях VAR_INPUT, VAR_IN_OUT и VAR_TEMP.

Ошибка возникает, если отсутствует какая-либо полная спецификация в конструкции VAR_CONFIG...END_VAR для какой-либо неполной спецификации адреса, выраженной символом "*" в любом экземпляре программы или функционального блока, который содержит такие неполные спецификации.

6.4.4.9 Прямо порожденный тип данных

6.4.4.9.1 Общие положения

Определенные пользователем типы данных могут быть прямо порождены из элементарного типа данных или определенного пользователем типа данных.

Это может быть использовано для определения специфических для типа начальных значений.

Пример - Прямо порожденный тип данных

TYPE

   myInt1123:  INT:= 123;

   myNewArrayType: ANALOG_16_INPUT_DATA:= [8(-1023), 8(1023)];

   Com3_data: Com2_data:= (head:= 3, length:=40);

END_TYPE

   .R1: REAL:= 1.0;

   R2: R1;

6.4.4.9.2 Инициализация

Неявное начальное значение равно начальному значению типа данных, из которого порожден новый тип. Пользователь может инициализировать тип данных определенным пользователем значением. Такая инициализация имеет приоритет.

Определенное пользователем начальное значение элементов структуры может быть объявлено в перечне, заключенном в скобки и следующим за идентификатором типа данных. Элементы, начальное значение которых не перечислено в перечне инициализации, имеют неявные начальные значения, объявленные для них в объявлении оригинального типа данных.

Пример 1 - Использование определенных пользователем типов данных

С учетом объявлений ANALOG_16_INPUT_DATA в таблице 11 и объявления VAR INS: ANALOG_16_INPUT_DATA; END_VAR переменные от INS[1] до INS[16] могут использоваться везде, где могут использоваться переменные типа INT.

Пример 2

Аналогично, с учетом объявления Com_data в таблице 11 и, дополнительно, объявления VAR telegram: Com_data; END_VAR переменная telegram.length может использоваться везде, где может использоваться тип USINT.

Пример 3

Это правило может применяться рекурсивно:

С учетом объявления ANALOG_16_INPUT_CONFIGURATION, ANALOG_CHANNEL_CONFIGURATION и ANALOG_DATA в таблице 11 и объявления VAR CONF: ANALOG_16_INPUT_CONFIGURATION; END_VAR переменная CONF.CHANNEL[2].MIN_SCALE может использоваться везде, где может использоваться тип INT.

6.4.4.10 Указатели

6.4.4.10.1 Объявление указателя

Указатель - это переменная, которая содержит только ссылку на переменную или на экземпляр функционального блока. Указатель может иметь значение NULL, то есть он не ссылается ни на что.

Указатели объявляются для определенных типов данных, используя ключевое слово REF_TO и ссылочный тип данных - тип данных, на который производится ссылка. Ссылочный тип данных уже должен быть определен. Им может являться элементарный тип данных или определенный пользователем тип данных.

Примечание - Указатели без привязки к типу данных выходят за пределы настоящего стандарта.

 

Пример 1

TYPE

   myArrayType:     ARRAY[0..999] OF INT;

   myRefArrType:    REF_TO myArrayType;            // определение указателя

   myArrOfRefType:  ARRAY [0..12] OF myRefArrType; // определение массива ссылок

END_TYPE

VAR

   myArray1:        myArrayType;

   myRefArr1:       myRefArrType;       // определение указателя

   myArrOfRef:      myArrOfRefType;     // определение массива указателей

END_VAR

Ссылка должна ссылаться только на переменные указанного ссылочного типа данных. Указатели на прямо порождаемые типы данных обрабатываются как псевдонимы указателей на базовый тип данных. Прямое порождение может применяться несколько раз.

Пример 2

TYPE

myArrType1: ARRAY[0..999] OF INT;

myArrType2: myArrType1;

myRefType1: REF_TO myArrType1;

myRefType2: REF_TO myArrType2;

END_TYPE

myRefType1 и myRefType2 могут ссылаться на переменные типа ARRAY[0..999] OF INT и производных типов данных.

Ссылочный тип данных указателя может также являться типом функционального блока или классом. Указатель базового типа может также ссылаться на экземпляры, порожденные из этого типа данных.

Пример 3

CLASS F1 ...        END_CLASS;

CLASS F2 EXTENDS F1 ...   END_CLASS;

TYPE

   myRefF1:   REF_TO F1;

   myRefF2:   REF_TO F2;

END_TYPE

Указатели типа myRefF1 могут ссылаться на экземпляры классов F1, F2 и на производные от них классы. Однако указатели типа myRefF2 не могут ссылаться на экземпляры класса F1, а могут ссылаться только на экземпляры класса F2 и производные от него, так как класс F1 может не поддерживать методы и переменные расширенного класса F2.

6.4.4.10.2 Инициализация указателей

Указатели могут инициализироваться значением NULL (неявно) или адресом уже объявленных переменных, экземпляров функционального блока или класса.

Пример -

FUNCTION_BLOCK F1 ... END_FUNCTION_BLOCK;

VAR

   myInt:     INT;

   myRefInt:  REF_TO INT:= REF(myInt);

   myF1:   F1;

   myRefF1:   REF_TO F1:= REF(myF1);

END_VAR

6.4.4.10.3 Операции с указателями

Оператор REF() возвращает указатель на заданную переменную или экземпляр. Ссылочным типом данных возвращенного указателя является тип данных заданной переменной. Применение оператора REF() к временной переменной (например, переменным любой секции VAR_TEMP или любым переменным внутри функций) не разрешается.

Указатель может быть присвоен другому указателю, если его ссылочный тип данных эквивалентен базовому типу или является ссылочным типом данных присвоенного указателя.

Указатели могут присваиваться параметрам функций, функциональных блоков и методов в вызове, если ссылочный тип данных параметра эквивалентен базовому типу или является базовым типом ссылочного типа данных. Ссылки не могут использоваться как входные-выходные переменные.

Если указатель присвоен указателю такого же типа данных, то последний ссылается на ту же самую переменную. В таком случае, прямо порожденный тип данных рассматривается так же, как его базовый тип.

Если указатель присваивается указателю на такой же тип функционального блока или базовый тип функционального блока, то затем этот указатель указывает на тот же самый экземпляр, но является все еще связанным со своим типом функционального блока, то есть может использовать только переменные и методы своего ссылочного типа данных.

Разыменование указателей осуществляется явно.

Указатель разыменовывается использованием предшествующего символа крышки "ГОСТ Р МЭК 61131-3-2016. Национальный стандарт Российской Федерации. Контроллеры программируемые. Часть 3. Языки программирования".

Разыменованный указатель может использоваться так же, как прямо используется переменная. Разыменованный указатель на NULL является ошибкой.

Примечание 1 - Возможные проверки указателей на NULL может производиться во время компиляции, системой поддержки выполнения программы или прикладной программой.

 

Конструкция REF() и оператор разыменования "ГОСТ Р МЭК 61131-3-2016. Национальный стандарт Российской Федерации. Контроллеры программируемые. Часть 3. Языки программирования" используются в графических языках при определении операндов.

Примечание 2 - Арифметические операции с указателями не рекомендуются и не входят в задачу настоящего стандарта.

 

Пример 1

TYPE

S1: STRUCT

SC1: INT;

SC2: REAL;

END_STRUCT;

A1: ARRAY[1..99] OF INT;

END_TYPE

VAR

myS1: S1;

myA1: A1;

myRefS1: REF_TO S1:= REF(myS1);

myRefA1: REF_TO A1:= REF(myA1);

myRefInt: REF_TO INT:= REF(myA1[1]);

END_VAR

myRefS1"ГОСТ Р МЭК 61131-3-2016. Национальный стандарт Российской Федерации. Контроллеры программируемые. Часть 3. Языки программирования".SC1:= myRefA1"ГОСТ Р МЭК 61131-3-2016. Национальный стандарт Российской Федерации. Контроллеры программируемые. Часть 3. Языки программирования"[12]; // в данном случае, это эквивалентно S1.SC1:= A1[12];

myRefInt:= REF(A1[11]);

S1.SC1:= myRefInt"ГОСТ Р МЭК 61131-3-2016. Национальный стандарт Российской Федерации. Контроллеры программируемые. Часть 3. Языки программирования"; // присваивает значение переменной A1[11] элементу структуры S1.SC1

Пример 2

Графическое представление операторов из примера 1

 

"ГОСТ Р МЭК 61131-3-2016. Национальный стандарт Российской Федерации. Контроллеры программируемые. Часть 3. Языки программирования"

 

В таблице 12 приведены свойства операций с указателями.

 

Таблица 12

 

Операции с указателями

 

Номер

Описание

Пример

 

Объявление

 

1

// определение типа указателя

TYPE

myRefType: REF_TO INT;

END_TYPE

 

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

 

2a

Присваивание указателя указателю

<указатель>:= <указатель>

myRefType1:= myRefType2;

2b

Присваивание указателя параметру функции, функционального блока или метода

myFB (a:= myRefS1);

Типы должны быть эквивалентными

2c

Сравнение с NULL

IF myInt = NULL THEN ...

 

Создание ссылки

 

3a

REF (<переменная>)

Предоставляет типизированную ссылку на переменную

myRefA1:= REF (A1);

3b

REF (<экземпляр функционального блока>)

Предоставляет типизированную ссылку на экземпляр функционального блока или класса

myRefFB1:= REF(myFB1)

 

Разыменование

 

4

<указатель>"ГОСТ Р МЭК 61131-3-2016. Национальный стандарт Российской Федерации. Контроллеры программируемые. Часть 3. Языки программирования"

Предоставляет содержимое переменной или содержимое экземпляра, на которые ссылается переменная указателя

myInt:= myA1Ref"ГОСТ Р МЭК 61131-3-2016. Национальный стандарт Российской Федерации. Контроллеры программируемые. Часть 3. Языки программирования"[12];

TOC