Forum: Mikrocontroller und Digitale Elektronik Probleme mit AD-Wandler + Atmega1280


von Helene (Gast)


Lesenswert?

Hallo,

ich lese alle 30 Sekunden den AD-Eingang (PF1) meines Atmega 1280 aus.
An diesem hängt ein Sensor der im "Normalzustand" einen AD-Wert von ca. 
180 liefern sollte.

Leider kommt es sporadisch vor, dass der AD-Wert für eine Messung auf 
ca. 760 steigt und bei der nächsten wieder 180 ist.

Woran könnte dies liegen (der Sensor ist ausgeschlossen). Es ist eine 
externe Referenzspannung von 2,048V angelegt.

Der Code zum Auslesen sieht wie folgt aus:
1
ADMUX=(1 & 0x07) | (ADC_VREF_TYPE & 0xff);
2
if (1 & 0x08) ADCSRB |= 0x08;
3
else ADCSRB &= 0xf7;
4
// Delay needed for the stabilization of the ADC input voltage
5
delay_us(10);
6
// Start the AD conversion
7
ADCSRA|=0x40;
8
// Wait for the AD conversion to complete
9
while ((ADCSRA & 0x10)==0);
10
ADCSRA|=0x10;
11
AD_value = ADCW;

Seht ihr einen Fehler?

von nicht (Gast)


Lesenswert?

Helene schrieb:
> Seht ihr einen Fehler?
Magic Numbers welche es schwer machen den Code bzw. die ADC-Config 
nachzuvollziehen. Bitshifts nutzen!

Ich mag mich irren (es ist noch früh), aber imho gibt 1 & x immer x. Was 
soll das?

von nicht (Gast)


Lesenswert?

KORREKTUR:
streiche: aber imho gibt 1 & x immer x.
ersetze durch: aber imho gibt 1 & x immer 1.
                                          ^^

von nicht (Gast)


Lesenswert?

Sorry für Dreifachpost, Kaffemaschine läuft schon...

Richtig ist: x & 1 gibt das LSB von x, also 0 oder 1.

von Anja (Gast)


Lesenswert?

Helene schrieb:
> Seht ihr einen Fehler?

Den Code blicke ich gerade nicht so. Also die typischen Fehler:

Du hast vergessen den Prescaler auf einen ADC-Takt von 50-200kHz 
einzustellen?
Die Quellimpedanz am ADC-Eingang ist > 10kOhm.
Die Quellimpedanz am VRef-Eingang ist zu hoch und kann den Strom nicht 
liefern?
Es fehlen 100nF Kondensatoren an VRef und oder dem ADC-Eingang?

Gruß Anja

von Helene (Gast)


Lesenswert?

Hallo,

vielen Dank für eure Antworten!

Ich habe den ADC-Takt nun auf 115,200 kHz gestellt (war vorher 921,600 
kHz).

Hier der Code der ADC-Initialisierung:
1
// ADC Clock frequency: 115,200 kHz
2
// ADC Voltage Reference: AREF pin
3
// ADC Auto Trigger Source: Free Running
4
// Digital input buffers on ADC0: On, ADC1: On, ADC2: On, ADC3: On
5
// ADC4: On, ADC5: On, ADC6: On, ADC7: On
6
DIDR0=0x00;
7
// Digital input buffers on ADC8: On, ADC9: On, ADC10: On, ADC11: On
8
// ADC12: On, ADC13: On, ADC14: On, ADC15: On
9
DIDR2=0x00;
10
ADMUX=ADC_VREF_TYPE & 0xff;
11
ADCSRA=0xA7;
12
ADCSRB&=0xF8;


Die anderen Fehler, kann ich ausschließen:
>Die Quellimpedanz am ADC-Eingang ist > 10kOhm.
Die Quellimpedanz am VRef-Eingang ist zu hoch und kann den Strom nicht
liefern?
Es fehlen 100nF Kondensatoren an VRef und oder dem ADC-Eingang?

Der Code müsste auch passen, da dieser vom Codevision-Compiler 
automatisch erzeugt wird.

Nun ist es so, dass ich meist einen AD-Wert von ca. 760 erhalte und 
sporadisch einen von ca. 188, obwohl sich am Sensorwert nichts geändert 
hat.

Ich habe die gleiche Situation an PF0, hier messe ich über einen 
Spannungsteiler meine Versorgungsspannung und erhalte meist den ACD-Wert 
760, dazwischen sporadisch 188.

von Karl H. (kbuchegg)


Lesenswert?

