Hi!
ich probiere gerade den Status eines Schalters am ADC7 Pin des 328P mit
dem ADC abzufragen.
Ich benutze folgenden Code:
1
//Startet und konfiguriert den ADC.
2
intADCKonfiguration(void)
3
{
4
//ADC Multiplexer auf ADC7 pin einstellen
5
sbi(ADMUX,MUX2);
6
sbi(ADMUX,MUX1);
7
sbi(ADMUX,MUX0);
8
9
//ADLAR im ADMUX Register auf 1 setzen. Dadurch wird das 10bittige Ergebnis linksbündig in den Registern ADCH und ADCL gespeichert.
10
sbi(ADMUX,ADLAR);
11
12
//ADC einschalten
13
sbi(ADCSRA,ADEN);
14
//Eine Messung durchführen
15
sbi(ADCSRA,ADSC);
16
}
17
18
19
//Ließt den ADC7 Pin aus und gibt die 8 hochwertigsten Bits zurück.
20
intADC7Read(void)
21
{
22
//ADC Conversion starten:
23
sbi(ADCSRA,ADSC);
24
25
returnADCH;
26
}
Leider gibt mit die Funktion ADC7Read immer 255 zurück. Auch wenn ich
den Pin mit einer Drahtbrücke direkt auf Masse ziehe. Einen Defekt in
der Schaltung kann ich also fast ausschließen.
Stimmt die Initialisierung des ADCs soweit? Hab ich evtl. einen falschen
Modus verwendet oder ein Register vergessen?
Ist mein "erstes Mal" mit dem ADC ;-)
Grüße und Danke!
Warum?
Ein Schalter ist ein/aus, 1/0, true/false - binär halt.
Kannst Du trivial ohne ADC einlesen.
Was möglicherweise das Problem mit dem ADC ist: der braucht ein bisschen
Zeit, Du kannst nicht sofort das Ergebnis lesen nachdem Du eben erst
einen Umsetzungs-Zyklus gestartet hast. Siehe Beschreibung des ADC im
Manual. Ob Deine Initialisierung für den ADC vollständig/korrekt ist -
keine Ahnung, habe ich nicht gecheckt, aber wieder, siehe Manual.
Hey Mike,
ich geh mal davon aus du willst unabhängig von der Sinnhaftigkeit
trotzdem den ADC verwenden. Schau dir doch mal hier auf der Seite das
AVR-Tutorial zum Thema ADC an, so ein µC hat praktischerweise FLAGs die
dir sagen ob/wann der ADC mit samplen/wandeln fertig ist.
Einen einzelnen Wert messen ist ja immer so eine Sache, da werden aus
einem 8-Bit ADC gerne mal 7 oder 6 oder weniger? Besser ein array voll
mit werten sammeln und dann mal schauen was drin steht, da lernst du
eine ganze menge.
bis dahin beste grüße
public
Mike Litoris schrieb:> //ADC Multiplexer auf ADC7 pin einstellen> sbi(ADMUX, MUX2);> sbi(ADMUX, MUX1);> sbi(ADMUX, MUX0);>> //ADLAR im ADMUX Register auf 1 setzen. Dadurch wird das 10bittige> Ergebnis linksbündig in den Registern ADCH und ADCL gespeichert.> sbi(ADMUX, ADLAR);
Wie bist du denn auf diese Idee gekommen? Das geht alles viel einfacher
und in einer Zeile, ohne irgendwelche Verrenkungen:
1
ADMUX=(1<<ADLAR)|(7<<MUX0);
2
// oder
3
ADMUX=(1<<ADLAR)|(1<<MUX2)|(1<<MUX1)|(1<<MUX0);
Selbst in Assembler würde man nicht auf die Idee kommen, das alles mit
sbi zu lösen:
Jasch schrieb:> Ein Schalter ist ein/aus, 1/0, true/false - binär halt.>> Kannst Du trivial ohne ADC einlesen.
Ja, soweit bin ich mit meinen Kentnissen schon...
Geht aber in dem Falle nicht anders, da sonst keine Pins frei sind.
Frank schrieb:> Es muss gewartet werden bis die ADC Wandlung abgeschlossen ist!> Schau dir mal die Codebeispiele zum ADC an.
ok, danke für den Tipp. Ich erninnere mich, dass dazu im Datenblatt was
stand. Hab dem aber für meine Zwecke keine bedeutung zugemessen, da das
ja nicht zeitkritisch ist...
Grüße!
Mike Litoris schrieb:> //Ließt den ADC7 Pin aus und gibt die 8 hochwertigsten Bits zurück.> int ADC7Read(void)> {> //ADC Conversion starten:> sbi(ADCSRA, ADSC);>> return ADCH;> }
Wenn die Wandlung gestartet wird, muss du auch warten, bis sie fertig
ist. Den Wert kannst du nicht sofort auslesen.
mfg.
public schrieb:> Ey sach mal dein Name "mike litoris" ist ja wohl nen bissl frech wa?
Und du bist so katholisch das es selbst dem Papst peinlich wäre ;)
SCNR
Matthias Sch. schrieb:> Wie bist du denn auf diese Idee gekommen? Das geht alles viel einfacher> und in einer Zeile, ohne irgendwelche Verrenkungen:ADMUX = (1 <<> ADLAR)|(7 << MUX0);> // oder> ADMUX = (1 << ADLAR)|(1 << MUX2)|(1 << MUX1)|(1 << MUX0);
Ja das sieht natürlich besser aus. Gehen sollte es aber auch auf meinen
Weg, oder?
Thomas Eckmann schrieb:> Wenn die Wandlung gestartet wird, muss du auch warten, bis sie fertig> ist. Den Wert kannst du nicht sofort auslesen.
Wurde ja schon öfter angemerkt, hab ich ergänzt:
1
//Startet und konfiguriert den ADC.
2
intADCKonfiguration(void)
3
{
4
//ADC Multiplexer auf ADC7 pin einstellen
5
sbi(ADMUX,MUX2);
6
sbi(ADMUX,MUX1);
7
sbi(ADMUX,MUX0);
8
9
//ADLAR im ADMUX Register auf 1 setzen. Dadurch wird das 10bittige Ergebnis linksbündig in den Registern ADCH und ADCL gespeichert.
10
sbi(ADMUX,ADLAR);
11
12
//ADC einschalten
13
sbi(ADCSRA,ADEN);
14
//Eine Messung durchführen
15
sbi(ADCSRA,ADSC);
16
}
17
18
19
//Ließt den ADC7 Pin aus und gibt die 8 hochwertigsten Bits zurück.
20
intADC7Read(void)
21
{
22
//ADC Conversion starten:
23
sbi(ADCSRA,ADSC);
24
25
//Warten bis ADWandlung fertig.
26
while(ADCSRA&(1<<ADSC))
27
28
//Eingelesenen Wert zurückgeben.
29
returnADCH;
30
}
Welche Werte in welches Register kommen, stimmt "eigentlich" mit dem
Datenblatt überein. Kann da evtl. mal jemand drüberschauen?
Grüße!
public schrieb:> Ey sach mal dein Name "mike litoris" ist ja wohl nen bissl frech wa?
Ey sach mal hast du damit ein Problem? Kannst gerne vorbeikommen!
Hallo Mike Litoris schrieb:> //Warten bis ADWandlung fertig.> while (ADCSRA & (1<<ADSC))
Hier ist noch ein Fehler, es fehlt der While-Block
Entweder als { } oder als ;
In Init der ADC-Funtion schreibst Du:
1
//Eine Messung durchführen
2
sbi(ADCSRA,ADSC);
Aber diese Anweisung ist keine Messung, sondern nur das starten einer
ADC-Messung.
Man muss auch das Ende abwarten und denn ADC-Messwert auslesen.
Mike Litoris schrieb:>> Ey sach mal dein Name "mike litoris" ist ja wohl nen bissl frech wa?> Ey sach mal hast du damit ein Problem? Kannst gerne vorbeikommen!
"Kannst gerne kommen!" hätte es heißen müssen. Manchmal könnte man an
dieser Welt und ihren Insassen verzweifeln.
Hallo Uwe, danke für deine Antwort!
Du hast natürlich Recht, dass da die Klammer fehlt. Ist mir direkt nach
dem Absenden aufgefallen.
Wegen dem Starten der Messung in der InitFunktion:
Ich starte dort schonmal eine Messung, weil die erste Messung immer
mehrere Takte braucht. Ausgelesen wird das Ergebnis dieser Messung nie.
Im Programm Frage ich den Taster mit der ADC7Read Funktion ab, dort wird
auch das ADCH Register zurückgegeben.
Grüße!