Ассемблер (ASM) для AVR в вопросах и ответах

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
baghear
Опытный кот
Сообщения: 791
Зарегистрирован: Вт июн 17, 2014 00:34:26

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение baghear »

Еще такой вопрос, для чего умножают число которое хотят преобразовать на 0х67?
И потом старшую тетраду умножают на 4?
Код:

BcdByteTo:
// divide value by 10
ldi BCD_MUL, 0x67 // multiplicative inverse of 10
mul BCD_MUL, BCD_VALUE
mov BCD_TEMP, r1
lsr BCD_TEMP
lsr BCD_TEMP

// BCD_TEMP now - result of division and high nibble of BCD

// multiple back to calculate reminder (low nibble of BCD)
ldi BCD_MUL, 10
mul BCD_TEMP, BCD_MUL
sub BCD_VALUE, r0

// BCD_VALUE now - reminder and low nibble of BCD

// join low and high nibbles
swap BCD_TEMP
andi BCD_TEMP, 0xF0
or BCD_VALUE, BCD_TEMP
ret
akl
Друг Кота
Сообщения: 4444
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение akl »

baghear писал(а):Еще такой вопрос, для чего умножают...на 0х67?
И потом старшую тетраду умножают на 4?
По мне, это замена операции деления умножением. X/10=X*K*256/10*256; отсюда K=256/10=25,6. Но, это довольно грубый коэффициент, поэтому разработчик программы преобразования BIN-BCD искусственно умножает его на 4 с округлением в большую сторону, т.е. K=4*256/10=102,4~103(0x67), а затем уже в программе делит сдвигами вправо полученное число на 4. На истинность не претендую.
Аватара пользователя
baghear
Опытный кот
Сообщения: 791
Зарегистрирован: Вт июн 17, 2014 00:34:26

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение baghear »

Опишите подробнее пожалуйста как Вы заменили деление умножением.
У Вас деление в выражении с обоих сторон от равно
X/10=X*K*256/10*256
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение WiseLord »

Там просто много опечаток в формуле.
Принцип простой - чтобы разделить на 10, можно для начала умножить на какой-то коэффициент, чтобы потом можно было сдвигом получить результат.

Например: X / 10 = X * 205 / 2050

Т.е., чтобы разделить на 10, можно сначала умножить на 205, а потом разделить на 2050. А разделить на 2050 - это почти то же самое, что разделить на 2048, или сдвинуть на 11 вправо. По крайней мере, для X от 0 до 1023 это так.

Можно и на другие коэффициенты умножать. Если умножать на 0x67 (103), то получится:

X / 10 = X * 103 / 1030.
А разделить на 1030 - это почти то же самое, что разделить на 1024, или сдвинуть на 10 вправо. Но это работает уже только для чисел от 0 до 170.

В принципе, подобным образом можно просчитать любое деление на константу (не только 10), главное подобрать коэффициент, дающий в делителе число, чуть большее степени двойки. Чем ближе оно к степени двойки, тем для большего диапазона входных чисел результат будет верен.
Например,

X / 19 = X * 27 / 513 ~ X * 27 / 512, верно для X от 0 до 512.

X / 7 = X * 293 / 2051 ~ X * 293 / 2048, верно для X от 0 до 682.
akl
Друг Кота
Сообщения: 4444
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение akl »

akl писал(а):X/10=X*K*256/10*256
Согласен, не корректная запись. Ещё раз X/10=X*(256/256)/10. Если обозначить подчёркнутое как K=256/10, то получим X/10=X*K/256. Ещё в тему.
WiseLord писал(а):главное подобрать коэффициент
Ничего не надо подбирать.
nirq
Опытный кот
Сообщения: 758
Зарегистрирован: Вс фев 10, 2013 15:26:00

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение nirq »

исходные данные: BCD_VALUE (0..255)

А.

BCD_VALUE / .10 = результат (0..255)
256 * 4 * ( BCD_VALUE / 10 ) = старший байт от результата, два раза сдвинутого влево (0..26112 , помещаемся в 15 бит)
( 256 * 4 / 10 ) * BCD_VALUE = старший байт от результата, два раза сдвинутого влево

256 * 4 / 10 = 102.4 ~ 103 = 0x67, округлили в большую сторону

0x67 * BCD_VALUE = старший байт от результата, два раза сдвинутого влево, плюс "(как это будет сказать по-русски reminder, напоминалка?)" (0..26265, даже и так помещаемся в 15 бит)

Б.

от результата умножения берём только старший байт и двигаем его ещё два раза влево, т.е. умножаем на 4
внимание: ( 0..26265 * 4 ) уже может не поместиться в 16 бит !!!
как сделать, чтобы оно туда гарантированно поместилось? ограничить исходное BCD_VALUE.
каким максимально возможным значением его ограничить?
решаем уравнение 0x67 * BCD_VALUE * 4 <= 0xFFFF, получается BCD_VALUE <= 0x9F = 159

Или нет.

... дальше в исходном коде идёт камент "// BCD_TEMP now - result of division and high nibble of BCD" и магическая магия, а я иду кушать.
Но общий смысл такой, что "ремайндер после округления 102.4 до 0х67" не выбрасывается, а как-то потом учитывается в готовом результате.

Нуевовжопу такие "рационализации". Один вые потешил своё лично кульхацкерское самолюбие, другому потом отлаживать это всё, а третьему поддерживать и развивать проэхт, состоящий из вот такого вот.
Одинкуй глаза пользователя не различат цифры, обновляющиеся заметно чаще, чем раз в секунду. А за секунду это всё можно посчитать тупо вычитанием, в фоновом режиме (в майнлупе), не мешая никаким более важным задачам.

