PDA

Просмотр полной версии : преобразования



Василий Куц
22.06.2007, 11:31
здравствуйте.

каким образом можно преобразовать число от функции Len (она отдает в десятичном формате) в шестнадцатиричный и затем это значение в виде символов( т.е. 48h - это '48') передать в стринг?
у меня почему-то стринг пишется в десятичном формате тоже..... делал преобразование для получения Hex кода Ascii символов - такая же песня.

если можно - примерчик для обоих случаев на St.

Филоненко Владислав
22.06.2007, 12:20
Стандартные функции CoDeSys не дают возможности выводить строку в 16-ричном формате. Придется делать самому или поискать библиотечки на форумах - особенно в германии.

Василий Куц
22.06.2007, 12:21
понятно, владислав, а ссылочку дадите?

Филоненко Владислав
22.06.2007, 14:24
Для начала http://www.prolog-plc.ru/
Сам библиотеками не интересовался.

Игорь Петров
22.06.2007, 19:00
В лоб число в строку в десятичном виде совсем просто str1 := INT_TO_STRING(x);

В 16-ый формат так не получится. Я бы написал под это отдельную функцию для преобразования из байта в строку в 16-ом формате:

FUNCTION Byte_to_hex_str : STRING
VAR_INPUT
byIn : BYTE;
END_VAR
VAR CONSTANT
saHEX: ARRAY [0..15] OF STRING(1) := '0','1','2','3','4','5','6','7','8','9','A','B','C ','D','E','F';
END_VAR

Byte_to_hex_str := CONCAT(saHEX[SHR(byIn,4)],saHEX[byIn AND 16#0F]);

Есть очень интересная бесплатная биб-ка для систем автоматизации зданий и не только, вкл. всякие полезные штуки. Надо зайти на сайт OSCAT (http://www.oscat.de/) (он на немецком), в верху в меню жмем oscat.lib 1.6 fur CoDeSys – закачать.

Василий Куц
22.06.2007, 19:50
игорь, скачать, скачал - но там такого нет.... с немецким не дружу, но все же не нашел...

думаю сделать так: делить на 16 байт.... в общем - как в ручную...

за пример спасибо, буду смотреть, но не сейчас....

за день разобрал протокол Sms для сименсов S серии.... написал уже перекодировку - осталось только сообщение кодировать и собственно все - отправка будет работать...

Василий Куц
22.06.2007, 20:16
глянул ваш пример.... все же не удержался ;)
насколько я понимаю по тетрадам берем от входного байта сначало первую, вставляем символ из массива соответствующий данному полубайту (преобразование в стринг идет автоматом в этом случае получается?). затем с младшей так же.... Непойму зачем смещать на 4 бита влево.... Не проще домножить на 0xF0 ? Раз уж младшую тетраду так выделили?
Впрочем, Вам виднее ;)
Спасибо за пример, просто и со вкусом.

Игорь Петров
23.06.2007, 13:05
глянул ваш пример.... насколько я понимаю по тетрадам берем…

Берем старшую тетраду путем сдвига вправо на 4 (равносильно делению на 16#10). Старшая при этом обнуляется, получаем число 0…15, соответствующее первой позиции в 16-м представлении. Соответствующую ему цифру или букву берем из таблицы. Таблица является массивом строк (в каждой всего один символ), поэтому никаких дополнительных преобразований не нужно.

Затем в полученную строчу приклеиваем символ для младшей тетрады. Старшую при этом обнуляем посредством AND 16#0F.

Можно не использовать вспомогательный массив, а формировать код символа в лоб. Т.е. выделить тетраду и превратить в ASCII код. К сожалению, между цифрами и буквами A…F в табличке ASCII есть дырка. Поэтому придется ставить дополнительный IF Тетрада < 10 THEN прибавлять '0' ELSE 'A'. Короче, с массивом проще.


В биб-ке OSCAT 9 такого преобразования нет, там много чего другого, что может быть полезным. Документация к ней в pdf на немецком, но сама биб-ка спокойно открывается в CoDeSys командой Open... Тексты всех POU видны с комментариями на английском. Да и по текстам все достаточно понятно. Не обязательно ее использовать как цельную биб-ку, можно переделать под свои нужды.

Филоненко Владислав
25.06.2007, 09:09
пять копеек по оптимизации кода - на Arm архитектуре операция сдвига не стоит ровным счетом ничего, т.к. ею занимается спец. сопроцессор и операция сдвига может быть добавлена 3-м операндом к операциям сложения, вычитания, умножения и деления.

kanadchikov
28.02.2013, 14:12
Помогите решить проблему!
имеется массив 02 56 48 50 52 70 57 66 57 48 49 03 50 67 (в десятичном формате) необходимо его преобразовать в ascii и разбить на байты должно получиться примерно так . 80 24 F9 B9 01 . 2C

capzap
28.02.2013, 14:33
у Вас вроде в тексте точки в двух местах, а в массиве то два то три. Это с чем связано? А в остальном у вас как раз значения байт, переводите через указатель в строку и получаете требуемый результат

kanadchikov
28.02.2013, 15:10
capzap, Да это так сниффер преобразует. Все равно не могу догнать. Если можно, напишите пример. Меня интересует байтовый массив 56 48 50 52 70 57 66 57 48 49, начинаю преобразовывать 56>8; 48>0; в итоге первый интересующий меня байт должен быть равным 80, далее 50,52 второй байт должен быть равным 24 и так далее. Как то вот так!

capzap
28.02.2013, 15:19
у меня нет возможности пример полазать, не по памяти же исходник выложить по телефону. Сперва создаете указатель на строку размером с массив, присваиваете командой АДР имеющийся массив, дальше строке присваиваете значение указателя. И у Вас сразу появится нужная запись в строке.
Откройте в инете любую таблицу аскии, 48 соответствует нулю, 65 соответствует английской А

kanadchikov
01.03.2013, 12:44
capzap, спасибо за помощь, кое что получилось '$028024F9B901$032C'.

Yegor
01.03.2013, 14:15
Если «это так сниффер преобразует» и не принимать во внимание его мусор с долларами, то:
PROGRAM PLC_PRG
VAR CONSTANT
src: ARRAY[0..9] OF BYTE := 56, 48, 50, 52, 70, 57, 66, 57, 48, 49;
END_VAR
VAR
i: INT;
buf: STRING(5) := '16#00';
pBuf: POINTER TO ARRAY[0..4] OF BYTE;
result: ARRAY[0..4] OF BYTE;
END_VAR

pBuf := ADR(buf);

FOR i := 0 TO SIZEOF(result) - 1 DO
pBuf^[3] := src[i * 2];
pBuf^[4] := src[i * 2 + 1];
result[i] := STRING_TO_BYTE(buf);
END_FOR

http://images.devs-on.net/Image/PluCMzRQnrCkbOGA-CoDeSysUntitled.png

Gans
18.06.2019, 16:55
В лоб число в строку в десятичном виде совсем просто str1 := INT_TO_STRING(x);

В 16-ый формат так не получится. Я бы написал под это отдельную функцию для преобразования из байта в строку в 16-ом формате:

FUNCTION Byte_to_hex_str : STRING
VAR_INPUT
byIn : BYTE;
END_VAR
VAR CONSTANT
saHEX: ARRAY [0..15] OF STRING(1) := '0','1','2','3','4','5','6','7','8','9','A','B','C ','D','E','F';
END_VAR

Byte_to_hex_str := CONCAT(saHEX[SHR(byIn,4)],saHEX[byIn AND 16#0F]);

В строчке:
saHEX: ARRAY [0..15] OF STRING(1) := '0','1','2','3','4','5','6','7','8','9','A','B','C ','D','E','F';
ошибка, необходимо заменить на:
saHEX: ARRAY [0..15] OF STRING := '0','1','2','3','4','5','6','7','8','9','A','B','C ','D','E','F';

и + огромное СПАААСИИИБООО!!! ОЧЕНЬ помогло:-)

Gans
18.06.2019, 20:51
Здравствуйте, Цапзап.

а в чем ошибка то? Может далее в коде, но здесь то всё очевидно массив строк из одного символа, в Вашем случае, строка может разрастись до 80 символов но ни чем не отличается от первого варианта
В ходе компиляции у меня ругается на вышеуказанную строку, после внесения изменений программа заработала (CoDeSys 2.3)
Во вложении сам процесс ругательства.

Огромное спасибо за наводку. Померил размер занимаемой памяти
intTemp:=SIZEOF(saHEX);
и .... ппц.

Исправил строку на нижеследующую:
saHEX: ARRAY [0..15] OF STRING(2) := '0','1','2','3','4','5','6','7','8','9','A','B','C ','D','E','F';


Объем занимаемой памяти снизился с 1296 до 48 байт.

P. S. Век живи век учись :-)

Gans
21.06.2019, 18:53
Здравствуйте.

В лоб число в строку в десятичном виде совсем просто str1 := INT_TO_STRING(x);

В 16-ый формат так не получится. Я бы написал под это отдельную функцию для преобразования из байта в строку в 16-ом формате:

FUNCTION Byte_to_hex_str : STRING
VAR_INPUT
byIn : BYTE;
END_VAR
VAR CONSTANT
saHEX: ARRAY [0..15] OF STRING(1) := '0','1','2','3','4','5','6','7','8','9','A','B','C ','D','E','F';
END_VAR

Byte_to_hex_str := CONCAT(saHEX[SHR(byIn,4)],saHEX[byIn AND 16#0F]);

В строчке:
saHEX: ARRAY [0..15] OF STRING(1) := '0','1','2','3','4','5','6','7','8','9','A','B','C ','D','E','F';

Необходимо убрать лишний пробел заменить 'C ' на 'C'.
Нашел и ткнул носом Цапзап.

bort992
16.08.2019, 16:30
Совсем запутался. Задача такая, есть переменная STRING с номером абонента '9051458992', это значение нужно разбить пополам "90514" и "58992" в формате DWORD и отправить на панель Скады. Помогите пожалуйста

capzap
16.08.2019, 17:57
Совсем запутался. Задача такая, есть переменная STRING с номером абонента '9051458992', это значение нужно разбить пополам "90514" и "58992" в формате DWORD и отправить на панель Скады. Помогите пожалуйста
а запутались то в чем, какие функции использовали

petera
16.08.2019, 20:23
Совсем запутался. Задача такая, есть переменная STRING с номером абонента '9051458992', это значение нужно разбить пополам "90514" и "58992" в формате DWORD и отправить на панель Скады. Помогите пожалуйста


Функции из standart.lib
LEFT
RIGHT
и два раза STRING_TO_DWORD


PROGRAM PLC_PRG
VAR
strNumber: STRING(10);
loDWORD: DWORD;
hiDWORD: DWORD;
END_VAR
loDWORD:= STRING_TO_DWORD(RIGHT(strNumber, 5));
hiDWORD:= STRING_TO_DWORD(LEFT(strNumber, 5));

bort992
16.08.2019, 20:47
Petera, спасибо вам!!! А я искал в других библиотеках.