PDA

Просмотр полной версии : DWORD_TO_REAL



@ND
07.08.2015, 06:45
Мне нужно перевести 4 байта (16#40 00 00 00) в формат REAL
Так как порядок следования байт в REAL для СПК перепутан, пробую так:

dword_to_real(16#4000)

По идее это должно мне дать значение real равное 2.0 , но это не так.
Получается что dword это такой же числовой тип как и uint!
Спрашивается, зачем нужны два одинаковых типа?

И существует ли в ST оператор, который может нормально перевести 16#4000 в real = 2.0 ?

@ND
07.08.2015, 06:59
По сути, мне нужно решить задачу: корректно перевести переменную типа dword в real не используя память данных М в языке ST.
Это вообще реально?

_Mikhail
07.08.2015, 07:04
На форуме уже не раз выкладывался пример получения переменной типа REAL в СПК. Просто оператора нет, нужно написать функцию перестановки байт.

capzap
07.08.2015, 07:12
И существует ли в ST оператор, который может нормально перевести 16#4000 в real = 2.0 ?

только через указатель, либо самому написать функцию

@ND
07.08.2015, 07:16
На форуме уже не раз выкладывался пример получения переменной типа REAL в СПК. Просто оператора нет, нужно написать функцию перестановки байт.

Байты уже переставлены. Мне реал получить надо.

@ND
07.08.2015, 07:21
только через указатель, либо самому написать функцию

Разве возможно написать такую функцию на ST?
Где она будет хранить значения при перекидывании байт? (М память не предлагать)
Функциональный блок тут конечно справится. Но это как из пушки по воробьям.

@ND
07.08.2015, 07:24
Почему в других системах dword_to_real нормально работает, а в КДС так убого?

@ND
07.08.2015, 07:29
Даже документации по dword_to_real нет.

Yegor
07.08.2015, 07:29
Получается что dword это такой же числовой тип как и uint!По стандарту он не числовой ни разу, но ощущение, что на это забили вообще все.

DWORD_TO_REAL делает как раз числовое преобразование. Вам нужно реинтерпретировать байты через указатель:

d: DWORD;
ptrReal: POINTER TO REAL;
r: REAL;

ptrReal := ADR(d);
r := ptrReal^;

Будь у меня свой кодесис, я бы запретил на фиг арифметику и неявные преобразования в число для типов, которые имеют в своём названии WORD, чтобы вот этой путаницы не возникало. И сделал бы операторы вроде DWORD_AS_REAL, чтобы обходиться без указателей.

capzap
07.08.2015, 07:31
Разве возможно написать такую функцию на ST?
Где она будет хранить значения при перекидывании байт?
Функциональный блок тут конечно справится. Но это как из пушки по воробьям.
это делается за один цикл и памяти отведенной для этого в функции вполне хватает.

В каких системах есть такой перевод, поделитесь?

_Mikhail
07.08.2015, 07:35
Разве возможно написать такую функцию на ST?

Где она будет хранить значения при перекидывании байт?

Функциональный блок тут конечно справится. Но это как из пушки по воробьям.

1. Конечно написать можно. Она очень простая
19415
2. Функция не хранит данные, она пересчитывает и выдает результат
3. Хотите ФБ пожалуйста, только для этой задачи достаточно функции

@ND
07.08.2015, 07:35
Siemens step7
DWORD_TO_REAL(W#16#40000000) даст 2.0

Yegor
07.08.2015, 07:40
Тогда у Сименса логичнее. В кодесисе бред, с которым придётся смириться через указатели.

Пометка на полях: из Кодесиса в Степ7 код не копипастить.

@ND
07.08.2015, 07:52
Спасибо за своевременную помощь. Недооценил я указатели.
А на счёт DWORD_TO_REAL , разработчикам КДС минус.

@ND
07.08.2015, 07:54
Пометка на полях: из Кодесиса в Степ7 код не копипастить.

Это уголовно наказуемо? :)
Да и зачем. Там эта плюшка из коробки работает.

capzap
07.08.2015, 07:56
Тогда у Сименса логичнее. В кодесисе бред, с которым придётся смириться через указатели.

Пометка на полях: из Кодесиса в Степ7 код не копипастить.

вроде бы логичнее, но тот кто в степе написал 105 (SCALE), вход почему то в интах завел и FB41 преобразования все делает DINT_TO_REAL, я так же пользуюсь интами, поэтому DWORD_TO_REAL для меня открытие ) и почему все от логичности отказываются

@ND
07.08.2015, 08:06
вроде бы логичнее, но тот кто в степе написал 105 (SCALE), вход почему то в интах завел

Ну вообще то это логично подавать на вход число, характеризующую величину переменной процесса.
Как раз не логичнее там было бы видеть ворд.

capzap
07.08.2015, 08:09
так если DWORD-ами никто не пользуется Вам то это зачем :)
скале преобразует физ.аналоговый вход в реал, не такли, а он у них не в интах

