Просмотр полной версии : Преобразование массива байт в формате Motorola в REAL
Читаю данные из расходомера в массив байт ARRAY [0..3] OF BYTE
Судя по инструкции, они хранятся "в формате Motorola (MSB->LSB)". Никак не могу преобразовать их в REAL. Пробовал использовать функции DWORD_OF_BYTE и DW_TO_REAL из oscat. Переставлял байты во всех возможных порядках, но все равно получается неверное число. Может кто-нибудь сталкивался.
FUNCTION Swap : REAL
VAR_INPUT
B : ARRAY[0..3] OF BYTE; //сюда пихаете свое ...
Order : WORD; (*2143,3412,4321, все остальное as is - 1234*) //... и определяете как свапить
END_VAR
VAR
{flag noinit on}
_ AT %MB0 : ARRAY[0..3] OF BYTE;
W1 AT %MB0 : WORD;
W2 AT %MB2 : WORD;
D AT %MB0 : DWORD;
X AT %MB0 : REAL;
{flag off}
END_VAR
---------------------------
_ := B;
CASE Order OF 3412,4321:
D := ROL(D, 16);
END_CASE
CASE Order OF 2143,4321:
W1 := ROL(W1, 8);
W2 := ROL(W2, 8);
END_CASE
Swap := X;
ps
такие примитивы быстрее написать чем шарится по каким-то оскатам.
скоро таблицу умножения там искать будут
CASE Order OF 3412,4321:
D := ROL(D, 16);
END_CASE
Что за странная конструкция оператора CASE ? Что там делается ?
CASE Order OF 3412,4321:
D := ROL(D, 16);
END_CASE
Что за странная конструкция оператора CASE ? Что там делается ?
очевидно же, что меняются слова местами
kondor3000
28.07.2022, 15:36
CASE Order OF 3412,4321:
D := ROL(D, 16);
END_CASE
Что за странная конструкция оператора CASE ? Что там делается ?
См. скрин 61882
А можно ещё вопрос по синтаксису?
{flag noinit on}
_ AT %MB0 : ARRAY[0..3] OF BYTE;
..............
{flag off}Где выделяется память под %MB0?
Для чего использовать директивы компилятора? Почему без них не обойтись?
kondor3000
28.07.2022, 22:07
А можно ещё вопрос по синтаксису?
{flag noinit on}
_ AT %MB0 : ARRAY[0..3] OF BYTE;
..............
{flag off}Где выделяется память под %MB0?
Для чего использовать директивы компилятора? Почему без них не обойтись?
Посмотрите мой скрин, начальные адреса массива, DWORD, REAL и первого WORD одинаковые AT %QB12.1.0, только второй WORD отличается адресом. Выделил память в слейве в виде 2 регистров. Это можно сделать двумя 2BYTE (так думаю лучше) или четырьмя 8 BIT ( 1 байт).
Перевёрнутые регистры (байты) получаем по Модбас в виде массива B и кладём их по адресу массива W. Переставляя слова в DWORD или байты в словах, получаем правильное значение ( всего 3 варианта).
В эмуляции я сначала выделил 4 байта, представил их в виде массива, переставил местами слова и подал их на вход функции.
(блоки разложения на байты и перестановки байтов у меня давно в личной биб-ке есть)
Пример склейки REAL из двух WORD, есть в моём примере, в последнем сообщении в конце страницы тут https://owen.ru/forum/showthread.php?t=35094#10
Байты переставлять и раскладывать можно так же, как в примере перестановки слов.
{flag noinit on} и {flag off} в 2.3 это комментарии и их можно просто выкинуть
Массив у меня W, а не _
W3, W4, D2 просто для наглядности, видно как меняются местами байты и регистры, r10 значение полученного REAL.
Где выделяется память под %MB0?
В области которую не видел кто использует )) Чего добру пропадать ?
Для чего использовать директивы компилятора? Почему без них не обойтись?
Потому что это - функция. На входе стековые переменные засираются неявно в 0 по стандарту КДС.
И КДС с какого-то считает что как бы локальные нестековые тоже нужно засрать.
От этой диареи есть директива запрета инициализации. Не нашел бы директивы (или б где-то нужна была бы %M...) - заюзал бы указатель.
.... тоже самое
VAR
pd : pointer to dword;
pw : pointer to word;
px : pointer to real;
END_VAR
---------------------------
pd := pw := px := adr(B);
CASE Order OF 3412,4321:
pd^ := ROL(pd^, 16);
END_CASE
CASE Order OF 2143,4321:
pw^ := ROL(pw^, 8);
pw := pw + 2;
pw^ := ROL(pw^, 8);
END_CASE
Swap := px^;
Но и тут поставил бы "flag noinit on" (была б) - ну накой бестолковое обнуление 12-ти байт если они в первой же строке устанавливаются.
В КДС3 - прошел бы union. Можно использовать SysMemSwap. Можно юзать не функцию а PROGRAM
Главное - понимать чего хочешь.
{flag noinit on} и {flag off} в 2.3 это комментарии и их можно просто выкинуть..
)) И КДС чудит (см. выше)
kondor3000, Валенок, спасибо.
Успешно решал подобную задачу на другом ПЛК, и при изучении в качестве тренировки пробовал в CoDeSys, но до указателей не додумался, а штатных средств приведения типов (typecast) не нашёл.
Спасибо.
а штатных средств приведения типов (typecast) не нашёл..
Дык везде где по одному адресу можно одновременно разместить разнотипные переменные это оно есть - штатное.
Powered by vBulletin® Version 4.2.3 Copyright © 2025 vBulletin Solutions, Inc. All rights reserved. Перевод: zCarot