реклама на сайте
подробности

 
 
3 страниц V  < 1 2 3 >  
Reply to this topicStart new topic
> Помогите разобраться с преобразованиями
rezident
сообщение Oct 17 2009, 19:33
Сообщение #16


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(Neytrino @ Oct 18 2009, 01:26) *
Простите за глупый вопрос, но как выделить полубайт?
Накладыванием маски и сдвигами.
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Oct 17 2009, 22:37
Сообщение #17


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...
Go to the top of the page
 
+Quote Post
rezident
сообщение Oct 18 2009, 00:57
Сообщение #18


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(sigmaN @ Oct 18 2009, 04:37) *
Я вот тут книгу читал:

Информация устарела? (книга старая)
Дык вы не просто читайте, а еще и в смысл прочитанного вникайте wink.gif
Написано же
Цитата
Не используйте эти символы.
Потому что эти типы описаны в стандарте С99 (раздел 7.18 Integer types) и являются стандартными. Для использования их достаточно подключить хедер stdint.h. laughing.gif
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Oct 18 2009, 06:58
Сообщение #19


неотягощённый злом
******

Группа: Свой
Сообщений: 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.


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
Rst7
сообщение Oct 18 2009, 07:35
Сообщение #20


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



Цитата
Ну мне надо вывести значения в десятичной системе, которые выдает мне DS1307


Куда вывести? На дисплей? В символьном виде? Если да - то я Вам еще вот в этом посте написал. Что не ясно?


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Oct 18 2009, 11:15
Сообщение #21


I WANT TO BELIEVE
******

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



Цитата
Дык вы не просто читайте, а еще и в смысл прочитанного вникайте
Оооо, дошло наконец! Автор имел ввиду не использовать - т.е. не определять своих имен, оканчивающихся на "_t" или начинающихся с "_" smile.gif

Ну а по делу:
Ув. топикстартер, мне кажется Вам нужно заново перечитать все ответы и ЧЕТКО сформулировать проблему, которая сейчас преграждает вам путь к победе.
Прямо не стесняясь, от начала и до конца. Что уже сделано, что не понятно, что уже хоть как-то работает и как оно работает.
И тогда, возможно, кто-нибудь вам поможет.

Возьмем хотя-бы этот совет rezident:
Цитата
Накладыванием маски и сдвигами.
С этим всё ясно? Потому что может так случиться, что смысл Вами до конца был не понят, а от того, что дважды спросить одно и то-же бывает неудобно - вы можете остановиться на пол пути.

P.S. ну это я для примера взял именно этот совет, возможно тут какраз Вам всё понятно.


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
Neytrino
сообщение Oct 18 2009, 15:44
Сообщение #22


Участник
*

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



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

Честно говоря, Вы правы, я толком не могу понять, что значит наложить маску... я так понимаю, что сдвигая часть бит, маска как бы восполняет недостающие биты, причем в нужном мне порядке, верно? например 00001111 сдвигаем влево на 4 бита - получаем 11110000 и добавляем маску 00001111, то получится 11111111 верно?
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Oct 18 2009, 16:25
Сообщение #23


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.
Так вот после описанных мною операций мы получим число байт в буфере smile.gif

Ну и т.д.
Для закрепления материала задам задачку: нужно УСТАНОВИТЬ бит 5 какого-то(8ми битного) регистра в 0. Что для этого нужно? Какая маска и какая логическая операция должна быть использована?


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
Neytrino
сообщение Oct 18 2009, 17:02
Сообщение #24


Участник
*

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



Кажется до меня дошло!!!!!!!!! Сейчас попробую!!!
Go to the top of the page
 
+Quote Post
Neytrino
сообщение Oct 18 2009, 19:41
Сообщение #25


Участник
*

Группа: Участник
Сообщений: 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;
}


Что я не так сделал? Я хотя бы правильным путем пошел?
Go to the top of the page
 
+Quote Post
xemul
сообщение Oct 18 2009, 20:02
Сообщение #26



*****

Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731



Цитата(Neytrino @ Oct 18 2009, 23:41) *
...
Что я не так сделал?

Не прочитали статью в википедии, рекомендованную Вам на первой странице треда:
Цитата
...
При сложении двоично-десятичных чисел каждый раз, когда происходит перенос бита в старший полубайт, необходимо к полубайту, от которого произошёл перенос, добавить корректирующее значение 0110.
При сложении двоично-десятичных чисел каждый раз, когда встречается недопустимая для полубайта комбинация, необходимо к каждой недопустимой комбинации добавить корректирующее значение 0110 с разрешением переноса в старшие полубайты.
При вычитании двоично-десятичных чисел, для каждого полубайта, получившего заём из старшего полубайта, необходимо провести коррекцию, отняв значение 0110
Go to the top of the page
 
+Quote Post
baralgin
сообщение Oct 18 2009, 20:31
Сообщение #27


Частый гость
**

Группа: Участник
Сообщений: 92
Регистрация: 23-12-08
Из: Кишинёв
Пользователь №: 42 680



Neytrino В функции dec2bcd в глаза бросается неинициализированная (нулём) переменная(w) . На вид правильно. Но для надёжности стоит различать ещё "+" от "|" . Если уйти от "оптимизации", то функцию можно переписать одной строчкой. на предыдущей странице rezident давал пример того же самого только немного красивее.

rezident Неужели библиотечные "целое/целое" и "%" массивнее самописных? Ведь алгоритм прозрачен и сделать по другому сложно. Разве что вызовы вместо "инлайна" ... Или есть ещё что-то, что я не учитываю?
Go to the top of the page
 
+Quote Post
rezident
сообщение Oct 19 2009, 00:08
Сообщение #28


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(baralgin @ Oct 19 2009, 02:31) *
rezident Неужели библиотечные "целое/целое" и "%" массивнее самописных?
Я этого не утверждал. Просто бывают случаи когда целесообразнее вообще отказаться от применения умножения (хотя бы в подобном BCD-преобразовании), которое вызывает увеличение кода на лишние сотни байт линковкой соответствующей библиотеки.
Go to the top of the page
 
+Quote Post
Neytrino
сообщение Oct 19 2009, 10:16
Сообщение #29


Участник
*

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



Цитата(xemul @ Oct 19 2009, 00:02) *
Не прочитали статью в википедии, рекомендованную Вам на первой странице треда:

А можно, если конечно не сложно, разжевать это мне, я что-то не совсем понял данной статьи, если быть точнее как производить коррекцию и как вычислить в функции те самые недопустимые комбинации
Go to the top of the page
 
+Quote Post
rezident
сообщение Oct 19 2009, 11:28
Сообщение #30


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(Neytrino @ Oct 19 2009, 16:16) *
А можно, если конечно не сложно, разжевать это мне, я что-то не совсем понял данной статьи, если быть точнее как производить коррекцию и как вычислить в функции те самые недопустимые комбинации

Проще всего делать bcd-преобразование непосредственно перед выводом на экран или сразу после ввода значения (если есть ввод). А вычисления делать в обычном бинарном формате, не заморачиваясь десятичной коррекцией.
Go to the top of the page
 
+Quote Post

3 страниц V  < 1 2 3 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th July 2025 - 20:10
Рейтинг@Mail.ru


Страница сгенерированна за 0.01503 секунд с 7
ELECTRONIX ©2004-2016