Ich versuche jetzt schon ein weilchen, den AD Wandler anzusprechen, aber ich schaffs einfach nicht. Zur Hardware, ein Mega8 (16 Mhz) und am PortC Pin1 hängt ein analoger Sharp Abstandssensor (0 - 3 V). Am Port D hängen alles LED's (leuchten bei Low). Irgendwie habe ich das Gefühl, das Problem liegt nicht bei der Hardware ... Hier mal mein Code, habe ich übrigens aus dem C Tutorial. #include <io.h> int main( void ) { long x; // Ich weiss wär nicht unbedingt nötig, aber lieber zu gross long x2; long wert; outp(0xff,DDRD); outp ((1<<ADEN) & 7,ADCSR); // Ad Wandler starten mit Vorteiler 128. while(1) { outp ((1<<PINC1),ADMUX); // Pin 1 an Port C auswählen outp((1<<ADSC),ADCSR); while (bit_is_set (ADCSR, ADSC)){}; x = inp(ADCL); x2 = inp(ADCH); x2 = x2*256; wert = x + x2; if (wert<150) outp(0x00, PORTD); else outp(0xff,PORTD); } } Kompiliert wird das ganze Fehlerfrei, aber der AD Wandler gibt immer 0 zurück. (Oder sonst ein sehr kleiner Wert...)
Soweit ich das sehe, solltest du ADIF nach dem Setzen von ADSC abfragen, wenn du den ADC im single-conversion mode betreibst um zu sehen, wenn die wandlung fertig ist. Oder du betreibst ihn im free-running mode, dann musst du ADFR im ADCSR setzen. Notker
Ok, also ich hab jetzt while (bit_is_set (ADCSR, ADSC)){}; durch while ((ADCSR, ADIF)== 0){}; Leider funktionierts immer noch nicht. Übrigens ist mir ein kleines Missgeschick passiert, ich habe Beim überprüfen Vcc direkt mit einem Pin verbunden. Überlebt das der AD Wandler ? Der Code sieht jetzt übrigens so aus: #include <io.h> int main( void ) { long x; // Ich weiss wär nicht unbedingt nötig, aber lieber zu gross long x2; long wert; outp(0xff,DDRD); outp ((1<<ADEN) & 7,ADCSR); // Ad Wandler starten mit Vorteiler 128. while(1) { outp ((1<<PINC1),ADMUX); // Pin 1 an Port C auswählen outp((1<<ADSC),ADCSR); while ((ADCSR, ADIF)== 0){}; x = inp(ADCL); x2 = inp(ADCH); x2 = x2*256; wert = x + x2; if (wert<150) outp(0x00, PORTD); else outp(0xff,PORTD); } }
Also ich habe das obige Programm nun mangels Zeit nicht testen können, sondern nur mal "optisch" geprüft. Das müsste so eigentlich funktionieren. Ich würde empfehlen, dass du den Code mal im AVR-Studio testest. Ich bin mir nun zwar nicht 100% sicher, aber ich glaube, man kann den analogen Eingang des ADC im AVR-Studio irgendwie simulieren, also irgendwie einen bestimmten Wert vorgeben und dann sehen, was der Code daraus macht. > Übrigens ist mir ein kleines Missgeschick passiert, ich habe Beim überprüfen Vcc direkt mit einem Pin verbunden. Überlebt das der AD Wandler ? Gute Frage, nächste Frage! Ich glaube, darauf wird dir niemand eine sichere Antwort geben können. Im Zweifelsfall sollte man immer einen Ersatz zur Hand haben, den man im Austausch mal testen kann. Notker
komischerweise funktioniert bei mir der ADWandler bei Prüfung auf ADIF auch nicht richtig. Ich erhalte viel zu hohe Werte. Wenn ich einfach eine genügend lange Warteschleife einfüge (wie lange steht im Datenblatt des AVR) gehts.
>Ok, also ich hab jetzt >while (bit_is_set (ADCSR, ADSC)){}; >durch >while ((ADCSR, ADIF)== 0){}; Ich bin zwar was C angeht nicht unbedingt ein Profi, aber wird hier nicht einfach der Wert von ADCSR ingoriert und dann überprüft ob ADIF null ist? Zum Nachvollziehen: 1.) Ausdruck=(ADCSR, ADIF) a) Kommaoperator bedeutet den Teilausdruck vor dem Komma einfach nicht ins Ergebnis einbeziegen. b) D.h. ADIF bleibt übrig c) In iom8.h steht #define ADIF 4 d) Das Ergebnis dieses Ausdrucks ist 4 2.) Prüfen ob 1.) gleich Null ist. Da 4!=0 wird daraus ne Endlosschleife Was meint ihr dazu? Hermann
Stimmt, er hat beim zweiten Entwurf das bit_is_set vor der Klammer vergessen. Ist mir auch jetzt erst aufgefallen. Also das mit dem Komma-Operator ist eine interessante Theorie, war aber wohl so bestimmt nicht beabsichtigt ;-) frohes Fest Notker
Hmm, also das wegen dem Komma, das hab ich einfach vom C Tutorial übernommen. Dort steht : while (bit_is_set (ADCSR, ADSC)) Beim 2. Versuch hab ich ja ADSC mit ADIF ersetzt, dazu steht im C Tut: ADIF ADC Interrupt Flag Dieses Bit wird vom ADC gesetzt wenn eine Umwandlung erfolgt und das ADC Data Register aktualisiert ist. dann muss ich ja nicht warte während es gesetzt ist, sondern solange es nicht gesetzt ist ! Das mit der Warteschleife hab ich auch probiert, funktioniert leider auch nicht ...
>dann muss ich ja nicht warte während es gesetzt ist, sondern >solange es nicht gesetzt ist ! Dann nimm halt "loop_until_bit_is_set". Hermann
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.