> Nun ist es so, dass ich meist einen AD-Wert von ca. 760 erhalte und
> sporadisch einen von ca. 188, obwohl sich am Sensorwert nichts geändert
> hat.
>
> Ich habe die gleiche Situation an PF0, hier messe ich über einen
> Spannungsteiler meine Versorgungsspannung und erhalte meist den ACD-Wert
> 760, dazwischen sporadisch 188.

Das klingt für mich aber sehr danach, dass du einmal ein falsches 
(altes) Ergebnis ausliest, dass eigentlich zum anderen Kanal gehört, 
oder dass du dich irgendwo in der Kanaleinstellung verhaut hast.

> Der Code müsste auch passen, da dieser vom Codevision-Compiler
> automatisch erzeugt wird.
>
> ADCSRA=0xA7;
> ADCSRB&=0xF8;
> if (1 & 0x08) ADCSRB |= 0x08;
> else ADCSRB &= 0xf7;
> // Delay needed for the stabilization of the ADC input voltage
> delay_us(10);
> // Start the AD conversion
> ADCSRA|=0x40;
> // Wait for the AD conversion to complete
> while ((ADCSRA & 0x10)==0);
> ADCSRA|=0x10;

Solange du dich mit diesem Bitgepfriemel zufrieden gibst, wird es auch 
schwer das auseibnander zu dröseln, welche BIts du tatsächlich setzt, 
bzw. wo du dich verhaut hast. Vergiss den Müll, den der Wizard erzeugt 
hat und schlüssle dir die Bits selber nach Namen auf. Hier im Forum wird 
das keiner für dich tun.

von nicht (Gast)


Lesenswert?

Helene schrieb:
> Hier der Code der ADC-Initialisierung:
>
1
> // ADC Clock frequency: 115,200 kHz
2
> // ADC Voltage Reference: AREF pin
3
> // ADC Auto Trigger Source: Free Running
4
> // Digital input buffers on ADC0: On, ADC1: On, ADC2: On, ADC3: On
5
> // ADC4: On, ADC5: On, ADC6: On, ADC7: On
6
> DIDR0=0x00;
7
> // Digital input buffers on ADC8: On, ADC9: On, ADC10: On, ADC11: On
8
> // ADC12: On, ADC13: On, ADC14: On, ADC15: On
9
> DIDR2=0x00;
10
> ADMUX=ADC_VREF_TYPE & 0xff;
11
> ADCSRA=0xA7;
12
> ADCSRB&=0xF8;
13
>
Immer noch Magic Numbers. :-(

DEUTLICH besser:
1
REGISTER = (1<<OPTIONSBIT1) | (1<<RST42) | (1<<ANDERESBIT);
 wobei die ganzen Bits Präprozessormakros sind und bereits fertig in 
irgendeinem Headerfile für den jeweilgen µC existieren.

Ist das '&' bei ADCSRB Absicht? Warum "&0xff"? (Bei 8 Bit ist das 
nutzlos.)

von Anja (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Das klingt für mich aber sehr danach, dass du einmal ein falsches
> (altes) Ergebnis ausliest, dass eigentlich zum anderen Kanal gehört,
> oder dass du dich irgendwo in der Kanaleinstellung verhaut hast.

Vermutlich läuft im Hintergrund noch eine ISR-Routine mit ADC.

Oder warum wird das Bit zum Starten des ADCs gesetzt und dann das Ende 
der Wandlung über das Interruptflag (und nicht das ADC conversion ready 
Flag) abgefragt?

Gruß Anja

von Helene (Gast)


Lesenswert?

DANKE für eure Hilfe!

Der Fehler lag in der Initialisierung:
ADCSRA=0xA7;
ADCSRB&=0xF8;

habe ich ersetzt durch
ADCSRA=0x87;   > ADATE auf 0 gesetzt

und schon funktioniert es....

von nicht (Gast)


Lesenswert?

Helene schrieb:
> Der Fehler lag in der Initialisierung:
> ADCSRA=0xA7;
> ADCSRB&=0xF8;
>
> habe ich ersetzt durch
> ADCSRA=0x87;   > ADATE auf 0 gesetzt
>
> und schon funktioniert es....
und man weiß trotzdem nicht was das genau tut.

Ich sags zum dritten Mal: KEINE MAGIC NUMBERS IM CODE
Verwende Bitshifts, dann sieht man auf den ersten Blick welche Bits 
gesetzt werden und findet fehlerhafte Konfigurationen deutlich 
schneller und mit deutlich weniger Aufwand.

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.