I have implemented this fuction for an ohmmeter, which must do a divide (R=E/I), since it can only measure voltage and current. Here is the source for an Atmel processor. Use a fixed width font, tab space = 6 to view.
This function divides two 32-bit numbers using an 8-bit AVR processor. you will also need fuctions to store 4-registers to memory, and recall them, e.g. SQ_2_mem() and LoadSQ()
Frank Raffaeli
Ratio: cbr Status, (1 SQ[] movw SQ2, Temp2 ; hi word DD -> SQ[]
clr Temp0 ; Temp[] -> lo byte RM = 0 clr Temp1 ; Temp[] -> 2nd byte RM = 0 clr Temp2 ; Temp[] -> 2nd byte RM = 0 sub Temp3, Temp3 ; 4th byte: RM=0 & clr carry
ldi EE_Addr, 33 ; use of EE_Addr as counter
divide_loop1:
rol SQ0 ; shift dividend left rol SQ1 ; carry -> byte 2 dividend rol SQ2 ; carry -> byte 3 dividend rol SQ3 ; carry -> byte 4 dividend
dec EE_Addr ; decrement counter breq ExitRatio ; bug out at end count
rol Temp0 ; shift dividend into remainder rol Temp1 ; shift RM byte 2 rol Temp2 ; shift RM byte 3 rol Temp3 ; shift RM byte 4
ldi XL, low(mem2) ; load pointer low byte mem2 ldi XH, high(mem2) ; load pointer high byte mem2 rcall SQ_2_Mem ; SQ[] (DD/result) -> mem2
ldi XL, low(mem1) ; load pointer low byte mem1 ldi XH, high(mem1) ; load pointer high byte mem1 rcall LoadSQ ; divisor from mem1 -> SQ[]
sub Temp0, SQ0 ; RM = RM - VR (low byte) sbc Temp1, SQ1 ; RM = RM - VR (carry) sbc Temp2, SQ2 ; RM = RM - VR (carry) sbc Temp3, SQ3 ; RM = RM - VR (carry) brcs add_back ; if carry, add back to RM
ldi XL, low(mem2) ; load pointer low byte mem2 ldi XH, high(mem2) ; load ptr high byte mem2 rcall LoadSQ ; DD/result: mem2 -> SQ[] sec ; set carry, '1' into DD rjmp divide_loop1
add_back: add Temp0, SQ0 ; RM = RM + VR (restore) adc Temp1, SQ1 ; RM = RM + VR (carry 2nd) adc Temp2, SQ2 ; RM = RM + VR (carry 3rd) adc Temp3, SQ3 ; RM = RM + VR (carry 4th)
ldi XL, low(mem2) ; load pointer low byte mem2 ldi XH, high(mem2) ; load pointer high byte mem2 rcall LoadSQ ; DD/result: mem2 -> SQ[] clc ; clear carry, '0' into DD
rjmp divide_loop1 ; back to start
ExitRatio: rcall RatioFilter ; smooth the data in SQ[] sbr Status, (1