@ND
07.08.2015, 08:13
так если DWORD-ами никто не пользуется Вам то это зачем :)
скале преобразует физ.аналоговый вход в реал, не такли, а он у них не в интах

Тут немчура конечно отчудила. Ставя по умолчанию на физ вход ворд. Но его ни кто не запрещает поменять на инт, прямо там же в настройках модуля ввода.

@ND
07.08.2015, 08:20
так если DWORD-ами никто не пользуется Вам то это зачем

Я пользуюсь.
Особенно когда много приходится работать с коммуникациями.
Удобно биты выделять, байты переворачивать и прочее.

Тут например я хотел сначала воспользоваться такой конструкцией:
DWORD_TO_REAL(ROL(%ID0, 16)) чтоб получить местный реал.

А приходится писать костыль на указателях.
Не люблю начинать знакомство с костылей. :)

capzap
07.08.2015, 08:33
Я пользуюсь.
Особенно когда много приходится работать с коммуникациями.
Удобно биты выделять, байты переворачивать и прочее.

Тут например я хотел сначала воспользоваться такой конструкцией:
DWORD_TO_REAL(ROL(%ID0, 16)) чтоб получить местный реал.

А приходится писать костыль на указателях.
Не люблю начинать знакомство с костылей. :)

коммуникациями какими? put и get, так там указателями на структуру можно, а в ней в структуре что угодно, необязательно ворды

@ND
07.08.2015, 08:57
Я имел в виду разбор телеграмм от различных устройств. (много приходится работать с протоколом модбас рту).

@ND
07.08.2015, 12:48
1. Ну и что, что в документации есть Union. Dword_to_real то нет. То бишь документация не полная.

2. Разницу между преобразованием и интерпретацией прекрасно понимаю, разве с самого начала не было понятно что мне нужно интерпретировать набор 4х байт в реал?

3. String_to_real в Step7 вообще нет. Так же не понял на счёт убожества: интерпретировать реал из 4х байт предварительно поменяв два ворда в них коротенькой строкой - что тут плохого или убогого?

4. UINT - числовой тип, DWORD - это не числовой тип. И я всегда привык работать с DWORD, как c не числовым типом. Потому то меня и выбило из колеи, когда DWORD_TO_REAL(16#1) дал мне 1.0

5. В MODBUS RTU телеграммы - это набор байт. Если мне удобно для работы с этими байтами пользоваться различными бинарными операторами и интерпретировать с помощью DWORD_TO_REAL в случае STEP7, то почему бы и нет?

@ND
07.08.2015, 15:10
Ничего. Вы сами себе выбрали "костыли" (C)

В данном случае костылём является как раз UNION. ("Многабукв" за вместо одной строки)


Т.е. Вы утверждаете что прочитали весь хелп ?

Поиск по "DWORD_TO_REAL" никто не отменял. Результат 0 topic(s) found.


Нет, непонятно что Вам нужно. Мелофон поломался

Ну остальные участники форума то поняли, зачем так цепляться?

capzap
07.08.2015, 15:43
Ну остальные участники форума то поняли, зачем так цепляться?

кто понял, я где то написал, скорее наоборот всё хотел узнать зачем Вам дворд, вялая отмазка про модбас не прокатит, тамслова используются а ни как не двойные, это Вы сами потом из них лепите двойное слово чтоб в реал перевести

@ND
07.08.2015, 16:25
На счёт понимания:
Валенку не понравилось что я за вместо слова "интерпретировать" слово "перевести" использовал. Согласен, не точно выразился. Но ведь по смыслу то, меня ведь правильно поняли, что мне нужна интерпретация 4х байт в реале, и правильно предложили написать функцию с использованием указателей.


всё хотел узнать зачем Вам дворд

Ну REAL занимает 4 байта, значение REAL можно интерпретировать, указав на на DWORD, или на два WORDа, или четыре байта, или 32 бита. Просто я выбрал одновесные типы вот и всё.

Пример из использования в Step7
Когда телеграммам прилетает на порт, она ложится в определенный DBxxx, по определенному адресу.
И если мне нужно интерпретировать REAL c 4х байт начиная с 200 адреса я пользовался следующей конструкцией:
real_var := DWORD_TO_REAL(DBxxx.DBD200);

int_var := WORD_TO_INT(DBxxx.DBW200); для интерпретации инта соотвтетственно.

Коротко и удобно.

capzap
07.08.2015, 16:31
Ну REAL занимает 4 байта, значение REAL можно интерпретировать, указав на на DWORD, или на два WORDа, или четыре байта, или 32 бита. Просто я выбрал одновесные типы вот и всё.

почему сразу не реал?

@ND
07.08.2015, 16:47
почему сразу не реал?

Ну в один момент времени там реал лежит, а в другой там может вообще какие нибудь дискретные сигналы лежат. Особенно если устройств опроса несколько или когда количество и качество запросов может меняться со временем.

Или может быть я не правильно понял. Как это сразу REAL ?
Предложите пример.

capzap
07.08.2015, 17:12
Ну в один момент времени там реал лежит, а в другой там может вообще какие нибудь дискретные сигналы лежат. Особенно если устройств опроса несколько или когда количество и качество запросов может меняться со временем.

Или может быть я не правильно понял. Как это сразу REAL ?
Предложите пример.
для какой среды? Для степа, так зачем изначально размещать в ДБшке двойное слово, когда можно реал и даже преобразовывать ничего не надо, для КДС3 - мне что то не попадалось где там в канальной части попадаются дворды, там только слова, для КДС2 - существует конфигуратор в котором сразу в мастере и вставляется нужный модуль - реал

@ND
07.08.2015, 17:21
для какой среды? Для степа, так зачем изначально размещать в ДБшке двойное слово, когда можно реал и даже преобразовывать ничего не надо, для КДС3 - мне что то не попадалось где там в канальной части попадаются дворды, там только слова, для КДС2 - существует конфигуратор в котором сразу в мастере и вставляется нужный модуль - реал

А если мне нужно будет порядок байт для REALа поменять или на коэффициент умножить?
А считывать мне нужно одной большой телеграммой, в которой есть как использующиеся данные так и нет и лежать они могут там с разрывами.
Так же производители устройств с поддержкой MODBUS протокола могут разместить realы таким образом, что они будут отстоять друг от друга скажем на один байт, тогда у вас вообще не получится их прописать как реалы.

Вот к примеру программа для одного соединения в STEP7

capzap
07.08.2015, 17:54
ну и что в этом коде не так, у Вас слейвы от каждого производителя разная последовательность байт, так это опять проблема не среды.Там имеет смысл поиграться с типами данных в структурах и можно не пользоваться роллами, а для каждого нума свою структуру, только там где требуется переворачивать так и так делать преобразования. В КДС так же своя структура в одном месте сразу пойдет, в другом преобразовывать всё равно придется

@ND
07.08.2015, 18:11
Дело еще в том, что этот код у меня пишет скрипт на VBA, и мне гораздо удобнее не заморачиваться со структурами, тем более еще с преобразованиями к этим структурам.
Мне гораздо удобнее, когда одна строка соответствует записи в один тег.

capzap
07.08.2015, 18:22
Дело еще в том, что этот код у меня пишет скрипт на VBA, и мне гораздо удобнее не заморачиваться со структурами, тем более еще с преобразованиями к этим структурам.
Мне гораздо удобнее, когда одна строка соответствует записи в один тег.

:) и во всем виноват S3 software, чеж не Путин то?