Даже пословица есть народная: "увидишь рационализатора - убей!".


___
(смутившая описка поправлена, это было очень важно, зато трудно на фоне "еррор 502" и т.п)
Последний раз редактировалось nirq Чт июн 19, 2014 15:45:18, всего редактировалось 6 раз.
Аватара пользователя
baghear
Опытный кот
Сообщения: 791
Зарегистрирован: Вт июн 17, 2014 00:34:26

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение baghear »

BCD_VALUE / .10 = результат (0..255)
Результат будет 0...25 или не так понял?
256 * 4 * ( BCD_VALUE / 10 )
Откуда появилось 256?
akl
Друг Кота
Сообщения: 4444
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение akl »

Деление на 256 осуществляется простым отбрасыванием младшего байта.

Код: Выделить всё

 mul BCD_MUL, BCD_VALUE   ; умножить X на 4*256/10
 mov BCD_TEMP, r1   ; разделить результат на 256
 lsr BCD_TEMP
 lsr BCD_TEMP   ; разделить результат на 4. В итоге получить X/10
Аватара пользователя
baghear
Опытный кот
Сообщения: 791
Зарегистрирован: Вт июн 17, 2014 00:34:26

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение baghear »

Спасибо akl, этот кусочек понял.
akl
Друг Кота
Сообщения: 4444
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение akl »

Хорошо, пошли дальше

Код: Выделить всё

   ldi BCD_MUL, 10
   mul BCD_TEMP, BCD_MUL   ; получить число десятков результата
   sub BCD_VALUE, r0   ; получить число единиц

;// BCD_VALUE now - reminder and low nibble of BCD
;// join low and high nibbles
   swap BCD_TEMP     ; старшую тетраду на своё место
   andi BCD_TEMP, 0xF0   ; лишняя команда
   or BCD_VALUE, BCD_TEMP   ; склеить тетрады
Внимание. Этот код правильно преобразовывает числа в диапазоне 0...99!!!
Аватара пользователя
baghear
Опытный кот
Сообщения: 791
Зарегистрирован: Вт июн 17, 2014 00:34:26

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение baghear »

Разобрался!!!
Спасибо :))
То что это код работает до 99 понятно.
Может у Вас есть код который работает до 999, на асм?
akl
Друг Кота
Сообщения: 4444
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение akl »

В принципе, есть. Код довольно легко меняется как в сторону увеличения так уменьшения, подходит для камней без аппаратной поддержки умножения.
Аватара пользователя
FreshMan
Друг Кота
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение FreshMan »

как известно ресет вызывается тремя способами:
- при включении питания
- при нажатии кнопки
- с помощью watchdog
а если я сделаю прыжок на нулевой адрес, будет ли оный ресет равносильный первым трем ?
Tell Me The Truth
Аватара пользователя
ibiza11
Поставщик валерьянки для Кота
Сообщения: 1900
Зарегистрирован: Сб фев 21, 2009 13:11:40
Откуда: Москва

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение ibiza11 »

FreshMan писал(а):будет ли оный ресет равносильный первым трем ?
не будет.
Ставим плюсы: )
Аватара пользователя
FreshMan
Друг Кота
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение FreshMan »

почему ?
Tell Me The Truth
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение ARV »

потому что аппаратный сброс производит инициализацию периферии, например, обнуляет все регистры DDRх и PORTx, а что там у вас делается по нулевому адресу - известно только вам.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
Seriyvolk
Друг Кота
Сообщения: 4961
Зарегистрирован: Сб май 05, 2012 20:19:55
Откуда: Минск

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Seriyvolk »

Привет всем! Есть один канал АЦП, и есть клавиатура из 4-х кнопок, к нему подключённая. Единственное, чего нет, так это защиты от дребезга контактов, из-за чего АЦП иногда неверно интерпретирует нажатую кнопку. Интересует кто как борется с этим дребезгом. Больше даже интересен не сам код, сколько принцип, да так чтоб оно работало хорошо и быстро! :))
Прибор, защищённый предохранителем, сгорает первым, защитив предохранитель. Закон Мерфи.
Shinen
Родился
Сообщения: 4
Зарегистрирован: Ср июн 18, 2014 13:33:39

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Shinen »

Seriyvolk писал(а):Есть один канал АЦП, и есть клавиатура из 4-х кнопок, к нему подключённая. Интересует кто как борется с этим дребезгом.

Методов много и выбор зависит от ресурсов.
Например адц работает в цикле. С частотой например 15Гц. Берем результат и запоминаем в буфер на 3 результата выбрасывая более старые. Нажатие считаем если последнии результаты равны. Необходимо учитывать шум в измерениях, например выбрасывать младшие биты сдвигом, пори этом инкрементнуть, если последний сдвинутый был 1 (округление).
Аватара пользователя
Seriyvolk
Друг Кота
Сообщения: 4961
Зарегистрирован: Сб май 05, 2012 20:19:55
Откуда: Минск

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Seriyvolk »

Вот как раз шум АЦП и интересен. Какой порядок цифр ожидать, если вести речь конкретно о тини13?
Прибор, защищённый предохранителем, сгорает первым, защитив предохранитель. Закон Мерфи.
nirq
Опытный кот
Сообщения: 758
Зарегистрирован: Вс фев 10, 2013 15:26:00

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение nirq »

(здесь был выебон не по делу)
Последний раз редактировалось nirq Пт июн 20, 2014 19:36:32, всего редактировалось 1 раз.
Ответить

Вернуться в «AVR»