В этой статье, или, скорее, цикле статей хочу поговорить о языках программирования ПЛК и дать их понимание и описание.
Языки программирования ПЛК прошли довольно приличный путь, прежде, чем обрели свой теперешний вид.
Изначально ПЛК представляли собой вообще устройства с жестко зашитой логикой работы. Что, конечно же, было весьма неудобно для случаев, если нужно было что-то поменять в цикле производства. Приходилось фактически изготавливать новый контроллер. Хотя это был самый дешёвый вариант. Затем были придуманы контроллеры, которые можно было перепрограммировать с помощью релейной логики. И именно от них и пошла аббревиатура ПЛК (PLC — programmable logic controller).
Затем появились контроллеры с программированием на машинно-ориентированном языке, что значительно облегчало адаптацию их под новые нужды производства. Но, с другой стороны, требовало постоянного привлечения профессиональных программистов. Затем для программирования использовались и языки высокого уровня, что опять-таки требовало наличия программистов.
Кроме того, каждый производитель промышленных контроллеров изобретал свой язык и способ программирования своих изделий. Что, безусловно, облегчало программирование контроллеров и не требовало наличия программистов, но вносило сумбур и чересчур большое разнообразие языков на рынке, что создавало сложности для потребителя.
И этот бардак длился до тех пор, пока МЭК (IEC) не был предложен стандарт, включающий в себя 5 (пять) языков программирования промышленных контроллеров, который поддержали и со временем дополнили большинство производителей контроллеров. Этот стандарт именуется МЭК (IEC) 61131-3.
Как я уже сказал, этот стандарт предусматривает 5 языков. Языки эти не были выдуманы разработчиками стандарта, а взяты из всего лучшего, что было уже наработано производителями ПЛК. Эти языки достаточно просты, ориентированы не на программистов, а на инженеров, которые разбираются и понимают процессы, требующие автоматизации с помощью ПЛК, и достаточно легки в освоении.
Итак, что же это за языки.
Хотя, стоп. Для начала — о типах данных.
В языках стандарта типы данных строго контролируются. Это означает, что присвоить одной переменной значение другой можно только, если обе — одного типа. Но есть функции явного преобразования типов.
Возможно и неявное преобразование типов в том случае, если переменной присваивается значение, тип данных которого совместим с типом данных переменной и имеет более узкое множество значений. Например, тип данных SINT (-128...+127) можно присваивать типу INT (-32568...+32567).
Приведу табличку с типами данных МЭК 61131-3
|
Тип |
Нижний предел |
Верхний предел |
Размер в байтах |
| Логический тип | |||
| BOOL | 0 (FALSE) | 1 (TRUE) | 1 бит |
| Целочисленные типы | |||
| BYTE | 8 бит | ||
| WORD | 16 бит | 2 | |
| DWORD | 32 бита | 4 | |
| LWORD | 64 бита | 8 | |
| SINT | -128 | 127 | 1 |
| INT | -32768 | 32767 | 2 |
| DINT | -231 | 231-1 | 4 |
| LINT | -263 | 263-1 | 8 |
| USINT | 0 | 255 | 1 |
| UINT | 0 | 65535 | 2 |
| UDINT | 0 | 232-1 | 4 |
| ULINT | 0 | 264-1 | 8 |
| Числа с плавающей точкой | |||
| REAL | ±10±38 | 4 (из них 23 бита – мантисса) | |
| LREAL | ±10±307 | 84 (из них 52 бита – мантисса) | |
| Строки | |||
| STRING | 1 на символ | ||
| WSTRING | 2 на символ | ||
| Время | |||
| TIME | Время длительности (интервал времени) | ||
| Дата и время | |||
| DATE | Календарная дата (в секундах от 01.01.1970 | 4 | |
| TIME_OF_DAY | Время суток (макс.=24 часа) | 4 | |
| DATE_AND_TIME | Дата и время | 4 | |
| Пользовательские типы | |||
| ARRAYS | Массив | ||
| STRUCT | Структура | ||
| TYPE | Одиночный тип | ||
А теперь – языки программирования ПЛК.
Знакомьтесь — IL – список инструкций (instruction list). Очень напоминает ассемблер. Все действия в нём совершаются через аккумулятор. Сначала в аккумулятор заносится необходимая переменная или величина, а затем с ней совершаются различные операции. Операций не много — всего 24.
| Оператор | Описание |
| LD | Загрузить значение операнда в аккумулятор |
| ST | Присвоить значение оператора аккумулятору |
| S | Если аккумулятор TRUE, то установить логический операнд (в TRUE) |
| R | Если аккумулятор FALSE, то сбросиь логический операнд (в FALSE) |
| AND | Поразрядное И |
| OR | Поразрядное ИЛИ |
| XOR | Поразрядное исключающее ИЛИ |
| NOT | Поразрядная инверсия аккумулятора |
| ADD | Сложение |
| SUB | Вычитание |
| MUL | Умножение |
| DIV | Деление |
| MOD | Деление по модулю |
| GT | > |
| GE | >= |
| QE | = |
| NE | <> |
| LE | <= |
| LT | < |
| JMP | Переход на метку |
| CAL | Вызов функционального блока |
| RET | Возврат в вызывающую программу |
Описанные в таблице инструкции — это обязательный набор, регламентированный стандартом. Но конкретные реализации языка для контроллера могут дополняться своими инструкциями по желанию производителя.
IL легко конвертируется в язык релейной логики LD, о котором мы поговорим дальше.
Подробнее расписывать этот язык я не буду. Во-первых, сам я им практически не пользуюсь, а во-вторых этот язык устарел и в третьей редакции стандарта МЭК 61131-3 от 2012 года его уже не рекомендуют к использованию.
В продолжении статьи мы поговорим о языке LD – ladder diagramm, или язык релейной логики, который очень хорошо понятен тем, кто имеет дело с электрическими схемами.
Есть замечания к статье? Делитесь ими в комментариях.
И не забывайте делиться статьей с коллегами в соцсетях!
