Страница 1 из 2
Команды деления в AVR нет, а мне ОЧЕНЬ надо разделить
Добавлено: Вт май 22, 2007 07:47:59
VIY
Ситуация до безобразия бытовая, ВСЕМ нужна эта замечательная функция, и тем ни менее, кто-б не задал подобный вапрос,(как я уж поглядел), остальные тут-же по гамлетовски пускаются в рассуждения о сущности бытия..
Даже приятеля, который пиками увлекался больше года спросил, говорит, он эту задачу решил перебором!

. Но если я правильно понял, меня это не спасёт. С 8 битными не представляю как это возможно, а мне нужно 16 бит поделить!!!
***** Логика подсказывает что это всё-ж вазможно, ведь калькуляторы умеют!!

Даже от сомнений толька-что удостоверился, поделил и перемножил большие цифры на обычном калькуляторе, вроде одинаково быстро считает. Значит не перебором..
А ещё один приятель, подсказывал, что деление, это то-же самое умножение(А эта коменда есть у AVR-ов), только на число в минус_первой_степени. И опять тупик, чтобы получить минус_первую_степень, нужно разделить еденицу на это самое число.
************* у меня вабще складывается впечатление, будто она неразрешима.
Кстати, в математие есть множество других операций, каторых нет у AVR-ов, думаю всем, кто не углублялся в школьный курс бинарной арифметики было-бы интересно о них узнать.
Заранее спасибо...
Кстати, с радостью поделюсь вариантом практического решения алгоритма "Сглаживание опытных данных методом наименьших квадратов". Функция может быть очень полезной для устранения погрешности датчика, если известно что реальные показания изменяются плавно
http://www.intuit.ru/department/calcula ... /11-06.jpg Но это не раньше, чем я с делением разберусь :-/.
Добавлено: Вт май 22, 2007 08:12:21
Кашпо
Гы-Гы. Сам недавно наткнулся на команду деления в АВР (точнее на её отсутствие). Сам я пишу на Си (в CAVR), а Си эмулирует хоть плавающую точку.
Отсутствие команды деления я заметил, когда пришлось написать функцию очень критичную по скорости. Одна единственная команда деления (16бит целое на 16 бит целое) по моим рассчётам выполнялась более 200 тактов процессора.
Умножение всего в 10 раз быстрее.
Либо переходи на Си, либо подсмотри какой Ассемблерный код генерит Си при делении, либо выбирай числа на которые легко делить

. (это все степени двойки, деление на них как известно можно заменить быстрым битовым сдвигом

, который выполняется практически мгновенно)
Добавлено: Вт май 22, 2007 09:54:37
VIY
Время критично, точнее не очень, но математики у меня много!, а временной упор не так уж и далёк. Точность тоже, критична, метод подбора загубит мне всю арифметику(получится хуже чем до апроксимирования!).
Ну должен-же быть какой-то ПРАВИЛЬНЫЙ алгоритм, по каторому тот-же калькулятор имея в распоряжении всё те-же логические операции И, ИЛИ, и НЕ приспакойненько подсчитывает длинные, на весь экран цифры, (и не асобо парится!!),.. а ведь он ещё и корни умеет доставать!!! Не волшебные-же они?!! :-/
Вопрос по прежнему открыт. Не умею я не Си, ни программ для Си
не знаю, про дизасемблирование только и слышал.. Обо всём этом, как и о переборе массива похожих цифр можно рассуждать так-же долго, как и о смысле бытия, пример, соседние ветки...
По прежнему отчаянный
*****(ато сечас пойду, и валерьянкой с горя отравлюсь, тагда обьяснять вам будет нЕкаму

)
Добавлено: Вт май 22, 2007 10:05:08
Iron Rat
Добавлено: Вт май 22, 2007 10:43:34
Кашпо
А ты на чём пишешь?
вот во что транслируется вот такой код:
unsigned int A,B,C;
C = A/B;
; перегоняем в регистры делимое и делитель
MOV R30,R0x12
MOV R31,R0x13
MOV R26,R0x10
MOV R27,R0x11
; вызываем саму функцию деления
CALL __DIVW21U
; результат возвращаем обратно в переменную
MOV R0x14,R30
MOV R0x15,R31
; а вот сама функция, которая делит беззнаковое 16 битное целое на беззнаковое 16битное целое:
__DIVW21U:
CLR R0
CLR R1
LDI R25,16
__DIVW21U1:
LSL R26
ROL R27
ROL R0
ROL R1
SUB R0,R30
SBC R1,R31
BRCC __DIVW21U2
ADD R0,R30
ADC R1,R31
RJMP __DIVW21U3
__DIVW21U2:
SBR R26,1
__DIVW21U3:
DEC R25
BRNE __DIVW21U1
MOVW R30,R26
MOVW R26,R0
RET
P.S. Разберешься? я общий смысл понимаю, но вникать лень
Поставь себе какой-нить Сишный компилятор для мелкопроцессоров (Например CodeVisionAVR, сойдёт даже триальный).
пишешь там пару строк и компилируешь.
Компилятор генерит АСМ файл как побочный продукт (т.е. текст асемблерный). Куришь его блокнотом и вникаешь
P.P.S. таким нехитрым способом можно даже подсмотреть как делить дробные числа и считать всякие синусы-косинусы

Добавлено: Вт май 22, 2007 11:17:09
tych
Апноут у AVR есть - разные операции на АСМе. Список апноутов в низу 7-й страницы о прошивании AVR -
http://www.roboforum.ru/viewtopic.htm?p=11560
Добавлено: Вт май 22, 2007 11:40:50
VIY
Вах!

Пасиба!!, ИМХО этого должно быть достаточно. с меня по пакету сливок

. Сейчас уже на работу бежать, но вечерком всёпривсё проонализирую, и буду сочинять для 16-бит, Если всё-ж чего получится, здесь покажу....
Добавлено: Вт май 22, 2007 12:15:48
tych
Жуть как интересно !
Добавлено: Вт май 22, 2007 16:48:40
Mamonth
Этот код скачал где-то в инете:
; Div8 divides a 16-bit-number by a 8-bit-number
; Test: 16-bit-number: 0xAAAA, 8-bit-number: 0x55
;
.NOLIST
.INCLUDE "C:\avrtools\appnotes\8515def.inc"
.LIST
;
; Registers
;
.DEF rd1l = R0 ; LSB 16-bit-number to be divided
.DEF rd1h = R1 ; MSB 16-bit-number to be divided
.DEF rd1u = R2 ; interim register
.DEF rd2 = R3 ; 8-bit-number to divide with
.DEF rel = R4 ; LSB result
.DEF reh = R5 ; MSB result
.DEF rmp = R16; multipurpose register for loading
;
.CSEG
.ORG 0
;
rjmp start
;
start:
;
; Load the test numbers to the appropriate registers
;
ldi rmp,0xAA ; 0xAAAA to be divided
mov rd1h,rmp
mov rd1l,rmp
ldi rmp,0x55 ; 0x55 to be divided with
mov rd2,rmp
;
; Divide rd1h:rd1l by rd2
;
div8:
clr rd1u ; clear interim register
clr reh ; clear result (the result registers
clr rel ; are also used to count to 16 for the
inc rel ; division steps, is set to 1 at start)
;
; Here the division loop starts
;
div8a:
clc ; clear carry-bit
rol rd1l ; rotate the next-upper bit of the number
rol rd1h ; to the interim register (multiply by 2)
rol rd1u
brcs div8b ; a one has rolled left, so subtract
cp rd1u,rd2 ; Division result 1 or 0?
brcs div8c ; jump over subtraction, if smaller
div8b:
sub rd1u,rd2; subtract number to divide with
sec ; set carry-bit, result is a 1
rjmp div8d ; jump to shift of the result bit
div8c:
clc ; clear carry-bit, resulting bit is a 0
div8d:
rol rel ; rotate carry-bit into result registers
rol reh
brcc div8a ; as long as zero rotate out of the result
; registers: go on with the division loop
; End of the division reached
stop:
rjmp stop ; endless loop
Добавлено: Вт май 22, 2007 16:58:56
Tohey
В AVR студии в справке есть шаблоны...
Добавлено: Вт май 22, 2007 20:27:43
Мышонок
VIY, и не надо так шуметь.
Напоминаю, слова "ХЕЕЕЛП!", "СРОЧНО!", "ГОРЮ!" и т.п. ведут к немедленному удалению темы. В данном случае тема не удалена из-за уважения к ответившим вам форумчанам.
VIY, Вы наверняка будете удивлены, но практически все МК не могут выполнять простейших математических операций. Утрируя, они только нули с единичками складывать умеют.
Советую прочесть "Библию для программистов", т.е.
книгу Дональда Кнута "Искусство программирования для ЭВМ". Там много чего есть интересного, несмотря на то, что она впервые была издана в 1968 г. Совсем недавно она была переиздана в России. Посмотрите на библиотечных порталах в теме:
http://www.radiokot.ru/forum/viewtopic.php?t=466 , по-моему, она там есть.

