Hallo alle zusammen, ich habe ein kleines Problem mit dem AD Wandler beim XMega128A1. Ich möchte dass mir der angelegte Spannungswert an PortA Pin0 mit dem AD Wandler ausgewertet wird. Leider verändert sich der angezeigte Wert nicht (der Wert bleibt gleich) in Abhängigkeit von der angelegten Spannung. Das heißt der Quellcode müsste fehlerhaft sein. Leider finde ich den Fehler nicht. Kann mir jemand helfen? Vielen Dank im Voraus :) Mein Quellcode: #include <avr/io.h> #include <avr/interrupt.h> double x= 0; unsigned char temp; void adc_init(void) { ADCA.CTRLA = 0x41; ADCA.CTRLB = 0x04; ADCA.REFCTRL = 0x02; ADCA.EVCTRL = 0x00; ADCA.PRESCALER = 0x00; ADCA.CH0.CTRL = 0x00; ADCA.CH0.MUXCTRL = 0x00; ADCA.CH0.INTCTRL = 0x03; PMIC.CTRL = 0x07; sei(); } void Osi_init(void) { OSC.CTRL =3; while(OSC.STATUS != 3); CCP = 0xD8; CLK.CTRL = 1; } ISR(ADCA_CH0_vect) { temp = ADCA.CH0.RES; x = (double)temp; ADCA.CH0.CTRL = 0x80; } int main(void) { PORTA.DIRCLR = 0xff; adc_init(); Osi_init(); ADCA.CH0.CTRL = 0x80; while(1){} }
Hallo, Du mußt das Ergebniss-Register zeimal lesen, zuerst High dann Low. So ähnlich: tmp = ADCA.CH0.RESL; tmp += ADCA.CH0.RESH<<8; sum += tmp; Gruß GG
Hallo, vielen Dank für Eure Hilfe. Habe die Variable volatile deklariert (volatile int x reicht natürlich auch aus!) sowie das RESH und RESL Register ausgelesen. Der Fehler bleibt aber leider dennoch derselbe: Bei angelegten 0V wird z.B der Wert x= 100 ausgelesen. Bei 0,7V wird ebenfalls x=100 ausgelesen. Wie kann das sein?Woran kanns noch liegen?
Das mit dem .RES ist schon völlig in Ordnung so, das braucht man nicht einzeln auslesen. Was mir aber zuerst mal spanisch vorkommt ist, dass du für das Ergebnis des Wandlers ein unsigned char bereitstellst. Dann würde ich dir nahe legen statt 0x41 lieber Bitnamen zu benutzen. Wofür aktivierst du denn die DMA Unterstützung überhaupt? In CTRLA braucht erst mal nur das ENABLE gesetzt zu werden. Dann stellst du den Wandler auf 8 Bit, das heißt, du musst NUR das RESL Register für deinen 8 Bit Wert auslesen. Außerdem setzt du nicht das Free Running Bit. Das heißt, du musst den Wandler vor jeder Wandlung auch aktivieren, damit er wandelt. PRESCALER ist bei dir auf /4 gesetzt. Mit welchem Takt läuft dein Prozessor? Das könnte einen zu schnellen ADC Takt ergeben. Außerdem setzt du das Channel Control Register komplett auf 0, das heißt, du misst nicht am Ausgangspin, sondern du musst eine interne ADC Quelle. Und was hat der PMIC eigentlich damit zu tun? Preisfrage: Hast du dir überhaupt mal das Datenblatt angeguckt? Dein Code macht nicht mal annähernd das, was du möchtest.
danke erstmal, also habe deine Hinweise soweit umgesetzt. Ich habe einen internen Takt von 32KHZ eingestellt. Und ja habe mir das Manual angeguckt ;) Irgendwie bekomme ich das trotz deiner Hinweise nicht hin. Es wird immer noch der selbe Wert bei verschiedenen Spannungswerten angezeigt. Wenn ich so falsch mit meinem Programm liege (bin ja auch Anfänger),wärst du so nett und könntest hier den richtigen Code pinnen? Danke schon mal
#include <avr/io.h> #include <avr/interrupt.h> volatile int temp = 0; void Osi_init(void) { OSC.CTRL =7; //interner 32KHz Oszillator while(OSC.STATUS != 7); CCP = 0xD8; CLK.CTRL = 0; } void adc_init(void) { ADCA.CTRLA = 0x01; ADCA.CTRLB = 0x0C; ADCA.REFCTRL = 0x02; ADCA.EVCTRL = 0x00; ADCA.PRESCALER = 0x00; //PRescaler = 4 ADCA.CH0.CTRL = 0x00; ADCA.CH0.MUXCTRL = 0x00; ADCA.CH0.INTCTRL = 0x03; PMIC.CTRL = 0x07; //gibt Interrupt Level frei sei(); } ISR(ADCA_CH0_vect) { temp = ADCA.CH0.RESL; } int main( void ) { PORTA.DIRCLR = 0x00; adc_init(); Port_init(); Osi_init(); ADCA.CH0.CTRL = 0x80; while(1){} }
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.