Для чего нужна перестановка байт в CoDeSyS ?

В программной среде CoDeSyS перестановка байт требуется для правильных показаний датчиков при сопряжении двух устройств (Master и Slave), или когда на одном устройстве один порядок байт в слове, а втором другой. Компьютеры и оборудование, как и люди, разговаривают на разных языках. Одни хранят данные «слева направо», другие «справа налево». трудности возникают, когда требуется считать данные.
Всем привет!! Я решил написать небольшой минипост по теме перестановки байтов данных. Так как пытаюсь помочь себе разобраться в этом вопросе и считаю, что для вас эта информация будет не лишней. Честно говоря, я учился на энергетика, так что базовых знаний по программированию у меня к сожалению нет.
Всё приходится делать своими силами, и доходить приходится самому. Так что, где-то я могу ошибаться, но это ничего страшного. итак продолжим…
Циферки, числа, данные
Основная мысль заключается в понимании разницы между числами и данными вообще. Числа — это некие абстрактные понятия, исчисление чего-либо.
Возьмём число 10. Десять пальцев, десять яблок, десять корзинок, булочек и т.д. Понятие этого числа не изменяется, изменяется только его представление, римская цифра Х, машинная цифра в двоичной системе исчисления 1010 тоже «10».
А данные — это набор чисел, а так же и символов. Это некое машинное письмо. Ведь десять можно выразить и символами IO, и в форме записи на любом языке, или всё-таки значение в цифрах.
Другими словами данные — это последовательность битов и байтов, хранящихся на компьютере. Некая физическая величина. Процессор хранит данные в бинарной форме 0 и 1.
Процессоры говорят на разных языках, они имеют различные способы хранения абстрактного понятия числа «10».
Что хранит ПЛК?
В школе на уроках информатики нам говорили, что компьютер хранит данные в двоичной системе счисления. В виде нулей и единичек. Как происходит хранение данных.
- Самая первая и маленькая единица это Бит, он имеет два состояния 0 или 1.
- Байт это последовательность из 0 и 1. Байт состоит из 8 битов. То есть двоичная последовательность 10 является вот такой 00001010.
Биты нумеруются справа налево Бит 0 является младшим — это крайний правый, а бит 7 является старшим — это крайний левый.
А дальше мы с байтами поступаем как хотим, можно получить число Word — это два байта, или число Float — это 4 байта и т.д.
На сайте gidroboom.ru душевые кабиныасимметричные по низким ценам.
Машины отлично понимают, где находится «0» байт. И в каком порядке они начинают считаться. Ведь вроде бы все понятно с однобайтовыми системами. Но нет никакого соглашения в какой последовательности машины будут считать — в прямой или обратной.
Понятие указателя
Указатели являются ключевой частью программирования. Указатель представляет собой число, являющееся адресом в памяти. И это зависит только от нас (программистов), как интерпретировать данные по этому адресу.
В языке ST на CoDeSyS, когда вы приводите указатель к конкретному типу, это говорит компьютеру, как именно интерпретировать данные по этому адресу. Например, давайте объявим:
1 2 | p1: POINTER TO BYTE;(*указатель на результат функции*) p2: POINTER TO BYTE;(*указатель на массив регистров*) |
Это просто объявление указателя, теперь программист говорит ПЛК, что нужно указать на начало функции, и данные по этому адресу нужно интерпретировать как один символ (1 байт).
1 | p1:=ADR(two_word_to_real);(*указатель на начало результата функции (1-й байт)*) |
С помощью тех самых указателей мы можем проходиться по памяти считывать по одному байту за раз.
Таким образом мы можем преобразовать два Word'a (2 байта) в Float (4 байта).
Давайте сначала объявим переменные:
1 2 3 4 5 6 7 8 | FUNCTION two_word_to_real : REAL VAR_INPUT IN_Data: POINTER TO ARRAY[0..1] OF WORD;(*Указатель на массив регистров для Float*) END_VAR VAR p1: POINTER TO BYTE;(указатель на результат функции) p2: POINTER TO BYTE;(*указатель на массив регистров*) END_VAR |
Основная программа перестановки байт:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | p1:=ADR(two_word_to_real);(*указатель на начало результата функции (1-й байт)*) p2:=ADR(IN_Data^[1]);(*указатель на второй элемент массива (3-й байт) *) p1^:=p2^;(*копируем содержимое по адресу второго указателя в адрес первого указателя *) p1:=p1+1;(*смещаем адрес на 1 байт, теперь он указывает на 2-й байт результата*) p2:=p2+1;(*смещаем адрес на 1 байт, теперь он указывает на 4-й байт массива*) p1^:=p2^;(*копируем содержимое по адресу второго указателя в адрес первого указателя *) p1:=p1+1;(*смещаем адрес на 1 байт, теперь он указывает на 3-й байт результата*) p2:=ADR(IN_Data^[0]);(*указатель на первый элемент массива (1-й байт) *) p1^:=p2^;(*копируем содержимое по адресу второго указателя в адрес первого указателя *) p1:=p1+1;(*смещаем адрес на 1 байт, теперь он указывает на 4-й байт результата*) p2:=p2+1;(*смещаем адрес на 1 байт, теперь он указывает на 2-й байт массива*) p1^:=p2^;(*копируем содержимое по адресу второго указателя в адрес первого указателя *) |
В общем, как-то так. Если будут какие-то дополнения, пишите в комментариях.
Как я написал статью? Надеюсь понятно. Мне, честно говоря, тяжело даются эти понятия.
С уважением, Гридин Семён
Интересно, но не совсем понятно как в конкретной задаче реализовать данный пример. Хотелось бы проверить на своем примере, у меня в modbus master на 147 и 148 регистре имеются 16 битные данные (WORD), хочу преобразовать их в float и проверить с получаемым значением REAL. В итоге не совсем понятно как эти регистры объявить в VAR INPUT?