Hallo, ich hab hier das AVR-P8-Board von Olimex mit einem Mega8 und versuche meine ersten Schritte in der AVR-Programmierung zu machen. Led-Blinken, Taster einlesen und Timer laufen lassen hat bei mir auch alles schon gut geklappt. Jetzt würde ich gerne mal den ADC ausprobieren. Aber das will nicht so richtig. Aus irgendeinem Grund steht in den Registern ADCL und ADCH nie was drin. Wäre nett wenn mal jemand über den angehängten C-Code gucken könnte. Danke, mfg Michi
>ADCSRA = 0x80; //AEDC enable äusserst schlechte Schreibweise. Nimm lieber die Bit-Namen-Schreibweise "(1<<ADEN)". Oder so. CLI und SEI sind in der ISR völlig unnötig, da der AVR andere Interrupts von sich aus sperrt, wenn eine ISR abgearbeitet wird. Die Register "ADCL" und "ADCH" werde auch zu "ADCW" vom Type unsigend int zusammengefasst. Hättest du die Bit-Namen verwendet (und vielleicht auch den einen oder anderen Blick ins gcc-Tutorium geworfen), dann wäre dir vielleicht aufgefallen, dass du auch noch das "ADSC" oder "ADFR§-Bit hättest setzen müssen.
OK, die Schreibweise mag schlecht sein, aber das ADSC-Bit wird gesetzt. Wenn der ADC mit der Wandlung fertig ist, springt mein Programm auch artig in die ISR. Nur es steht halt kein Ergebnise in ADCL und ADCH.
>Nur es steht halt kein Ergebnise in ADCL und ADCH.
Da nicht oder in deinem ADC_Wert?
Schreib mal ein volatile zur Variablendeklaration.
Die Register sind tatsächlich leer und damit natürlich meine Variable ADC_Wert auch.
Oder kann das vielleicht auch mit dem Debug-Modus im AVR-Studio-4 zu tun haben? Ich starte das Programm nach dem Übertragen immer uns setzte dann den Cursor vor "ADC_Wert = ADCL;" und lasse das Programm dann mit "Run to Cursor" laufen.
Dass die von dir gewählte Schreibweise (ADCSRA = 0x88) nicht gut lesbar ist wurde ja bereits erwähnt.
1 | ADCSRA = (1<<ADEN) | (1<<ADIE); |
liest sich doch viel besser. Wie man hier gleich sieht, setzt du keinen Prescaler. Der ADC braucht eine Frequenz von 50 kHz bis 200 kHz um vernünftige Ergebnisse zu liefern. Ich denke mal, die wird mit einem PS von 2 (PS2:0 = 0) nicht erreicht werden. Du liest brav ADCL vor ADCH aus, leichter geht es natürlich wenn du gleich
1 | ADC_Wert = ADC; |
hinschreibst (ADC = ADCW, da in Assembler der Registername ADC bereits vergeben ist). Du prüfst übrigens in deiner Timer0 ISR auch nicht, ob eine Wandlung gerade läuft bevor du eine neue startest. ADC_wert sollte übrigens als volatile gesetzt werden, also
1 | volatile uint16_t ADC_Wert; |
. Das ist mir mal beim Drüberlesen aufgefallen. LG
wenn du das ADCH bzw. ADCL Register schon selbst auslesen möchtest dann solltest du auch das 16Bit breite Ergebnis richtig zusammensetzten. So wie es jetzt ist, addierst du nur die beiden Register mit Überlauf - Glückwunsch ;-) Mach es so wie Christopher schon geschrieben hat:
1 | ADC_Wert = ADC; |
Grüße Timo
Guten Morgen, so ich hab das Programm jetzt noch einmal neu geschrieben in einer hoffentlich besser zu lesenden Form. Leider bekomme ich von meinem ADC aber immer noch keine Ergebnisse :-( Gruß Michi
Hallo, Michi schrieb: > > Leider bekomme ich von meinem ADC aber immer noch keine Ergebnisse :-( > Aus irgendeinem Grund steht in den Registern ADCL und ADCH nie was drin. >Die Register sind tatsächlich leer... Da das hier mehrfach so formuliert wurde: Ein Register kann NIE leer sein. Es kann Werte zwischen 0x00 und 0xFF enthalten und jeder dieser Werte ist eben ein Inhalt. Ansonsten sehe im letzten Source nichts, was irgendwo Werte ausgibt? Gruß aus Berlin Michael
Mit nichts meine ich 0x00. Ich habe aber an PIN1 von PortC eine Spannung von 1,05V liegen. Da ich als Referenzspannung VCC (=5V) gewählt habe, müsste der ADC als in etwa einen Wert von 216 (dezimal) ausgeben. Den Wert gebe ich auch nirgends direkt aus, sondern schreibe ihn in die Variable ADC_Wert. Aber und die schaue ich mir dann im Debug-Modus im AVR-Studio an.
Michi schrieb: > ... Aber und die schaue ich mir dann im Debug-Modus im > AVR-Studio an. ??? Der Mega8 hat weder DebugWire noch JTAG, was willst Du da also sehen? Gruß aus Berlin Michael
Hi >Den Wert gebe ich auch nirgends direkt aus, sondern schreibe ihn in die >Variable ADC_Wert. Aber und die schaue ich mir dann im Debug-Modus im >AVR-Studio an. Mit welchem Debugger? JTAG ICE MKII/AVR Dragon? MfG Spess
Jetzt hab ichs endlich verstanden. Ich benutze das USB-Prog aus dem AVR Starterkit vom embedded-shop. Das was ist im Debug-Modus gesehen habe war nur der Simulator vom AVR-Studio welcher den ADC natürlich nur sehr eingeschränkt simulieren kann. Ich hab das Programm jetzt noch etwas erweitert, so das wenn der ADC_Wert eine bestimmte Schwelle überschreitet eine LED eingeschaltet wird und siehe da, es geht :-) Ich weis, ich hab mich doof angestellt, dafür aber jetzt immerhin was gelernt. Danke für eure Hilfe und Geduld ;-) mfg michi
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.