Как поменять местами байты в слове конкретного тега ?
![Как поменять местами байты в слове конкретного тега ? Как поменять местами байты в слове конкретного тега ?](https://www.rusavtomatika.com/articles/images/105/modbus_swap_byte__logo_02.webp)
В настройках драйвера для протокола Modbus есть возможность поменять местами байты в слове, но только для целого диапазона адресов (например, все Holding регистры или все Input регистры).
А как же поступить в случае, если поменять байты нужно только для некоторых переменных ?
Конкретно в драйвере modbus есть возможность использовать специальный тип адреса 3x_Double и 4x_Double, для которых можно задать порядок байт.
Таким образом без каких-либо ухищрений можно получать значение одного и того же регистра с разным порядком байт просто выбирая тип адреса 3x или 3х_Double (и 4x или 4х_Double соотвественно)
Однако бывают устройства, в драйвере которых нет возможности указать смену порядка байт.
Например в драйвере Siemens S7-1200/S7-1500 (Absolute Addressing) (Ethernet) такой возможности нет.
В этой статье мы рассмотрим два примера реализации возможности преобразования порядка байт на примере двух драйверов: Modbus TCP/IP и Siemens S7-1200/S7-1500 (Absolute Addressing) (Ethernet).
Для первого примера запустим симулятор сервера modbus и зададим регистрам 1, 2, 3, 4 в области памяти Holding Registers соотвествующие значения 1,2,3 и 4.
В реализации преобразования порядка байт в слове нам поможет механизм адресных меток, в котором есть возможность указать какую-либо функцию из библиотеки макросов для преобразования в момент чтения или записи тега.
Откроем Макросы (про макросы у нас есть несколько статей 1, 2 и 3 и видео на нашем Youtube канале ) и в нём откроем Библиотеку макросов.
Откроем Библиотеку макросов и добавим новый макрос, который будем использовать для преобразлвания.
Назовём его swap_byte.
Текст нашего макроса будет простой:
sub unsigned short swap_byte(unsigned short input)
unsigned short output = 0
SWAPB(input, output)
return output
end sub
Для нашего преобразования мы использовали встроенную в EasyBuilder Pro функцию SWAPB.
Имя | SWAPB |
Синтаксис | SWAPB(source, result) |
Описание |
Обменивает старший и младший байты местами в 16-битном источнике. Источник может быть константой или переменной. Результат должен быть переменной. |
Пример использования |
macro_command main() short source, result SWAPB(0x5678, result) // result is 0x7856 source = 0x123 SWAPB(source, result) // result is 0x2301 end macro_command |
Откроем EasyBuilder Pro и добавим в окно несколько полей ввода/вывода чисел и текстовые подписи к ним.
Для удобства наблюдения за результатом преобразования отобразим одну и ту же переменные в разных системах счисления (dec - десятичной, hex - шестнадцатеричной, bin - двоичной).
Подписи swaped и direct означают перевернутый и прямой порядок байт.
Одновременно в окне будем наблюдать теги устройства "Modbus TCP/IP" и адресные метки с тем же адресами регистров.
Для наглядности механизма преобразования cоздадим две адресные метки с одним и тем же регистром modbus. В одной будем использовать преобразование, в другой не будем.
Создадим адресную метку (в рамках Weintek можно использовать термин "тег" для адресной метки) со следующими параметрами:
- имя: "tag_4x_swaped"
- устройство: " MODBUS TCP/IP"
- режим адреса: "слово"
- тип адреса: "4х"
- адрес: 1
- тип переменной выберем "16-bit Unsigned" для наглядности преобразования
- Поставим флажок "Преобразование/Вычисления"
- преобразование: формат данных – "16-bit Unsigned"
- преобразование: преобразование при чтении – выберем нашу функцию "swap_byte"
- преобразование: преобразование при записи – выберем нашу функцию "swap_byte"
Создадим адресную метку (в рамках Weintek можно использовать термин "тег" для адресной метки) со следующими параметрами:
- имя: "tag_4x_direct"
- устройство: " MODBUS TCP/IP"
- режим адреса: "слово"
- тип адреса: "4х"
- адрес: 1
- тип переменной выберем "16-bit Unsigned" для наглядности преобразования
- флажок "Преобразование/Вычисления" ставить не будем
Для второго примера возьмем ПЛК Siemens S7-1200 с драйвером Siemens S7-1200/S7-1500 (Absolute Addressing) (Ethernet).
В примере будем использовать тег hmi_cpu_load, который имеет тип UInt.
Создадим две адресные метки для этого тега – в одном будем использовать преобразование, в другом нет.
Запустим онлайн симулятор и посмотрим на значения регистра 1 в нашем устройстве "MODBUS TCP/IP" в оригинальном отображении (в десятичном представлении, в шестнадцатеричном и в двоичном) и в представлении наших адресных меток.
В онлайн симуляторе видно, что значение 1 в регистре представляется в адресной метке с преобразованием как 256.
Теперь зададим значение 256 в регистре 1 и посмотрим, что получится в наших адресных метках.
Запишем значение 8 в регистр и посмотрим, что получится после преобразования.
Все вопросы и обсуждения - на нашем форуме.