Es sind 4 Messungen, da man dann keine Divisionsroutine benötigt, sondern nur zweimal rechts schieben muss.
Den Rest solltest Du selbst zusammenbringen.
Code:
.include "m8def.inc"
.equ chan = 0 ; adc-channel
.cseg
.org 0
rjmp start
reti
.org 0x13
start:
ldi r16, high(RAMEND)
out SPH, r16
ldi r16, low(RAMEND)
out SPL, r16
rcall adc_init
mainloop:
rcall get_adc
; do something
rjmp mainloop
get_adc: ; returns averaged result out of 4 samples
clr r18 ; result in r18/r19
clr r19
ldi r17, 4 ; count of samples
in r16, ADMUX
andi r16, ~(1<<MUX3)|(1<<MUX2)|(1<<MUX1)|(1<<MUX0)
ori r16, chan
out ADMUX, r16
get_sample:
sbi ADCSRA, ADSC ; start conversion
wait_adc:
sbic ADCSRA, ADSC
rjmp wait_adc ; wait for conversion ready
in r16, ADCL ; get result low byte
add r18, r16 ; add
in r16, ADCH ; get high byte
adc r19, r16 ; add with carry
dec r17 ; decrease sample counter
brne get_sample
lsr r19 ; shift result right = divide by 2
ror r18
lsr r19 ; same again, now divided by 4
ror r18
ret
adc_init:
ldi r16, (1<<ADEN)|(1<<ADPS2)|(1<<ADPS0) ; enable adc, adc-prescaler 32
out ADCSRA, r16
ldi r16, (1<<REFS0) ; ref is AVCC
out ADMUX, r16
ret
Lesezeichen