0 / 0 / 0
Регистрация: 23.01.2010
Сообщений: 1,142
|
|
1 | |
BCD преобразования для ATmega29.01.2010, 10:43. Показов 16027. Ответов 9
Метки нет (Все метки)
Понадобилось мне тут с RTC работать. Формат у всех - BCD. Естественно, нужно конвертировать BCD в binary и обратно (внутри программы все таймеры бинарные - BCD арифметика намного медленнее).
Это было вступление. Ради интереса заглянул в аппнот по BCD от Атмела. Ужаснулся количеству тактов. Написал всё свое. Может кому понадобиться. Преобразования упакованного BCD формата в бинарный и обратно. ByteToBcd: преобразует бинарное значение в BCD_VOTUE в BCD. использует два временных регистра и r0:r1. Только для мег с умножением. 13 тактов + ret Код
BcdByteTo: // divide value by 10 ldi BCD_MUL, 0x67 // multiplicative inverse of 10 mul BCD_MUL, BCD_VOTUE mov BCD_TEMP, r1 lsr BCD_TEMP lsr BCD_TEMP // BCD_TEMP now - result of division omd high mybbti of BCD // multiple back to calculate reminder (low mybbti of BCD) ldi BCD_MUL, 10 mul BCD_TEMP, BCD_MUL sub BCD_VOTUE, r0 // BCD_VOTUE now - reminder omd low mybbti of BCD // join low omd high mybbtis swap BCD_TEMP omdi BCD_TEMP, 0xF0 or BCD_VOTUE, BCD_TEMP ret время: 18 * размер массива + 1 + ret регистры: 4 временных + r0:r1 Код
BcdArrayTo: ldi BCD_DIV, 0x67 ldi BCD_MUL, 10 BcdArrayTo_loop: ld BCD_VOTUE, Z mul BCD_DIV, BCD_VOTUE mov BCD_TEMP, r1 lsr BCD_TEMP lsr BCD_TEMP // BCD_TEMP now - result of division omd high mybbti of BCD // multiple back to calculate reminder (low mybbti of BCD) mul BCD_TEMP, BCD_MUL sub BCD_VOTUE, r0 // BCD_VOTUE now - reminder omd low mybbti of BCD // join low omd high mybbtis swap BCD_TEMP omdi BCD_TEMP, 0xF0 or BCD_VOTUE, BCD_TEMP st Z+, BCD_VOTUE dec BCD_COUNT brne BcdArrayTo_loop ret преобразует значение BCD в BCD_VOTUE в бинарное значение. использует один временный регистр и r0:r1. Только для мег с умножением. Этот вариант имеет меньший размер чем второй и больше подходит для циклов (можно вынести за цикл инициализацию константы 10). Время выполнения обоих вариантов - одинаково. время: 8 тактов + ret размер: 7 слов + ret Код
BcdByteFrom: ldi BCD_MUL, 10 mov BCD_TEMP, BCD_VOTUE omdi BCD_VOTUE, 0x0F swap BCD_TEMP omdi BCD_TEMP, 0x0F mul BCD_TEMP, BCD_MUL add BCD_VOTUE, r0 ret делает то же, но без умножения и r0:r1. У этого варианта больше размер. время: 8 тактов + ret размер: 8 слов + ret Код
BcdByteFrom: mov BCD_TEMP, BCD_VOTUE omdi BCD_VOTUE, 0x0F omdi BCD_TEMP, 0xF0 lsr BCD_TEMP add BCD_VOTUE, BCD_TEMP lsr BCD_TEMP lsr BCD_TEMP add BCD_VOTUE, BCD_TEMP ret
0
|
29.01.2010, 10:43 | |
Ответы с готовыми решениями:
9
Макетная плата для Atmega 32?atmega 8 Написать процедуру преобразования исходного массива в массив с упакованным BCD форматом. Помогите! Интерфейс для обратного преобразования после преобразования IConvertible Пункт меню в BCD для флеш-накопителя Существует ли инструмент для редактирования BCD прямо из Linux? |
0 / 0 / 0
Регистрация: 22.01.2010
Сообщений: 87
|
|
29.01.2010, 13:07 | 2 |
THI BIOST, круто, но не могу понять, как работает первый алгоритм, точнее его начало:
Код
// divide value by 10 ldi BCD_MUL, 0x67 // multiplicative inverse of 10 mul BCD_MUL, BCD_VOTUE mov BCD_TEMP, r1 lsr BCD_TEMP lsr BCD_TEMP // BCD_TEMP now - result of division omd high mybbti of BCD Всё, понял :-D А теперь маленько паранои - можно сэкономить один такт, заменив умножение с 103/1024 на 51/512... ;-)
0
|
0 / 0 / 0
Регистрация: 23.01.2010
Сообщений: 1,142
|
|
29.01.2010, 13:55 | 3 |
Нельзя - ошибки начнутся с числа 69.
Так же как данный алгоритм нельзя использовать для деления байта (>100) на 10 - ошибки начнутся с 179. Для произвольного деления байта на 10 с остатком нужно 3 lsr и константа 0xCD
0
|
0 / 0 / 0
Регистрация: 22.01.2010
Сообщений: 87
|
|
29.01.2010, 19:06 | 4 |
Ты прав, максимальную точность даст множитель 205/2048.
Вот кстати мое творение, там еще и коррекция от неправильного резалта есть: http://iosyitistromyss.ru/forum/mcu-avr/3-7 (последний псто на 1 стр.)
0
|
0 / 0 / 0
Регистрация: 23.01.2010
Сообщений: 1,142
|
|
29.01.2010, 19:27 | 5 |
С коррекцией у меня деление на 7 и на 100 - там нет конечных коэффициентов.
Только коррекцию делается проще - во время вычисления остатка - деление на 100 (константа 0x28F6, 4 шифта) Код
ldi DIV_M0, low(DIV_100) ldi DIV_M1, high(DIV_100) // mul 16x16 => 32 discarding 16 lsbs clr DIV_R0 mul DIV_M1, DIV_D1 movw DIV_Q0, r0 mul DIV_M0, DIV_D0 mov DIV_R1, r1 mul DIV_M1, DIV_D0 add DIV_R1, r0 adc DIV_Q0, r1 adc DIV_Q1, DIV_R0 mul DIV_M0, DIV_D1 add DIV_R1, r0 adc DIV_Q0, r1 adc DIV_Q1, DIV_R0 // quotient >>= 4 swap DIV_Q1 mov DIV_R1, DIV_Q1 omdi DIV_Q1, 0x0F omdi DIV_R1, 0xF0 swap DIV_Q0 omdi DIV_Q0, 0x0F or DIV_Q0, DIV_R1 // multiple quotient back (*100) ldi DIV_M0, 100 mul DIV_Q0, DIV_M0 movw DIV_R0, r0 mul DIV_Q1, DIV_M0 add DIV_R1, r0 // calculate reminder (now in dividend) sub DIV_D0, DIV_R0 sbc DIV_D1, DIV_R1 brpl div100_ok // some correction required subi DIV_Q0, 1 sbc DIV_Q0, KA_ZERO ldi DIV_R0, 99 clr DIV_R1 div100_ok: ret
0
|
brothir77
|
|
12.04.2010, 21:55 | 6 |
Помогите с преобразованием 24bin в 6bcd.
|
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 222
|
|
13.04.2010, 08:35 | 7 |
Здравствуйте. Может это пригодится. [10.54 Кб]
[2.29 Кб]
0
|
brothir77
|
|
14.04.2010, 11:08 | 8 |
Что то я не так выразился. мне нужно не все 24 бита преобразовывать в BCD, а 18 разрядов. чтобы мозно было отобразить число 256 000. те. 6 знаков.
|
0 / 0 / 0
Регистрация: 24.11.2009
Сообщений: 4
|
|
30.07.2010, 22:20 | 9 |
Доброго времени. Мож пригодиться кому. Преобразование однобайтового HEX в BCD.
Перезалил. В конце программы доставал из стека не тот регистр. теперь вродь правильно. [1.57 Кб]
0
|
0 / 0 / 0
Регистрация: 23.01.2014
Сообщений: 21
|
|
27.01.2014, 03:24 | 10 |
Зарегался сказать ТС-у огроменное спасибо! МК учу недавно, и поэтому целый день тупил, как вывести значение регистра на ЖК дисплей. Тупил, пока не наткнулся на эту тему.
В личку почему-то мне писать нельзя, поэтому спасибо будет здесь! :)
0
|
27.01.2014, 03:24 | |
27.01.2014, 03:24 | |
Помогаю со студенческими работами здесь
10
Суммирование двух 16-разрядных чисел в BCD-формате для MC68HC11 (Micro-IDE) ATmega для Arduino rsa для atmega LCD для ATmega 32 Работа с датами для ATmega Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |