Как известно у AVR микроконтроллеров отсутствует узел
аппаратного делителя. Это тот узел , который позволяет организовать операцию
деления над байтами без особых программных затрат. Обычно этот узел имеется на
борту всех сигнальных процессоров, поскольку данная операция необходима при
обработки сигналов. Еще встречается аппаратный делитель у МК 51 и у других микроконтроллеров. У AVR микроконтроллеров компания ATMEL игнорирует этот узел, и балует нас только арифметическим или/и логическим сложением, вычитанием, умножением.
Чтобы поделить одно двухбайтное число на однобайтное в таких
микроконтроллерах потребуется от 1 до 4 тактов. Это ничего по сравнению с
организацией деления в МК AVR.
У меня на процедуру деления в формате 0xAAAA / 0xAA = 0xAAАА уходит под 250 тактов. Ну для
неплохой точности и малой погрешности быстрее никак не получается. Может вы
что-то быстрее придумаете и выкладуйте.
Для тех кто работает с АВРками и нуждается в этой операции
привожу исходник. Формат: 0xAAAA / 0xAA = 0xAAАА (то есть 2 байта делим на один, получаем два байта). Запись делимого и делителя производится в тексте программы, а результат (частное) отображается на пинах порта А и С. Текст программы. .include "m8535def.inc" ; подключаем библиотеку ATmega8535 .list .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 .DEF temp = R17 .CSEG ; программный код расположется в сегменте памяти программ .ORG 0x0000 ; процессор стартует с нулевого адреса, а дальше пойдут вектора прерывания RJMP Reset ; прерывания по сбросу. Прыгаем на метку Reset
;================ТАБЛИЦА ВЕКТОРОВ ПРЕРЫВАНИЯ================ .org INT0addr ; External Interrupt 0 reti .org INT1addr ; External Interrupt 1 reti .org OC2addr ; Timer/Counter2 Compare Match reti .org OVF2addr ; Timer/Counter2 Overflow reti .org ICP1addr ; Timer/Counter1 Capture Event reti .org OC1Aaddr ; Timer/Counter1 Compare Match A reti .org OC1Baddr ; Timer/Counter1 Compare Match B reti .org OVF1addr ; Timer/Counter1 Overflow reti .org OVF0addr ; Timer/Counter0 Overflow reti .org SPIaddr ; SPI Serial Transfer Complete reti .org URXCaddr ; USART, RX Complete reti .org UDREaddr ; USART Data Register Empty reti .org UTXCaddr ; USART, TX Complete reti .org ADCCaddr ; ADC Conversion Complete reti .org ERDYaddr ; EEPROM Ready reti .org ACIaddr ; Analog Comparator reti .org TWIaddr ; Two-wire Serial Interface reti .org INT2addr ; External Interrupt Request 2 reti .org OC0addr ; TimerCounter0 Compare Match reti .org SPMRaddr ; Store Program Memory Read reti .org INT_VECTORS_SIZE ; size in words reti
;================ НАЧАЛО ИНИЦИАЛИЗАЦИИ ПЕРЕФЕРИИ================= Reset: ldi temp,high(RAMEND) ; инициализация стека out SPH,temp ldi temp,low(RAMEND) out SPL,temp ldi temp,0xff out DDRC,temp out DDRA,temp
start: ldi rmp,0b10000000 ; делимое (старший) mov rd1h,rmp ;-------------- ldi rmp,0b00001011; делимое (младший) mov rd1l,rmp ;-------------- ldi rmp,0b00000101 ;делитель mov rd2,rmp ;-------------
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)
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: out portC,rel ;а частное выводим сюда out portA,reh ;и сюда rjmp stop ; endless loop
|