Stránka 1 z 1
mega8 ADC nedokončí převod
Napsal: 15 úno 2013, 19:41
od Jenda_KL
Občsas, tak jednou za dvě hodiny přestane převodník číst a pomůže jenom reset.
Řekl bych, že nedojde k tomu přerušení od ADC.
Je ještě použito TIM0 a v mainu je jen SLEEP.
Řešenim je kontrolovat časovačem, ale rád bych našel příčinu.
kód je zřejmě ok, ale stalo se mi to už u druhé aplikace.
//INIT ADC
admux = $0C0 //internal 2.56Vref,chan0
adcsra = $0C8 //ADEN,ADSC,ADIE
Kód: Vybrat vše
ADCCC:
ldi XL,low(ip1) //$08-$0D (ip1-ip6) reg s hodnotou, celkem 6
ldi XH,high(ip1) //$01 (ip1-ip6)
lds a,muxpos //offset 0-5 ; a=r16 b=r17
add XL,a
in b,ADCL
st X,b
in b,ADCH //naprazdno
inc a
cpi a,6
brne muxok
ldi a,0 //reset offsetu
muxok:
sts muxpos,a
ori a,$0C0
ldi b,$0C8
out admux,a
out adcsra,b
RETI
Napsal: 15 úno 2013, 19:45
od Andrea
To tam tak vesele měníš v přerušení registry a flagy, aniž bys je ukládal a obnovoval?
Napsal: 15 úno 2013, 20:28
od Jenda_KL
Ukádal a obnovoval ? nikde jinde se nepoužívají.
Je problém zápis 0 do ADIF ? To je jediný flag co tam je.
Zápisem C8 se změní jen ADSC 0->1, ADIF zůstává 0
Nějak nerozumím tomu "Alternatively,
ADIF is cleared by writing a logical one to the flag. Beware that if doing a Read-Modify-
Write on ADCSRA, a pending interrupt can be disabled."
Ale to by se mělo týkat zápisu do ADCSRA mimo rutinu, když je hotová konverze a čeká se na ISR, což tady není.
Napsal: 15 úno 2013, 20:33
od Andrea
No jak myslíš. A měla jsem na mysli flagy v SREG.
Napsal: 15 úno 2013, 20:40
od Jenda_KL
jasně, jde ale vždy jen ADCCC nebo TIM0, jak zůstane SREG při návratu do spánku (po RETI) musí být přeci jedno.
Napsal: 15 úno 2013, 21:23
od Andrea
Když to říkáš, já ten zbytek programu nevidím.
Napsal: 15 úno 2013, 21:39
od Jenda_KL
Kód: Vybrat vše
.include "m8def.inc"
//dale definice registru
.cseg
.org $0 RJMP init
.org $09 RJMP tim0
.org $0E RJMP adccc
.org $30 RETI
ADCCC uz tu bylo
// =============== TIMER 0 ISR / 31.25kHz
TIM0:
inc rpwm //=r22
lds b,ip1 ;chan1 reset
lds a,dpwm1
andi a,$1F
lsl a
lsl a
lsl a
ori a,$07
cp b,a
brlo ex_c1
cbi portd,pd0
cbi portd,pd1
ex_c1:
// ---- dalsi kanaly
cpi rpwm,$1E
brlo texit
ldi rpwm,$0FF
lds a,dpwm1 ;chan1 set ano nebo ne
sbrc a,7
sbi portd,pd0
sbrs a,7
cbi portd,pd0
sbrc a,6
sbi portd,pd1
sbrs a,6
cbi portd,pd1
// ---- dalsi kanaly
texit:
RETI
// =============== INIT
INIT:
ldi a,low(RAMEND)
ldi b,high(RAMEND)
out sph,b
out spl,a
ldi a,0b10000000 //SE SM2 SM1 SM0 ISC11 ISC10 ISC01 ISC00
out MCUCR,a
//dale porty,adc a vychozi hodnoty registru, smazani RAM
;TIMER 0
ldi a,1
out tccr0,a
;INT
ldi a,1
out timsk,a
sei
// =============== MAIN
loop:
SLEEP
rjmp loop
Napsal: 17 úno 2013, 16:01
od Jenda_KL
Napadla mě věc kterou jsem se nedočetl.
Je potřeba ADC vypínat při změně kanálu, čiže ADEN 1->0 , změnit kanál, ADEN 0->1 ?
Napsal: 18 úno 2013, 10:32
od Jenda_KL
Ne, přepnutí kanálu tímto způsobem toreticky nevadí, ale nějaký vliv má, protože bez přepínání to neudělá.
Je to skutečně tak, že se nenastaví ADIF a taky se nesnuluje ADSC. Otázka - vzhledem k tomu že to točí motůrkama je tu možnost takového rušení že to resetne jen ADC?
Asi to vzdávám, kombinace 555+LM393+4013 to jistí.
Napsal: 18 úno 2013, 11:24
od Andrea
A zkusil jsi to bez sleepu?
Mimochodem, jak zjišťuješ, jestli se nastavil ADIF a shodil ADSC nebo ne?
Napsal: 18 úno 2013, 14:20
od Jenda_KL
Tady to zjišťuju tak, že ADCSRA čtu v INT_TIM0 a posílám bity na volné výstupy, jinak to asi nejde.
V té druhé aplikaci to je bez sleepu a bez přerušení od ADC a to tak, že v hlavní smyčce se testuje kdy zmizí ADSC. Tam se problém se "zatuhnutím" měřených hodnot vyskytoval občas taky.