mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ADC XMega128A1


Autor: Thomass (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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){}
}

Autor: Ralfi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
x volatile machen.

Autor: Ralfi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und warum ist x ein double reicht nicht int.

Autor: GG (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Thomass (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Thomass (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie sieht dein Code denn jetzt aus? Poste doch noch mal mit den 
Verbesserungen.

Autor: Thomass (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
#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){}

}

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.