Записная книжка разработчика

Мои проекты

Протокол Modbus в устройствах на базе микроконтроллеров. Часть 1.2

| Comments

Продолжение. Начало здесь: http://32bit.me/?p=355 - введение; http://32bit.me/?p=373 - часть 1.0; http://32bit.me/?p=377 - часть 1.1.

Перед тем, как приступить к дальнейшим экспериментам с протоколом Modbus, разберёмся с ещё одной темой, относящейся к этому протоколу: с регистрами Modbus.

Каждая переменная, которую ведущее устройство считывает/записывает из ведомого устройства, имеет 16-битный адрес. Но помимо адреса, есть ещё тип регистра, обозначаеый обычно цифрой от 0 до 6 и буквой x, например 4х. Часто адрес переменной записывается, например, так: 400001. Это означает, что адрес переменной равен 1, и она относится к типу 4. Максимальное значение адреса равно 65535, поэтому для переменных типа 4 полные адреса будут находиться в диапазоне от 400001 до 465535 (от 4000116 до 4FFFF16).

Что означает тип переменной? Итак:

0 - Output coil (дискретные выходы)

1 - Discrete Inputs (дискретные входы)

3 - Input Registers (входные регистры)

4 - Holding Registers (регистры хранения)

5 - фактически используются регистры типа 4, но производится перестановка байт, она будет рассмотрена ниже.

6 - Extended Memory File. Используется крайне редко, и здесь рассматриваться не будет.

Как мы видим, типа 2 не существует. Также, мы уже упоминали о том, что адрес, передающийся в посылке протокола, на 1 меньше, чем адрес регистра. Поэтому адреса Modbus нумеруются, начиная с 1, а не с 0. Максимальное же значенме адреса регистра равно 65535, а не 65536, как можно было бы подумать. Однако такое ограничение не очень существенно, так как реальные устройства редко имеют 65536 переменных, передаваемых по Modbus.

На практике обычно используются регистры тиов 0х и 1х для дискретных входов-выходов (1-битных), 3х и 4х для 16-битных переменных. Тип 5х фактически заменяется на тип 4х.

Формально, переменные с адресами 100001 и 400001 - разные переменные, так как, хотя они имеют одинаковый адрес регистра (1), они относятся к разным типам, к разным адресным пространствам. На практике же это не так. Сделать в одном устройстве переменные разных типов с одинаковыми адресами - грубая ошибка. Почему это так?

Откроем среду разработки ISaGRAF, зайдём в Словарь переменных, и попробуем добавить 2 переменные с одним и тем же адресом, скажем, 10, но одну в раздел "Целые/Действительные", а другую в раздел "Булевские". Теперь откроем карту адресов Modbus. Что мы видим? Там отображается только одна из введённых нами переменных, другим адрес просто не назначен. Более того, ISaGRAF просто отображает адресные пространства всех типов в на одну, общую карту адресов. Вы можете записать переменную типа 0х по адресу 10, а потом считать её значение по адресу 400010.

И если в вашем устройстве будут 2 переменные с адресами 10 и 400010, то контроллер под управлением ISaGRAF не сможет с ним работать.

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

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

Приведём список функций протокола Modbus

1 - Read coil (Чтение состояния выходов, регистры 0х)

2 - Read Discrete input (Чтение состояния входов, регистры 1х)

3 - Read holding register (Чтение регистров 4х)

4 - Read input register (Чтение регистров 3х)

5 - Write single coil (Запись состояния выходов, регистры 0х)

6 - Write single register (Запись одного регистра 4х)

1016 (16) - Write multiple register (Запись множества регистров 4х)

Остальные функции протокола используются крайне редко и здесь рассматриваться не будут.

Регистры типа 1х и 3х не поддерживают операции записи. Изначально они задумывались как регистры для входных переменных, однако никто не мешает использовать в качестве входных переменных регистры 0x и 4x. Именно поэтому чаще всего используются именно 0x и 4x, причём наиболее универсальными регистрами являются регистры 4x.

В описанных выше экспериментах мы наблюдали, что при обмене данными между панелью и контроллером использовались функции 3 и 1016 . Протоколом также предусмотрена функция 6 - запись одиночного регистра 4х, она используется редко, но некоторые ведущие устройства и OPC-сервера всё-таки могут её использовать.

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

Самый важный вывод, который можно сделать из перечисленного, состоит в том, что для реализации протокола Modbus в slave-устройстве достаточно поддерживать всего три функции: 3, 6 и 1016. Это позволит записывать и считывать как целочисленные 16-битные, так и однобитные переменные, представляя последние как нулевое либо ненулевое значение регистра.

Многие ведущие (masters) также предоставляют возможность работы с регистрами 3x и 4x как с набором из 16-и дискретных переменных, в этом случае для каждой переменной указывается адрес регистра и номер бита от 0 до 15.

Продолжение следует.

Владимир Татарчевский