@ND
07.08.2015, 18:26
и во всем виноват S3 software

Да нет конечно.

Ну просто получается в STEP7 есть интерпретаторы типа DWORD_TO_REAL, WORD_TO_INT, ... и.т.д. так сказать из коробки,
а в КДС их нет. А ведь это хороший, достаточно нужный инструмент.

capzap
07.08.2015, 18:47
в КДС есть чтоТоТам_TO_чтоТоЕще, как оказалось с разницей, что степ DWORD переводит в REAL согласно IEEE745 только ради удобства а не логики

@ND
07.08.2015, 19:46
в КДС есть чтоТоТам_TO_чтоТоЕще, как оказалось с разницей, что степ DWORD переводит в REAL согласно IEEE745 только ради удобства а не логики

А где прослеживается логика, когда 16#1 переводится как 1.0 ? Учитывая, что DWORD это вообще не числовой тип.

capzap
07.08.2015, 20:12
dword_to_dint даст единицу, dint_to_real возвратит 1.0 здесь хоть какая то логика прослеживается. А преобразовывать во флоатовский формат, обязательно найдутся те кто скажет что это неудобно и им придется прежде чем получить реал пользоваться преобразованием в dint/udint.
Надеюсь Вы не считаете, что всё само собой конвертируется, ну реализовано в степе преобразование по стандарту, на него всёравно тратятся процессорные ресурсы, точно так же , как если бы Вы сами это делали

Sergey666
08.08.2015, 01:12
А кто сказал что DWORD не целочисленный тип ?
В Help КДС :
"
Integer Data Types

BYTE, WORD, DWORD, SINT, USINT, INT, UINT, DINT, and UDINT are all integer data types
Each of the different number types covers a different range of values. The following range limitations apply to the integer data types:

И чего полемику устраивать ?
А вот для ПЛК известных брэндов , работающих под языком LD есть мощнейший оператор MOV , который безусловно и безоглядно перенесет откуда нужно куда нужно , заменяя указатели Кодесис . Но никому в голову не приходит пенять кодесис за отсутствие "MOV" .
Организация памяти не та .

Yegor
08.08.2015, 08:59
А кто сказал что DWORD не целочисленный тип ?Стандарт сказал:

19423 19424

Арифметические операции не определены для битовых строк:

19425

Битовые операции не определены для числовых типов:

19426

FPavel
08.08.2015, 19:36
Добавлю терминов.
То, что требовалось ТС - typecast (приведение типов). Из целей безопасности кода typecast напрямую запрещён в CoDeSys. Искать лень, но это прописано где-то в начале изучения CoDeSys. Поэтому такие сложности - чтобы не случайно, а осмысленно выполнялось.

Yegor
09.08.2015, 19:20
Не соглашусь. Приведение типов разное бывает. Кодесисовские X_TO_Y это вполне себе явные приведения. Если с Си++ аналогию проводить, то это static_cast. А автору надо reinterpret_cast. Вот по-русски очень кратко: http://habrahabr.ru/post/106294/