Адресация и типы данных в Modbus
Протокол передаёт голые 16-битные слова и биты. Что за ними стоит — целое, дробное, дата или строка — знает только документация устройства. Здесь разберём, как из этих слов получить осмысленные величины и не ошибиться адресом.
Четыре области данных
| Область | Что хранит | Чтение | Запись |
|---|---|---|---|
| Дискретные выходы (0x) | Биты: реле, флаги команд | 0x01 | 0x05, 0x0F |
| Дискретные входы (1x) | Биты: состояния входов | 0x02 | — |
| Входные регистры (3x) | 16-битные слова: измерения | 0x04 | — |
| Регистры хранения (4x) | 16-битные слова: уставки и измерения | 0x03 | 0x06, 0x10 |
Обозначения 0x, 1x, 3x, 4x пришли из документации на первые контроллеры Modicon и живут в документации до сих пор. В самом протоколе никаких «областей» нет — есть только код функции и адрес.
Смещение адресов: минус один
Самая частая ошибка при первом подключении. В документации регистр может называться 40001, а в кадр нужно положить адрес 0. Правило перевода:
| В документации | В кадре | Функция |
|---|---|---|
| 40001 | 0x0000 | 0x03 |
| 40108 | 0x006B | 0x03 |
| 30011 | 0x000A | 0x04 |
| 10021 | 0x0014 | 0x02 |
| 00033 | 0x0020 | 0x01 |
Но единого правила нет: часть производителей нумерует регистры с нуля и пишет в документации именно адрес кадра. Проверяется за минуту: прочитайте регистр по «документальному» адресу и по адресу минус один — осмысленное значение окажется в одном из них.
Числа шире 16 бит
Одно значение занимает два регистра, и здесь начинается разнобой: производители по-разному располагают старшее и младшее слово. Одно и то же число 70000 может выглядеть так:
| Порядок | Байты в кадре | Как читать |
|---|---|---|
| Старшее слово первым | 00 01 11 70 | обычный big-endian: (первое слово << 16) + второе |
| Младшее слово первым | 11 70 00 01 | слова поменять местами, затем как выше |
Числа с плавающей точкой
Значение 123,45 в формате IEEE 754 одинарной точности встречается в четырёх видах:
| Порядок | Байты |
|---|---|
| ABCD (big-endian) | 42 F6 E6 66 |
| CDAB (word swap) | E6 66 42 F6 |
| DCBA (little-endian) | 66 E6 F6 42 |
| BADC (byte swap) | F6 42 66 E6 |
Как определить нужный вариант без документации: прочитайте регистр с заведомо известной величиной — например, напряжение около 230 В. Из четырёх перестановок осмысленное значение даст ровно одна.
Знак, масштаб и единицы
- Знаковые числа. 0xFFFE — это 65534 как беззнаковое и −2 как знаковое. Что именно, протокол не сообщает; смотрите документацию.
- Масштаб. Целые числа часто хранят дробную величину: 2305 при масштабе 0,1 — это 230,5 В. Множитель либо фиксирован, либо лежит в соседнем регистре.
- Единицы. Один и тот же прибор может отдавать мощность в ваттах, а энергию — в десятых долях киловатт-часа. Единицы задаёт только документация.
Строки, даты и битовые поля
Строки укладывают по два символа в регистр; порядок символов внутри слова у разных производителей отличается — та же проблема, что и с байтами чисел. Даты чаще всего передают либо набором регистров «год, месяц, день, час, минута», либо секундами от эпохи в двух регистрах. Битовые поля состояния — это обычный регистр, каждый разряд которого имеет свой смысл; читать его нужно функцией 0x03, а не 0x01.
Пример полного разбора
Мы прочитали два регистра начиная с адреса 0 и получили ответ:
01 03 04 00 01 E2 40 E2 A3
Данные — 00 01 E2 40. Если это два независимых регистра, получаем 1 и 57920. Если это одно 32-битное число со старшим словом впереди — 123456. Если младшее слово впереди — 65538 · 1000 + …, то есть заведомая бессмыслица. Правильный ответ подсказывает физический смысл: для счётчика энергии это 123456, то есть 1234,56 кВт·ч при масштабе 0,01.
Именно поэтому первый шаг при подключении незнакомого устройства — сверить прочитанное с показанием на его дисплее.





















































































































