|
|
  |
Помогите разобраться с преобразованиями |
|
|
|
Oct 17 2009, 22:37
|

I WANT TO BELIEVE
     
Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751

|
Цитата Чтобы избежать неоднозначности я использовал конкретный тип uint16_t, который соответствует 16-и битному unsigned int. Я вот тут книгу читал: Цитата 46. Не пользуйтесь именами из стандарта ANSI Cи Идентификаторы, начинающиеся с символа подчеркивания, и имена типов, оканчивающиеся на _t, были зарезервированы стандартом ANSI Cи для использования разработчиками компиляторов. Не используйте эти символы. Информация устарела? (книга старая)
--------------------
The truth is out there...
|
|
|
|
|
Oct 18 2009, 00:57
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(sigmaN @ Oct 18 2009, 04:37)  Я вот тут книгу читал:
Информация устарела? (книга старая) Дык вы не просто читайте, а еще и в смысл прочитанного вникайте  Написано же Цитата Не используйте эти символы. Потому что эти типы описаны в стандарте С99 (раздел 7.18 Integer types) и являются стандартными. Для использования их достаточно подключить хедер stdint.h.
|
|
|
|
|
Oct 18 2009, 06:58
|

неотягощённый злом
     
Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643

|
Цитата(Neytrino @ Oct 17 2009, 23:26)  Простите за глупый вопрос, но как выделить полубайт? Код uint8_t x = 0x12;
uint8_t bcd_l = x & 0x0f; // младший (единицы) uint8_t bcd_h = x>>4; // старший (десятки) Вот так. После чего будет: bcd_l = 2, а bcd_h = 1.
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Oct 18 2009, 11:15
|

I WANT TO BELIEVE
     
Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751

|
Цитата Дык вы не просто читайте, а еще и в смысл прочитанного вникайте Оооо, дошло наконец! Автор имел ввиду не использовать - т.е. не определять своих имен, оканчивающихся на "_t" или начинающихся с "_"  Ну а по делу: Ув. топикстартер, мне кажется Вам нужно заново перечитать все ответы и ЧЕТКО сформулировать проблему, которая сейчас преграждает вам путь к победе. Прямо не стесняясь, от начала и до конца. Что уже сделано, что не понятно, что уже хоть как-то работает и как оно работает. И тогда, возможно, кто-нибудь вам поможет. Возьмем хотя-бы этот совет rezident: Цитата Накладыванием маски и сдвигами. С этим всё ясно? Потому что может так случиться, что смысл Вами до конца был не понят, а от того, что дважды спросить одно и то-же бывает неудобно - вы можете остановиться на пол пути. P.S. ну это я для примера взял именно этот совет, возможно тут какраз Вам всё понятно.
--------------------
The truth is out there...
|
|
|
|
|
Oct 18 2009, 15:44
|
Участник

Группа: Участник
Сообщений: 53
Регистрация: 26-02-09
Пользователь №: 45 406

|
Цитата(sigmaN @ Oct 18 2009, 15:15)  Возьмем хотя-бы этот совет rezident: С этим всё ясно? Потому что может так случиться, что смысл Вами до конца был не понят, а от того, что дважды спросить одно и то-же бывает неудобно - вы можете остановиться на пол пути. Честно говоря, Вы правы, я толком не могу понять, что значит наложить маску... я так понимаю, что сдвигая часть бит, маска как бы восполняет недостающие биты, причем в нужном мне порядке, верно? например 00001111 сдвигаем влево на 4 бита - получаем 11110000 и добавляем маску 00001111, то получится 11111111 верно?
|
|
|
|
|
Oct 18 2009, 16:25
|

I WANT TO BELIEVE
     
Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751

|
Отлично. Начнем. Предположим, из порта(или откуда-то ещё) мы считали значение 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. Что для этого нужно? Какая маска и какая логическая операция должна быть использована?
--------------------
The truth is out there...
|
|
|
|
|
Oct 18 2009, 17:02
|
Участник

Группа: Участник
Сообщений: 53
Регистрация: 26-02-09
Пользователь №: 45 406

|
Кажется до меня дошло!!!!!!!!! Сейчас попробую!!!
|
|
|
|
|
Oct 18 2009, 19:41
|
Участник

Группа: Участник
Сообщений: 53
Регистрация: 26-02-09
Пользователь №: 45 406

|
CODE int bcd2dec (int bcd) { int x,y; x = (bcd & 0xf); y = ((bcd & 0xf0)>>4)*10; return x+y; }
Вот что получилось! Отлично работает! А вот с обратным преобразованием как-то не получилось, вот код CODE int dec2bcd (int dec) { int w,x,y; while ( dec >= 10) { dec -=10; w++; } x = dec; y = (w<<4); return y+x; } Что я не так сделал? Я хотя бы правильным путем пошел?
|
|
|
|
|
Oct 18 2009, 20:02
|
    
Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731

|
Цитата(Neytrino @ Oct 18 2009, 23:41)  ... Что я не так сделал? Не прочитали статью в википедии, рекомендованную Вам на первой странице треда: Цитата ... При сложении двоично-десятичных чисел каждый раз, когда происходит перенос бита в старший полубайт, необходимо к полубайту, от которого произошёл перенос, добавить корректирующее значение 0110. При сложении двоично-десятичных чисел каждый раз, когда встречается недопустимая для полубайта комбинация, необходимо к каждой недопустимой комбинации добавить корректирующее значение 0110 с разрешением переноса в старшие полубайты. При вычитании двоично-десятичных чисел, для каждого полубайта, получившего заём из старшего полубайта, необходимо провести коррекцию, отняв значение 0110
|
|
|
|
|
Oct 19 2009, 10:16
|
Участник

Группа: Участник
Сообщений: 53
Регистрация: 26-02-09
Пользователь №: 45 406

|
Цитата(xemul @ Oct 19 2009, 00:02)  Не прочитали статью в википедии, рекомендованную Вам на первой странице треда: А можно, если конечно не сложно, разжевать это мне, я что-то не совсем понял данной статьи, если быть точнее как производить коррекцию и как вычислить в функции те самые недопустимые комбинации
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|