Помогите с переводом INT(НЕХ) в 2 BYTE.
- Войдите на сайт для отправки комментариев
Вс, 11/01/2015 - 02:29
Доброго времени суток, форумчане. Прошу помощи в проблеме.
Итак, есть десятичное число 8800, если его первести в шестнадцатеричное , то оно будет выглядеть так 2260. Суть вопроса: как мне перевести десятичное в шестнадцатеричное, разложить шестнадцатеричное число 2260 на 22 и 60 и сделать из низ два байта вида 0x22 и 0x60. Так же необходима обратная операция: получаем два байта 0x25 и 0x4E, собираем в шестанцатеричное 254E и переводим в десятичное 9550.
Заранее спасибо.
сдвиг не спасет отца русской демократии?
Я не понял. Вам необходимо int перевести в строку в вид HEX ?
или
Правильней былобы так:
Доброго времени суток, форумчане. Прошу помощи в проблеме.
Итак, есть десятичное число 8800, если его первести в шестнадцатеричное , то оно будет выглядеть так 2260. Суть вопроса: как мне перевести десятичное в шестнадцатеричное, разложить шестнадцатеричное число 2260 на 22 и 60 и сделать из низ два байта вида 0x22 и 0x60. Так же необходима обратная операция: получаем два байта 0x25 и 0x4E, собираем в шестанцатеричное 254E и переводим в десятичное 9550.
Заранее спасибо.
мутно написали, но если правильно понял, вам нужно 16-ти битное число типа int разбить на два 8-ми битных
десятичное число есть только в вашем предствлении, все числа в МК представлены в виде двоичных чисел
вот несколько вариантов, все они архитектурно зависимы (т.е. на других МК могут работать неверно если там другая последовательность байт)
Вариант №1 архитектурно независим. :)
Правильней не давать указатель на слово а использовать union - это гарантирует вас от архитектурнозависимых неприятностей (однажды натыкался, правда на ARM)
ну и если использовать указатель, то правильней было бы объявлять переменную int. А на нее уже указатель (uint8_t*). Потому как int больше и компилятор резервирует память для большей переменной учитывая архитектурные возможности. Короче каждый int может стать двумя uint8_t, но не каждые 2 uint8_t могут стать int.
Плюс здесь напрашивается беззнаковый int.
Вариант №1 архитектурно независим. :)
возможно. Разве компилятор гарантирует очередность бит в операциях сдвига вне зависимости от платформы?
напрашивается uin16_t, но в описанном применение int ничему не вредит применительно к AVR. Ибо int на AVR это двухбайтное число. Так как мы знаковые операции не используем, то int или uint16_t нет разницы
Как угодно, но разница есть, 40000 как записать в int?
Разумеется это все фантазии, ТС про это ни слова не сказал.
Правильней не давать указатель на слово а использовать union - это гарантирует вас от архитектурнозависимых неприятностей (однажды натыкался, правда на ARM)
union это еще один вариант:
напишите лучше пример кода, а то ход мыслей не понятен, здесь очень важны детали
я исхожу из постановки задачи. Дальше уже либо фантазии отвечающих либо отдельное обсуждение о корректности постановки задачи
ну если тупо есть желание записать 40000 в int ))) то ниже просто теоретический вариант лишенный практического смысла
Опишу более подробно: в FM-трансмиттере (VMR6512) частота 88,00 МГц (8800 - десятичное значение, 2260 - шестнадцатеричное значение) задается командой из трех байт b1, b2, b3, где:
b1 = 0x01 - команда на установку частоты.
b2 = 0x22 - значение частоты.
b3 = 0x60 - значение частоты.
Байты b2 и b3 - 2 части целого 2260.
Частота может задаваться от 8800 до 10800 (88,00 МГц - 108,00 МГц) с шагом 0,10 МГц.
Заводим переменную int frec = 8800. Нужно ее преобразовать в byte b2 = 0x22 и byte b3 = 0x60.
Или наоборот: получаем два байта byte b2 = 0x22 и byte b3 = 0x60. Нужно преобразовать в int frec = 8800.
Все очень просто:
Вы повторили мой пример выше
но вопрос был не про union. А не понял хода мыслей касательно применения указателей
2Axill
в Вашем примере №2 Вы по адресу массива uint8_t записываете int это не во всех платформах проходит. Кпримеру в ARM int выровнян на 4 байта а short на 2, char на 1. таким образом если компилятор выделит память для uint8_t c нечетного адреса, то произойдет ошибка. Так как uint16_t нельзя записать в нечетный адрес. По этому я и братил внимание что былобы правильней так:
хотя в данном контексте я думаю это не принципиально.
sva1509 я специально сделал оговорку про привязку к платформе чтобы не затевать никаких обсуждения
но вы не удержались ) нет смысла обсуждать в этой теме ARM
ну если тупо есть желание записать 40000 в int ))) то ниже просто теоретический вариант лишенный практического смысла
Записать то можно, но использовать без гемора не получится.
Все, ТС сказал про частоту, значит нужен беззнаковый.
Ок, останемся при своих.
да я согласен) если понимаешь что делаешь можно делать как угодно используя какие угодно типы. Но это плохая практика, которая ведет к ошибкам. Вот и с типом int - в диапазоне значений частоты трансивера нет разницы использовать int или unsigned int. Но грамотно все же использовать unsigned ибо задача в принципе не подразумевает отрицательных значений
Вариант №1 архитектурно независим. :)
возможно. Разве компилятор гарантирует очередность бит в операциях сдвига вне зависимости от платформы?
Порядок бит одинаковый для всех платформ (из тех что я встречал) - старший слева, младший справа.
Разный у них порядок байт - в слове, в двойном слове и т.д. Но правильно собирать/разбирать слова на байты это не мешает.
Заводим переменную int frec = 8800. Нужно ее преобразовать в byte b2 = 0x22 и byte b3 = 0x60.
Или наоборот: получаем два байта byte b2 = 0x22 и byte b3 = 0x60. Нужно преобразовать в int frec = 8800.
Ну так, всё же правильно написано, осталось только перевести на С. :)
Распаковка:
И упаковка:
Спасибо всем, кто откликнулся. Задача разрешилась. Век живи, век учись. )))
похожая проблемма ... читаю цвет из файла, он в 10-чной. а установка цвета в mcufriend в 16-ричной. не могу перевести. цвет 16 бит ... тоесть к примеру из 48664 получить 0xBE18. попробовал последний варик ... не менятеся ничего ....
похожая проблемма ... читаю цвет из файла, он в 10-чной. а установка цвета в mcufriend в 16-ричной. не могу перевести. цвет 16 бит ... тоесть к примеру из 48664 получить 0xBE18. попробовал последний варик ... не менятеся ничего ....
Может так получиться:
Serial.print(B, HEX);
Правильней былобы так:
спасибо за информацию. ...век учись. записал под карандаш
решено . спасибо
Подниму тему, чтобы не плодить новую.
А как разобрать знаковый int на байты? И как потом собрать обратно, чтобы знак опять же остался?
Можно конечно банально, сначала прибавить 32768, получив unsigned int, а потом уже в байты, но может есть более изящное решение?
может есть более изящное решение?
варианты:
а) описать как унион
б) поменять тип указателя с int* на byte*
Круто, union будет и со знаком правильно работать, ничего придумывать не надо?
Круто, union будет и со знаком правильно работать, ничего придумывать не надо?
он вообще не будет никак с ним "работать", унион просто дает доступ к каждому байту отдельно, на содержание байтов ему фиолетово.
Хотя я вот так обычно делаю, без всяких унионов:
Круто, union будет и со знаком правильно работать, ничего придумывать не надо?
он вообще не будет никак с ним "работать", унион просто дает доступ к каждому байту отдельно, на содержание байтов ему фиолетово.
Хотя я вот так обычно делаю, без всяких унионов:
спасибо, учту
спасибо, учту
если не понимаешь этой записи - делай через унион, меньше вероятности ошибок
С ptr как то не экономненько.)))
С ptr как то не экономненько.)))
два байта со стека жалко? :)
Да уж.) Давеча писал программулину для pic10f200 - так у него стек (правда железный) аж на 2 байта! Да и с программным в 16-ти байтах сильно не развернёшься.)
Да уж.) Давеча писал программулину для pic10f200 - так у него стек (правда железный) аж на 2 байта! Да и с программным в 16-ти байтах сильно не развернёшься.)
Писал для контроллеров на PIC16F84 и даже не задумывался о глубине стека, девайсы отработали годы без нареканий (в вязальных машинках), судьба )))
Всё норм. Это ж простые ус-ва, стеку то куда деваться. А компилятор просчитывает глубину и выдаёт предупреждение.
Удивительно то, что в 10f можно программно выдавать на выход системную частоту. И это всё в SOT23!