F
Frank Raffaeli
Guest
Donald wrote:
(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
http://www.aomwireless.com/
;************************************************************************
;*
;* Ratio -
;* Divides const in Temp[] (dividend) by variable in SQ[] (divisor)
;* DD = dividend, VR = divisor, RM = remainder. SQ[] (divisor) stored
in
;* SRAM and recalled as needed. SQ[] is then used as initial dividend.
;* result is shifted into the dividend SQ[], which returns final
answer.
;*
;************************************************************************
Ratio:
cbr Status, (1<<ACC_Ready) ; clear acc ready flag
tst SQ2 ; see if SQ2 is zero
brne init_dividend ; if not, its big enough
ldi EE_Addr, low(MinDivisor) ; lo byte of min divisor
cp SQ0, EE_Addr ; check low byte divisor
ldi EE_Addr, high(MinDivisor) ; hi byte of min divisor
cpc SQ1, EE_Addr ; carry compare to hi byte
brsh init_dividend ; if big enough, init
ser EE_Addr ; load constant 0xFF
mov SQ0, EE_Addr ; max it out - div by zero
mov SQ1, EE_Addr ; max it out - div by zero
rjmp ExitRatio ; bug out in disgrace
init_dividend:
lds Temp0, ohms_scale ; initi low byte 32-bit DD
lds Temp1, ohms_scale+1 ; init 2nd byte 32-bit DD
lds Temp2, ohms_scale+2 ; init 3rd byte 32-bit DD
lds Temp3, ohms_scale+3 ; init 4th byte 32-bit DD
; alternate entry point for arbitrary dividend
RatioMoose:
ldi XL, low(mem1) ; pointer low byte mem1
ldi XH, high(mem1) ; pointer high byte mem1
rcall SQ_2_Mem ; SQ[] (input) -> mem1
movw SQ0, Temp0 ; low word DD -> 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<<DataReady) ; data ready
ret
I have implemented this fuction for an ohmmeter, which must do a divideSylvain Munaut wrote:
srinivasa.rangan@gmail.com wrote:
If the ouptut is obtained by around 500ms it is good enough.I dont want
to use a microcontroller or anything because i feel that it would be an
overkill.Also the quotient is good enough for me.
Overkill ? Come-on, a division is not 'that' simple (compared to an AND
snip
I don't know any chip that do the division and building one from other
chips, _that_ is overkill.
I think the OP wants an off-the-shelf (OTS) solution.
Any kind of micro will require software programming and hardware
programming, then it can be wired into his circuit.
Unless anyone here has this device already programmed with docs and
application notes to wire it up and maybe a demo board in their back
pocket......
It's clear that Srinivasa is a beginner.
So the long answer is "No" its not available OTS, but it can easily be
done if you are willing to learn a little and so some home work.
If Srinivasa is willing to learn, this is a good news group to ask
questions about getting your ideas and projects working.
I am sure many here have already did a napkin design on how they would
do it. ( I too have penciled out my own design I used and ATMega 32 )
Good Luck Srinivasa , I hope you success with your project.
Donald
(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
http://www.aomwireless.com/
;************************************************************************
;*
;* Ratio -
;* Divides const in Temp[] (dividend) by variable in SQ[] (divisor)
;* DD = dividend, VR = divisor, RM = remainder. SQ[] (divisor) stored
in
;* SRAM and recalled as needed. SQ[] is then used as initial dividend.
;* result is shifted into the dividend SQ[], which returns final
answer.
;*
;************************************************************************
Ratio:
cbr Status, (1<<ACC_Ready) ; clear acc ready flag
tst SQ2 ; see if SQ2 is zero
brne init_dividend ; if not, its big enough
ldi EE_Addr, low(MinDivisor) ; lo byte of min divisor
cp SQ0, EE_Addr ; check low byte divisor
ldi EE_Addr, high(MinDivisor) ; hi byte of min divisor
cpc SQ1, EE_Addr ; carry compare to hi byte
brsh init_dividend ; if big enough, init
ser EE_Addr ; load constant 0xFF
mov SQ0, EE_Addr ; max it out - div by zero
mov SQ1, EE_Addr ; max it out - div by zero
rjmp ExitRatio ; bug out in disgrace
init_dividend:
lds Temp0, ohms_scale ; initi low byte 32-bit DD
lds Temp1, ohms_scale+1 ; init 2nd byte 32-bit DD
lds Temp2, ohms_scale+2 ; init 3rd byte 32-bit DD
lds Temp3, ohms_scale+3 ; init 4th byte 32-bit DD
; alternate entry point for arbitrary dividend
RatioMoose:
ldi XL, low(mem1) ; pointer low byte mem1
ldi XH, high(mem1) ; pointer high byte mem1
rcall SQ_2_Mem ; SQ[] (input) -> mem1
movw SQ0, Temp0 ; low word DD -> 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<<DataReady) ; data ready
ret