Forum: Mikrocontroller und Digitale Elektronik ADC: Kanalumschaltung reisst AVR aus dem Konzept


von Mario M. (muraer)


Lesenswert?

Hallihallo zusammen,

ich habe ein Problem mit meinem AVR; genauer: dessen ADC. Es handelt 
sich um einen ATMega644, an 20MHz. Programmiert in C unter WinAVR 
20090313.

Der ADC wird wie folgt initialisiert:
1
ADMUX |= (1<<REFS0); //AREF = AVCC
2
ADMUX |= ((1<<MUX1) | (1<<MUX2) | (1<<MUX3) | (1<<MUX4)); //select internal Bandgap-reference as input
3
  
4
//ADC enable; ADCstart; ADC free running; Samplefreq = 156kHz, no interrupt
5
ADCSRA |= ((1<<ADEN) | (1<<ADSC) | (1<<ADATE) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0));

Das funktioniert soweit tiptop. Der ADC läuft und misst brav seine 
Bandgap-Referenz.

Nun muss ich aber eine Messung auf einem anderen Kanal machen. Dazu 
wechsle ich den Kanal. Der Folgende Code zeigt den Kanalwechsel mit der 
Messung (8 Messungen). Danach wird wieder auf die Bandgap-Referenz als 
ADC-Eingang umgeschaltet.
1
ADCSRA = 0; //Disable ADC;
2
ADMUX &= ~((1<<MUX0) | (1<<MUX1) | (1<<MUX2) | (1<<MUX3) | (1<<MUX4));//ADC Input Channel: ADC0
3
ADCSRA |= ((1<<ADEN) | (1<<ADIE) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0));//start ADC; no free running, 156kHz, interrupt enabled
4
ADCSRA |= (1<<ADSC);//start first conversion
5
6
ADCfinish = 0;
7
for(uint8_t k = 0; k<8; k++)
8
{
9
10
    while(ADCfinish == 0){}//wait until conv.compl.Interrupt
11
12
    ADCfinish = 0;
13
    resulthelper = ADCL; //read out the 10-bit value.
14
    resulthelper = resulthelper + (ADCH<<8);
15
    result = result + resulthelper;
16
        
17
}
18
19
//now: switch back to bandgap-reference:
20
ADCSRA = 0; //Disable ADC;
21
ADMUX |= ((1<<MUX1) | (1<<MUX2) | (1<<MUX3) | (1<<MUX4)); //select internal Bandgap-reference as input
22
23
//ADC enable; ADCstart; ADC free running; Samplefreq = 156kHz, no interrupt
24
ADCSRA |= ((1<<ADEN) | (1<<ADSC) | (1<<ADATE) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0));

Und hier noch die Interruptroutine:
1
ISR(ADC_vect)
2
{
3
4
  ADCfinish = 1;
5
  ADCSRA |= (1<<ADSC); //start next conversion.
6
}

Das Ganze nochmals in Kürze:
Standardmässig ist die Bandgap-Referenz ADC-Eingang, der ADC läuft free 
running und hat den conversion complete interrupt ausgeschaltet.

Es muss für 8 Messungen auf Kanal 0 umgeschaltet werden. Dazu wird der 
ADC komplett abgeschaltet, der Kanal gewechselt, und wieder 
angeschaltet, diesmal Interruptgesteuert.
Dann wird gemessen. In jeder ISR wird die nächste Messung ausgelöst.
Nach den 8 Messungen muss wieder auf die Bandgap-Referenz und free 
running umgeschaltet werden ==> ADC abschalten, Kanal wechseln, neu 
konfiguriert wieder anschalten.

Die Messwerte, welche beim Achtmaligen Messen entstehen, sind korrekt. 
Der ADC arbeitet also richtig.

ABER: Er haut mir irgendwie den Rest des AVR aus den Socken. An einem 
AVR-Pin hängt eine LED. Diese wird ganz zu beginn des AVR-Programms 
eingeschaltet und dann folgt nie mehr eine Anweisung, um diese LED 
wieder auszuschalten.
Führe ich aber die Kanalumschaltung und die 8 Messungen aus, so erlischt 
die LED! Ohne dass dafür irgendwo im Programm die Anweisung dafür stehen 
würde...Der AVR läuft jedoch weiter und tut so, als ob nichts 
wäre...Alle anderen funktionen funktionieren, nur die LED leuchtet nicht 
mehr...

Jetzt wollte ich nachfragen, ob meine Variante der ADC-Bedienung so in 
Ordnung ist. Kann sein, dass meine Methode etwas "holzig" und zu exakt 
ist, da ich jetzt schon viel probiert habe und noch keine Besserung 
eingetreten ist. Aber sollte die Methode im Prinzip funktionieren?

von Thomas (kosmos)


Lesenswert?

an welchen Pin hängt den die LED?

von Mario M. (muraer)


Lesenswert?

Die LED hängt an PA5, da hängen noch ADC5 und PCINT5 mit dran...
Könnte der ADC5, welcher ja auch am ADC-Mux hängt, einen Einfluss 
haben....?! Nur welchen...?

Lg
Mario

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.