Конвертирование HEX в BIN
- Войдите на сайт для отправки комментариев
Здравствуйте,
Заранее прошу прощения, если ответы на мои вопросы покажутся очевидными, но помощь мне не помешает ))
У меня есть входящие данные в виде наборов шестнадцатиричных данных.
Мне нужно разобрать входящие данные на части, преобразовать каждую из этих частей в бинарную форму и дальнейшие манипуляции выполнять уже с битами.
Например, есть такое входящее значение: 8D4840D620.
char receivedChars[] = "8D4840D620"; //char array, поскольку данные приходят из серийного порта
8D4840D620 мне нужно разделить на отдельные части (размер этих частей известен заранее условиями задачи, поэтому длину этих частей угадывать не надо):
8D 4840D6 20
Это я делаю так:
char dc_char[3]; // два реальных байта + 1 завершающий \0 dc_char[0] = receivedChars[0]; // сюда должно попасть 8 dc_char[1] = receivedChars[1]; // сюда должно попасть D dc_char[2] = "\0"; // сюда должно попасть \0
1) превратить ее в бинарную форму, чтобы получилось 10001101;
2) из полученной бинарной формы (10001101) взять первые 5 бит (10001) и превратить их в десятичную форму (должно получиться 17).
Но вот тут начинаются какие-то неясности.
Когда я пробую вывести в последовательный порт содержимое массива, то получаю вот что:
Serial.println("dc_char: ");
Serial.println(dc_char[0], BIN); // -> 111000 (хотя 8 должна была превратиться в 1000)
Serial.println(dc_char[1], BIN); // -> 1000100 (хотя D должна была превратиться в 1101)
Serial.println(dc_char[2], BIN); // -> 110 (\0 должен был превратиться в 0000)Ну то есть я не получаю из кусков бинарной формы нужного мне выражения. Как все это правильно сделать? Понимаю, что вопросы задаю от полного невежества, но все же...
Заранее благодарю за ответы.
судя по коду, у тебя
receivedChars[0] = "8D4840D620";
должно быть
https://www.arduino.cc/en/Reference.StringToCharArray
Нет, тут все нормально:
Serial.println("receivedChars[0]: " + String(receivedChars[0])); // -> 8 Serial.println("receivedChars[1]: " + String(receivedChars[1])); // -> DТогда покажи функцию конвертации
Так никакой конвертации и нет, я просто распихиваю исходное значение по массивам, а потом с нужными элементами пытаюсь сделать вывод в серийный порт командой
Я даже проверил и в массив назначения попадают верные значения:
Но вот с самим преобразованием в бинарную форму
что-то не то. И не пойму что. Результаты вот такие:
Кому это она так задолжала?
там был символ '8' - код его 0x38 или в десятичном 56. В двоичном это бутет как раз 111000 - именно то, что Вы и видите. Всё правильно работает.
Если Вы хотите, чтобы там именно числа сидели, так при присваивании нужно было вычитать '0' для цифр и и вычитать ('A'-10) для букв.
ЕвгенийП,
Для самоконтроля я пользуюсь таким конвертером: https://www.binaryhexconverter.com/hex-to-binary-converter
И именно там я вижу другие значения, не 111000, а 1000 для восьмерки в HEX.
И именно 1000 мне нужна для '8' и 1101 для 'D'.
Покажи, пожалуйста, как делать вычитание '0' для цифр и ('A'-10) для букв.
Покажи, пожалуйста, как делать вычитание '0' для цифр и ('A'-10) для букв.
Мы уже на ты?
Вот у Вас написано
Так вот туда ни хрена не 8 попадает, а '8'. Чтобы туда попадала именно 8, надо писать
Вот тогда там будет 8.
Если же в receivedChars[0] сидит не знак цифры, а знак от 'A" до 'F', то вычитать надо не '0', как я написал, а ('A' - 10). Тогда в случае A там окажется 10, в случае B - там окажется 11 и т.п.
Т.е. строку dc_char[0] = receivedChars[0] - '0'; надо переписать так, чтобы "если в receivedChars[0] цифра - вычиталось '0', а если символ 'A'-'F', то чтобы вычиталось ('A'-10).
Но это уже сами. Для цифр я Вам написал, а на общий случй сами доработайте.
Penni,
Спасибо, теперь я вижу значения, которые мне нужны. Постараюсь понять ваш пример ))
Спасибо!
P.S. Понял, отличная универсальная функция!
Мы уже на ты?
Простите, пожалуйста )) Оплошал я )))
dc_char[1] = receivedChars[1] - ('A'-10);dc_char[1] = receivedChars[1] - ('A'-10);
Ну, нет, здесь Вы уже как бы знаете, что там буква. А откуда? Надо проверить что там и соотвественно себя вести.
Нужно что-то вроде
dc_char[1] = receivedChars[1] - ((receivedChars[1] > '9') ? ('A'-10) : '0');Только здесь не проверяется, что в строке именн цифры и буквы от 'A' до 'F'. Считается, что так и есть.
llaabbss, а чем вообще вызвана надобность класть входящие данные в char?
dimax,
Такая необходимость возникла вследствие того, что данные поступают по серийному порту и для дальнейших преобразований в бинарную форму удобнее всего оказалось сделать через char.
Если есть идеи как сделать проще - буду благодарен ))
Конечно есть. Если она передаются в двоичном виде, то так и принимать. А если и передаются в текстовом, то переделать передачц и передавать в двоичном.
Друзья,
А вот еще вопрос: если у меня есть бинарное значение в виде 11101000, как мне "убрать" первые 4 бита?
Чтобы осталось только 1000? Что-то типа отрезать. Но в данном случае нужно обнулять.
Я так понимаю, что это сделать нужно при помощи bitClear(), bitWrite(). Или есть еще более красивое решение?
x= 11101000 & 0x0F;
__Alexander
Спасибо за идею, а если есть 12 бит, как поступить аналогичным образом с произвольным количеством первых бит?
llaabbss, может вы уже достаточно готовы что бы таки изучить битовые операции? :) У меня в своё время ушло полдня. А пользы -на всю оставшуюся жизнь.
может вы уже достаточно готовы
Боюсь, что нет. Ибо Вы должны подсказать. Иначе, зачем форум?
Ребята, спасибо!
За ссылку вообще отдельное спасибо! Я пытался найти вменяемые статьи даже на английском. Уже полез в учебники по С.
Так что всех благодарю, обязательно все прочту.
Поздравляю всех с наступающими праздниками ))
P.S. Шикарная ссылка. Сразу нашел ответ на свой вопрос:
видимо, потому что это неправильно. Пух, читай внимательно!!!
Ребята, нужна ваша помощь еще раз ))
Где я могу найти информацию какой длины HEX данных какая из Ардуин может конвертировать в бинарную форму?
Вопрос связан с тем, что когда у меня есть HEX данные, например, C382D690C8AC, то при попытке посмотреть его эквивалент в бинарной форме через серийный порт на УНО я получаю 1111111111111111111111111111111. Это безусловно неправильно. Мне пришлось делить исходный HEX на две части, чтобы правильно его обработать (в этом случае я вижу корректное отображение в строке последовательного порта).
Связано ли появление 1111111111111111111111111111111 с тем, что у Ардуино УНО просто нет мощностей для конвертации такой длины HEX данных, либо это ограничение последовательного порта (а в оперативке содержится верное значение в бинарной форме)?
И справится ли с этой строкой ESP-07 лучше, чем Ардуино?
Это к вам llaabbss У вас данные в виде char строки в которой HEX. Напишите функцию конвертацию из char строки в которой HEX в char строку в которой BIN. И не парьте форумчанам голову.
То есть как бы все логично, но я где-то тупонул? :)
То есть как бы все логично, но я где-то тупонул? :)
какой длины HEX данных какая из Ардуин может конвертировать в бинарную форму?
Практически любой
Связано ли появление 1111111111111111111111111111111 с тем, что у Ардуино УНО просто нет мощностей для конвертации такой длины HEX данных,
Мощностей не хватает не у УНО, а у программиста.
Ну, да, да, 32 бита максимум для long, unsigned long и float.
C382D690C8AC - это 48 бит. Поэтому приходится делить на части.
Отсюда и втрой вывод: ESP на ардуиновском IDE будет испытывать те же проблемы. Разве что использовать другое IDE, у которого возможностей больше.
Спасибо за то, что ткнули в очевидные ответы ))
Разве что использовать другое IDE, у которого возможностей больше.
Да, нет же. Надо использовать не другое IDE, а другого программиста.
Если уж Вам так жмёт long, почему не использовать long long? Или просто из строки в строку конвертировать.
В общем надо прокачивать программиста, а не IDE.
Это так что ли должно выглядеть?
Это так что ли должно выглядеть?
Конечно, нет. Посмотрите какого типа данные возвращает strtol и подумайте.
И это, ... читайте, учитесь, я же Вам говорю, Вам надо прокачать программиста, а не IDE!
И не гонитесь за готовой халявой! Я Вам в постах 5 и 8 показал как это сделать для строки ЛЮБОЙ длины (хоть двести символов). Но там работать надо, и Вы уцепились за халявную функцию strtol, которая делает всё за Вас, да вот беда - она ограничена типом long - халява не прошла.
void hexToBin(char * destptr, const char * srcptr ) { /*здесь вы напишите свой код конвертирования*/ }Ну и последний вопрос (уж простите, но я вас решил добить :) ).
У меня есть 20 битовое выражение числа типа unsigned int, которое я уже получил:
Мне нужно в нем заменить самые старшие биты с номерами 18 и 19.
Я стараюсь это выполнить так:
Но ничего не происходит. Так я могу менять биты только до 17 номера, а вот выше - нет.
Где мне хотя бы начать искать решение проблемы? И можно ли каким-то образом резать 32 битные числа по 16 (или по 8) бит, а потом склеивать их обратно без искажения цифры?
Где мне хотя бы начать искать решение проблемы?
В учебниках.
Заменитев Ваше выражении обе единицы на 1ul, И больше, пока не прочтёте учебник - не обращайтесь.
И можно ли каким-то образом резать 32 битные числа по 16 (или по 8) бит, а потом склеивать их обратно без искажения цифры?
Можно всё. Если уметь.
О, вы все просто БОГИ программирования!
Спасибо огромное, что выручили. Я впервые сталкиваюсь с настолько сложной для себя задачей, поэтому решил обратиться за специализированной помощью к профи. Спасибо, что помогли и не оставили.
Не обижайтесь, что такие как я задают подобные вопросы. Это происходит не из-за того, что таким как мне просто лень что-то читать. Не говорю за всех, но мне даже было непонятно где это все начать читать. Да, есть множество ссылок, куда вы меня можете отправить поднимать мою грамотность, но фактор времени тоже имеет свою цену. В конце концов если бы профи отвечали на вопросы профи, то им стало бы очень скучно ))
Безусловно, я все же освою это все, просто сейчас для решения конкретной задачи мне понадобилась быстрая квалифицированная помощь. И я благодарен всем за участие и практические подсказки.
Еще раз всех с наступающими праздниками и всех благ ))
И можно ли каким-то образом резать 32 битные числа по 16 (или по 8) бит, а потом склеивать их обратно без искажения цифры?
и обратно:
Это происходит не из-за того, что таким как мне просто лень что-то читать. Не говорю за всех, но мне даже было непонятно где это все начать читать. Да, есть множество ссылок, куда вы меня можете отправить поднимать мою грамотность, но фактор времени тоже имеет свою цену. В конце концов если бы профи отвечали на вопросы профи, то им стало бы очень скучно ))
Какие знакомые отговорки :)
Безусловно, я все же освою это все, просто сейчас для решения конкретной задачи мне понадобилась быстрая квалифицированная помощь.
Какие знакомые обещания :)
А это не знакомые слова? )))))))))))))))
О, вы все просто БОГИ программирования!
А это не знакомые слова? )))))))))))))))
О, вы все просто БОГИ программирования!
Богов тут нет, знаешь ли. Тут одни титаны :)))
В общем, с Новым годом, боги / титаны / высший разум / другие персонажи всех верований, мифов и легенд )))))))))))))
Да без проблем! Берете 4х байтовую переменную, первые два байта записываете в первую 2х байтовую переменную, вторые два байта - во вторую. А по 8бит - так еще проще:
Можно ещё классичнее:
или даже так:
или даже так:
Вы уже начали отмечать? Какой часовой пояс?