Forum: Mikrocontroller und Digitale Elektronik Problem mit XEMGA ADC


von Johann (Gast)


Lesenswert?

Hallo Leute,

ich verwende einen XMEGA32a4u von Atmel. Hier möchte ich 8 Eingänge 
digitalisieren.

Bei 1 Kanal hat dies auch funktioniert. Jedoch leider nicht bei den 
anderen Kanälen. Ich habe eine Funktion geschrieben. Diese startet die 
Digitalisierung bei 4 Kanälen.

// Start the AD conversion on channel 0, 1 ,2 ,3
ADCA.CTRLA |= 0x3C;

//Kanal 0 --> digitalisiert PA0
//Kanal 0 --> digitalisiert PA1
//Kanal 0 --> digitalisiert PA2
//Kanal 0 --> digitalisiert PA3

Ich überpprüfe nachdem ich die Digitailiserung gestartet habe ob die 
Interruptflags gesetzt sind.

// Wait for the AD conversion to complete
while ((ADCA.INTFLAGS & 0x0F) == 0);

Wenn dies der Fall ist dann lösche ich die Flags und lese anschließend 
die Daten aus den Result Registern aus.

// Clear the interrupt flag
ADCA.INTFLAGS = 0x0F;

// Read Data
new_adc_sample[0] = ADCA.CH0.RESH;
new_adc_sample[1] = ADCA.CH0.RESL;
new_adc_sample[2] = ADCA.CH1.RESL;
new_adc_sample[3] = ADCA.CH1.RESL;
new_adc_sample[4] = ADCA.CH2.RESH;
new_adc_sample[5] = ADCA.CH2.RESL;
new_adc_sample[6] = ADCA.CH3.RESL;
new_adc_sample[7] = ADCA.CH3.RESL;

Kanal 1 liefert das richtige Ergebnis, nur die anderen Kanäle 
funktionieren nicht.

Ich habe die 4 Kanäle wie folgt konfiguriert:

ADCA.CH0.MUXCTRL = ADC_CH_MUXPOS_PIN0_gc;  // 0x00;
ADCA.CH1.MUXCTRL = ADC_CH_MUXPOS_PIN1_gc;  // 0x10
ADCA.CH2.MUXCTRL = ADC_CH_MUXPOS_PIN2_gc;  // 0x20
ADCA.CH3.MUXCTRL = ADC_CH_MUXPOS_PIN3_gc;  // 0x30

von Gerhard G. (g_g)


Lesenswert?

Hallo,

du musst die Reihenfolge beachten.
Siehe folgenden Code. Der ist Bestandteil meiner Programmierung.

. Channel bestimmen
. Wait for the AD conversion to complete
. Ergebnis weiterreichen
. nächster Cannel


// ADCA channel data read function using polled mode
signed int adca_read(unsigned char channel)
{
  ADC_CH_t *pch=&ADCA.CH0+channel;
  signed int data;

  // Start the AD conversion
  pch->CTRL|=ADC_CH_START_bm;
  // Wait for the AD conversion to complete
  while ((pch->INTFLAGS & ADC_CH_CHIF_bm)==0);
  // Clear the interrupt flag
  pch->INTFLAGS=ADC_CH_CHIF_bm;
  // Read the AD conversion result
  ((unsigned char *) &data)[0]=pch->RESL;
  ((unsigned char *) &data)[1]=pch->RESH;
  // Compensate the ADC offset
  return data;
}


Den Befehl für die Reihenfolge der Ad-Wandlungen sollte auch nicht 
vergessen werden!

// ADC is free-running, sweeped channel(s): 0, 1, 2, 3
ADCA.EVCTRL=ADC_SWEEP_0123_gc| ADC_EVACT_NONE_gc;



Gruß G.G.

von Johann (Gast)


Lesenswert?

Dein Programm habe ich nicht so ganz verstanden. Du hast eine Funktion 
geschrieben, die einen Kanel enthält mit dem gestart werden soll.

Anschließend startest Du die Digitalisierung. Wie viele Messwerte werden 
denn nun wirlich aufgenommen?

Wenn ich mir den Qellcode anschaue dann wird ja nur 1 mal die 
Digitalisierung gestartet und es gibt nur ein return Wert.

Warum betreibst Du die Wandler dann im Free Running Mode?

von Gerhard G. (g_g)


Angehängte Dateien:

Lesenswert?

Hallo,

das war nur noch ein Überbleibsel vom vorherigen Code.

bei mir ADC_SWEEP_01_gc ist für die laufenden Wandlungen (Channel 0-3) 
nötig.

while ((pch->INTFLAGS & ADC_CH_CHIF_bm)==0); ist für jeden Channel 
auszuführen!

Siehe Anlage(zur Inspiration), DMA ist nicht erforderlich.

Gruß G.G.

von Johann (Gast)


Lesenswert?

Ist ja schon geil was der XMEGA kann. Der kann alleine die Channels 
wechseln und dann direkt per DMA die Datan in den RAM schreiben und dann 
auch automatisch per UART verschicken.

Nur habe ich davon immer Abstand gehalten da man dies nicht wirklich gut 
debuggen kann. Wie kann man da denn noch den Fehler eingrenzen.

Meine Version funktioniert jetzt auch hatte nur den Code falsch am PC 
zusammengesetzt :-)

Aber ich werde mir Deinen Quellcode auch noch mal anschauen

von Johann (Gast)


Lesenswert?

Ich habe da immer so digitale Sprünge bei mir das kommt mir komisch vor. 
Ich weis jedoch nicht vorher das kommt :-(

von jo (Gast)


Lesenswert?

>data = (data/6);

Warum nimmst du nicht 8 Zahlen für die Mittelwertbildung? Dann kann der 
Compiler aus der Division eine shift-operation machen und keine teure 
division.

GRuß Jonas

von Johann (Gast)


Lesenswert?

Hat denn auch schon mal jemand diese digitalen Sprünge gehabt?

Ich habe auch die Frequenz deutlich langsamer (65kHz) gemacht. Dies mach 
leider keinen Unterschied.

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
Noch kein Account? Hier anmelden.