Добавлено: Вт май 22, 2007 22:45:43
Nanobyte
Вот здесь много такого добра в разделе "AVR libraries for ASM projects":
http://elm-chan.org/cc_e.html
Добавлено: Ср май 23, 2007 17:49:49
Мышонок
ОФФТОП (разговор не по теме) и ФЛУД (трёп) были удалены. 
Спасибо за внимание!

Добавлено: Сб май 23, 2009 14:28:49
derestart
если делить на константу,- сначала подопытное число умножить на некий Х , потом сдвинуть в право Y раз
времени минимум результат близкий к "оригиналу"
числа Х и Y расчитайте сами...
Добавлено: Сб май 23, 2009 21:03:33
GP1
Настоятельно рекомендую.
Умножение и деление многоразрядных чисет и не только
Re: Команды деления в AVR нет, а мне ОЧЕНЬ надо разделить
Добавлено: Сб авг 14, 2010 11:01:09
Kisa
Вот и мне понадобилось делить 16 бит на 16 бит.
В этой книге только пример 32/8 бит. Сайт атмел у меня не открываеться уже вторые сутки... В приведённом Кашпо коде AVR Studio ругаеться на эти выражения:
MOV R30,R0x12
MOV R31,R0x13
MOV R0x14,R30
MOV R0x15,R31
Что это вобще такое?
Re: Команды деления в AVR нет, а мне ОЧЕНЬ надо разделить
Добавлено: Сб авг 14, 2010 12:51:11
Arlleex
ууу, я вообще про вычитание...
Ну а вообще вычитаешь необходимое количество раз
Re: Команды деления в AVR нет, а мне ОЧЕНЬ надо разделить
Добавлено: Сб авг 14, 2010 13:42:29
GP1
KisaВ этой книге изложена методология как делить/умножать, а количество байт зависит только от тебя

Re: Команды деления в AVR нет, а мне ОЧЕНЬ надо разделить
Добавлено: Сб авг 14, 2010 16:02:43
SII
Вот несколько подпрограмм:
Код: Выделить всё
; =======================
;
; Беззнаковое деление двухбайтовой величины на байт
;
; =======================
;
; Параметры:
;
; R17:R16 - делимое
; R18 - делитель
;
; Возвращаемый результат:
;
; C=1 - ошибка
; C=0 - деление выполнено
; R16 - частное
; R17 - остаток
;
; Изменяемые регистры: R16, R17, R19
DivByte:
ldi R19, 8
cp R18, R17
brlo _DB40
breq _DB40
_DB10: rol R16
rol R17
brcs _DB20
cp R18, R17
brlo _DB20
brne _DB30
_DB20: sub R17, R18
sec
_DB30: dec R19
brne _DB10
rol R16
ret
_DB40: sec
ret
; =======================
;
; Беззнаковое деление четырёхбайтовой величины на двухбайтовую
;
; =======================
;
; Параметры:
;
; R19:R16 - делимое
; R21:R20 - делитель
;
; Возвращаемый результат:
;
; C=1 - ошибка
; C=0 - деление выполнено
; R17:R16 - частное
; R19:R18 - остаток
;
; Изменяемые регистры: R16-R19, R22
DivWord:
ldi R22, 17
cp R21, R19
brcs _DWRet
brne _DW10
cp R18, R20
brcc _DWCS
clc
_DW10: rol R16
rol R17
dec R22
breq _DWRet
rol R18
rol R19
brcs _DW20
sub R18, R20
sbc R19, R21
brcc _DW30
add R18, R20
adc R19, R21
clc
rjmp _DW10
_DW20: sub R18, R20
sbc R19, R21
_DW30: sec
rjmp _DW10
_DWCS: sec
_DWRet: ret
; =======================
;
; Беззнаковое умножение двухбайтовых величин
;
; =======================
;
; Параметры:
;
; R17:R16 - множитель
; R19:R18 - множитель
;
; Возвращаемый результат:
;
; R23:R20 - произведение
;
; Изменяемые регистры: R0, R1, R20-R23
MulWord:
mul R17, R19
movw R23:R22, R1:R0
mul R16, R18
movw R21:R20, R1:R0
mul R17, R18
add R21, R0
adc R22, R1
adc R23, R2
mul R16, R19
add R21, R0
adc R22, R1
adc R23, R2
ret
Re:
Добавлено: Сб авг 14, 2010 18:24:48
dinets
я дико извиняюсь но я не нашол