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
elseADCSRB&=0xf7;
4
// Delay needed for the stabilization of the ADC input voltage
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?
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
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.
> 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.
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.)
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
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....
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.