rezident 0 17 октября, 2009 Опубликовано 17 октября, 2009 · Жалоба Простите за глупый вопрос, но как выделить полубайт?Накладыванием маски и сдвигами. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sigmaN 0 17 октября, 2009 Опубликовано 17 октября, 2009 · Жалоба Чтобы избежать неоднозначности я использовал конкретный тип uint16_t, который соответствует 16-и битному unsigned int.Я вот тут книгу читал: 46. Не пользуйтесь именами из стандарта ANSI Cи Идентификаторы, начинающиеся с символа подчеркивания, и имена типов, оканчивающиеся на _t, были зарезервированы стандартом ANSI Cи для использования разработчиками компиляторов. Не используйте эти символы. Информация устарела? (книга старая) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rezident 0 18 октября, 2009 Опубликовано 18 октября, 2009 · Жалоба Я вот тут книгу читал: Информация устарела? (книга старая) Дык вы не просто читайте, а еще и в смысл прочитанного вникайте ;) Написано же Не используйте эти символы. Потому что эти типы описаны в стандарте С99 (раздел 7.18 Integer types) и являются стандартными. Для использования их достаточно подключить хедер stdint.h. :laughing: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 18 октября, 2009 Опубликовано 18 октября, 2009 · Жалоба Простите за глупый вопрос, но как выделить полубайт? uint8_t x = 0x12; uint8_t bcd_l = x & 0x0f; // младший (единицы) uint8_t bcd_h = x>>4; // старший (десятки) Вот так. После чего будет: bcd_l = 2, а bcd_h = 1. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Rst7 5 18 октября, 2009 Опубликовано 18 октября, 2009 · Жалоба Ну мне надо вывести значения в десятичной системе, которые выдает мне DS1307 Куда вывести? На дисплей? В символьном виде? Если да - то я Вам еще вот в этом посте написал. Что не ясно? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sigmaN 0 18 октября, 2009 Опубликовано 18 октября, 2009 · Жалоба Дык вы не просто читайте, а еще и в смысл прочитанного вникайтеОооо, дошло наконец! Автор имел ввиду не использовать - т.е. не определять своих имен, оканчивающихся на "_t" или начинающихся с "_" :) Ну а по делу: Ув. топикстартер, мне кажется Вам нужно заново перечитать все ответы и ЧЕТКО сформулировать проблему, которая сейчас преграждает вам путь к победе. Прямо не стесняясь, от начала и до конца. Что уже сделано, что не понятно, что уже хоть как-то работает и как оно работает. И тогда, возможно, кто-нибудь вам поможет. Возьмем хотя-бы этот совет rezident: Накладыванием маски и сдвигами.С этим всё ясно? Потому что может так случиться, что смысл Вами до конца был не понят, а от того, что дважды спросить одно и то-же бывает неудобно - вы можете остановиться на пол пути. P.S. ну это я для примера взял именно этот совет, возможно тут какраз Вам всё понятно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Neytrino 0 18 октября, 2009 Опубликовано 18 октября, 2009 · Жалоба Возьмем хотя-бы этот совет rezident: С этим всё ясно? Потому что может так случиться, что смысл Вами до конца был не понят, а от того, что дважды спросить одно и то-же бывает неудобно - вы можете остановиться на пол пути. Честно говоря, Вы правы, я толком не могу понять, что значит наложить маску... я так понимаю, что сдвигая часть бит, маска как бы восполняет недостающие биты, причем в нужном мне порядке, верно? например 00001111 сдвигаем влево на 4 бита - получаем 11110000 и добавляем маску 00001111, то получится 11111111 верно? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sigmaN 0 18 октября, 2009 Опубликовано 18 октября, 2009 · Жалоба Отлично. Начнем. Предположим, из порта(или откуда-то ещё) мы считали значение 01110011 и нам нужен младший полу-байт(т.е. 4бита) Понятно, что правильный ответ = 0011, но как заставить машину отбросить 4старших байта и оставить 4младших. Тут нап придется вспомнить логические операции AND, OR, XOR, NOT.. и хотя-бы приблизительно помнить таблицу истинности для этих операций. Так вот, поскольку процессор может выполнять эти операции за один такт - то можно достаточно эффективно получить интересующие нас 4бита. Для этого я предлагаю воспользоваться логической операцией AND(лог. умножение). Так вот, то значение, НА КОТОРОЕ мы будем умножать значение переменной, считанной с порта - мы будем называть маской. Так вот. По таблице истинности лог операции AND видно, что в ней "всегда побеждает" ноль(это я так запоминал в детстве). Но сейчас мы можем понять, что умножение на 0 даёт 0:) Чтобы выделить младшие 4 бита я выберу маску 00001111. Посмотрим что это нам даст: 01110011 AND 00001111 equal 00000011 Верхняя строка - исходное значение. Ниже - маска. В самом низу результат. Как видим, операции эти потому и называются bitwise, потому что выполняются над битами операндов Почему rezident упомянул про сдвиг? Рассмотрим случай, когда нужно получить значение старшего полубайта. Маска будет, соответственно 11110000. Имеем: 01110011 AND 11110000 equal 01110000 Т.е. младший полубайт мы как-бы обнулили и осталось сдвинуть всё это дело на 4 бита вправо. 01110000 >> 4 == 00000111 Это я привел пример, когда размер переменной == 8бит, а нам нужно 4. Но бывает так, что переменная 16бит, а нам нужно из них, скажем, биты с 10 по 13. Тогда выбираем маску, с установленными в 1 битами с 10 по 13, а остальные 0. Маска, естественно, должна быть тоже 16битная. Но потом, чтобы значение этих байтов можно было применить как значение(к примеру в операции сравнения) нам нужно подвинуть их так, чтобы бит, стоящий на позиции 10 занял позицию 0. Т.е. нужен сдвиг на 10 вправо. Для наглядности, предположим что в документации на МК было указано, что биты с 10 по 13 в регистре таком-то, показывают сколько байтов сейчас можно считать из буфера FIFO. Так вот после описанных мною операций мы получим число байт в буфере :) Ну и т.д. Для закрепления материала задам задачку: нужно УСТАНОВИТЬ бит 5 какого-то(8ми битного) регистра в 0. Что для этого нужно? Какая маска и какая логическая операция должна быть использована? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Neytrino 0 18 октября, 2009 Опубликовано 18 октября, 2009 · Жалоба Кажется до меня дошло!!!!!!!!! Сейчас попробую!!! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Neytrino 0 18 октября, 2009 Опубликовано 18 октября, 2009 · Жалоба int bcd2dec (int bcd) { int x,y; x = (bcd & 0xf); y = ((bcd & 0xf0)>>4)*10; return x+y; } Вот что получилось! Отлично работает! А вот с обратным преобразованием как-то не получилось, вот код int dec2bcd (int dec) { int w,x,y; while ( dec >= 10) { dec -=10; w++; } x = dec; y = (w<<4); return y+x; } Что я не так сделал? Я хотя бы правильным путем пошел? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xemul 0 18 октября, 2009 Опубликовано 18 октября, 2009 · Жалоба ... Что я не так сделал? Не прочитали статью в википедии, рекомендованную Вам на первой странице треда: ... При сложении двоично-десятичных чисел каждый раз, когда происходит перенос бита в старший полубайт, необходимо к полубайту, от которого произошёл перенос, добавить корректирующее значение 0110. При сложении двоично-десятичных чисел каждый раз, когда встречается недопустимая для полубайта комбинация, необходимо к каждой недопустимой комбинации добавить корректирующее значение 0110 с разрешением переноса в старшие полубайты. При вычитании двоично-десятичных чисел, для каждого полубайта, получившего заём из старшего полубайта, необходимо провести коррекцию, отняв значение 0110 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
baralgin 0 18 октября, 2009 Опубликовано 18 октября, 2009 · Жалоба Neytrino В функции dec2bcd в глаза бросается неинициализированная (нулём) переменная(w) . На вид правильно. Но для надёжности стоит различать ещё "+" от "|" . Если уйти от "оптимизации", то функцию можно переписать одной строчкой. на предыдущей странице rezident давал пример того же самого только немного красивее. rezident Неужели библиотечные "целое/целое" и "%" массивнее самописных? Ведь алгоритм прозрачен и сделать по другому сложно. Разве что вызовы вместо "инлайна" ... Или есть ещё что-то, что я не учитываю? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rezident 0 19 октября, 2009 Опубликовано 19 октября, 2009 · Жалоба rezident Неужели библиотечные "целое/целое" и "%" массивнее самописных?Я этого не утверждал. Просто бывают случаи когда целесообразнее вообще отказаться от применения умножения (хотя бы в подобном BCD-преобразовании), которое вызывает увеличение кода на лишние сотни байт линковкой соответствующей библиотеки. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Neytrino 0 19 октября, 2009 Опубликовано 19 октября, 2009 · Жалоба Не прочитали статью в википедии, рекомендованную Вам на первой странице треда: А можно, если конечно не сложно, разжевать это мне, я что-то не совсем понял данной статьи, если быть точнее как производить коррекцию и как вычислить в функции те самые недопустимые комбинации Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rezident 0 19 октября, 2009 Опубликовано 19 октября, 2009 · Жалоба А можно, если конечно не сложно, разжевать это мне, я что-то не совсем понял данной статьи, если быть точнее как производить коррекцию и как вычислить в функции те самые недопустимые комбинации Проще всего делать bcd-преобразование непосредственно перед выводом на экран или сразу после ввода значения (если есть ввод). А вычисления делать в обычном бинарном формате, не заморачиваясь десятичной коррекцией. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться