Программирование ПЛК: преобразование в тип данных того же размера и обратное изменение фактического значения - PullRequest
0 голосов
/ 12 октября 2018

Функциональный блок дает мне номер типа данных REAL.Реальное должно быть преобразовано в DWORD.На используемой платформе типы данных имеют следующие размеры:

  • REAL: 32 бита (4 байта)
  • DWORD: 32 бита (4 байта)
* 1008Итак, я думаю, что если между этими двумя типами данных передается только битовое представление, значение не изменится или не потеряет точность.Я пытаюсь сделать следующее:
myReal : REAL;
myDWord : DWORD;
myResultReal : REAL;

myReal := 0.819;

myDWord := REAL_TO_DWORD(myReal);
myResultReal := DWORD_TO_REAL(myDWord);

// myResultReal has value: 1
// Also when I check the bit string of the myDWord it differs from the actual
// bit string of myReal. Immediately after the first conversion.

Вся проблема заключается только в правилах языка программирования.Поскольку оба типа данных имеют одинаковый объем памяти, преобразование кажется совершенно ненужным.Фактическая причина для конвертации - просто потому, что мне нужно передать свой номер в код позже, который принимает только типы данных DWORD.Затем он использует DWORD, чтобы получить REAL, но в этот момент это значение нежелательно.

Ответы [ 3 ]

0 голосов
/ 12 октября 2018

Есть два варианта.Любитель, который pboedker предложил: тип данных UNION.

Пример:

TYPE U_TestUnion :
UNION
    Value_DWORD : DWORD;
    Value_REAL  : REAL;
END_UNION
END_TYPE   

VAR
    TestUnion   : U_TestUnion;
END_VAR

 TestUnion.Value_REAL := 0.819;
 //TestUnion.Value_DWORD is now 1062316540 (=16#3F51A9FC)

 TestUnion.Value_DWORD := 10; 
 //TestUnion.Value_REAL is now 1.401298E-44 

 TestUnion.Value_DWORD := 1062316540; 
 //TestUnion.Value_REAL is now 0.819 

Другой - использовать функцию MEMCPY, которая копирует значения из памяти вДругое место.Функция может называться немного по-разному в разных системах.Делая это, вы можете скопировать содержимое из местоположения вашего реального значения на адрес DWORD и обратно.

В направлении REAL-> DWORD не должно быть никаких забот.Но при копировании из DWORD в REAL могут возникнуть некоторые проблемы, если есть вероятность, что данные были изменены где-либо.Возможно, это значение будет NaN или Infinity , что может привести к сбою ПЛК.Это означает, что REAL не правильно отформатирован десятичное число.

VAR
    Value_DWORD : DWORD;
    Value_REAL  : REAL;
END_VAR

Value_REAL := 0.819;
MEMCPY(destAddr:=ADR(Value_DWORD), srcAddr:=ADR(Value_REAL), n:=SIZEOF(Value_REAL));
 //Value_DWORD is now 1062316540 (=16#3F51A9FC)

Value_DWORD := 10; 
MEMCPY(destAddr:=ADR(Value_REAL), srcAddr:=ADR(Value_DWORD), n:=SIZEOF(Value_DWORD));
 //Value_REAL is now 1.401298E-44 

Value_DWORD := 1062316540; 
MEMCPY(destAddr:=ADR(Value_REAL), srcAddr:=ADR(Value_DWORD), n:=SIZEOF(Value_DWORD));
 //Value_REAL is now 0.819 
0 голосов
/ 13 октября 2018

Простым решением было бы умножить действительное значение в 10 n раз перед преобразованием, в зависимости от требуемой точности, например:

myReal := 0.819;

myDWord := REAL_TO_DWORD(myReal * 1000);
myResultReal := DWORD_TO_REAL(myDWord)/1000;

enter image description here

0 голосов
/ 12 октября 2018

Проблема в том, что вы используете преобразование, поэтому ваш REAL = 0,819 будет преобразован в DWORD = 1 и обратно в REAL = 1.Битовое представление будет соответствующим образом изменяться при каждом преобразовании.

Решение вашей проблемы - использовать UNION (IEC 61131-3).Таким образом, вы можете записать в часть REAL, передать часть DWORD в другой код, а затем снова использовать часть REAL в этом коде.

...