.. _modbus_byte_order: Перестановка байтов и регистров при передаче данных в Modbus ------------------------------------------------------------ Протокол Modbus широко используется для обмена данными между устройствами в системах промышленной автоматизации. При этом важно понимать, как данные (обычно 16-битные регистры) упаковываются и передаются, особенно когда речь идет о числах, занимающих больше одного байта (например, 32-битные целые и дробные числа). Порядок байтов в регистре (Byte Order / Endianness) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Каждый регистр Modbus имеет размер 16 бит (2 байта). При передаче этих 16 бит могут возникнуть различия в порядке байтов, в зависимости от того, как устройство хранит и передает данные. 1. От старшего байта(Big Endian) Принят по умолчанию в спецификации Modbus. - Старший байт (MSB) передается **первым**, младший (LSB) — **вторым**. - Например, число ``0x1234`` передается как: ``[0x12] [0x34]``. 2. От младшего байта(Little Endian) Нестандартный, но иногда используемый порядок. - Младший байт (LSB) передается **первым**, старший (MSB) — **вторым**. - Например, число ``0x1234`` передается как: ``[0x34] [0x12]``. .. note:: Протокол Modbus **рекомендует** использовать big endian (MSB-first), но **не требует** этого строго. Некоторые устройства могут использовать little endian, особенно если они хранят данные в памяти в таком порядке. Пример: - Предположим, вы хотите передать 16-битное целое число ``0xABCD``. - **Big Endian:** ``[0xAB] [0xCD]`` - **Little Endian:** ``[0xCD] [0xAB]`` Порядок регистров (Register Order) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Для передачи 32-битных значений (например, ``int32``, ``float``) используются **два 16-битных регистра**. Порядок этих регистров в пакете **не регламентирован** спецификацией Modbus, и может варьироваться от устройства к устройству. 1. От старшего регистра(Big Endian для регистров) - Старший 16-битный регистр передается **первым**, младший — **вторым**. - Например, 32-битное значение ``0x1234CDEF`` будет разбито на: - Регистр 1: ``0x1234`` - Регистр 2: ``0xCDEF`` - В пакете: ``[0x12] [0x34] [0xCD] [0xEF]`` 2. От младшего регистра (Little Endian для регистров) - Младший 16-битный регистр передается **первым**, старший — **вторым**. - То же значение ``0x1234CDEF`` будет передано как: - В пакете: ``[0xCD] [0xEF] [0x12] [0x34]`` .. note:: Комбинация порядка байтов и порядка регистров может быть разной. Например, вы можете получить: - Big Endian байты + Big Endian регистры - Little Endian байты + Little Endian регистры - И т.д. Пример: Допустим, вы передаете 32-битное значение ``0x1234CDEF``. - **Big Endian байты + Big Endian регистры:** - Регистр 1: ``0x1234`` - Регистр 2: ``0xCDEF`` - В байтах: ``[0x12] [0x34] [0xCD] [0xEF]`` - **Little Endian байты + Little Endian регистры:** - Регистр 1: ``0x1234`` → ``[0x34] [0x12]`` - Регистр 2: ``0xCDEF`` → ``[0xEF] [0xCD]`` - В байтах: ``[0xEF] [0xCD] [0x34] [0x12]`` .. note:: При работе с Modbus-устройством всегда проверяйте документацию к нему, чтобы убедиться, что данные интерпретируются правильно.