Forum: Mikrocontroller und Digitale Elektronik xMega32 Mehr als 4 ADC Channel


von Dominik Gausa (Gast)


Lesenswert?

Hallo Forum,

Ich habe derzeit einen xMega32A4 in benutzung um die Sensoren für eine 
Flugdrone auszuwerten. Dabei muss ich insgesamt 8 Spannungen abfragen.

Nun ist das Problem, das ich über das Eventsystem nur die 4 Channel 
ansprechen kann, deren Pin ich nicht so einfach ändern kann.

Ein "Manuelles" wechseln und Wandeln der Pins möchte ich umgehen.

Source der Main:
http://paradox-works.net/websvn/filedetails.php?repname=OpenUAV+OS&path=%2FUAV-Sensor%2FUAV-Sensor.c

Inits für Eventctrl:
http://paradox-works.net/websvn/filedetails.php?repname=OpenUAV+OS&path=%2FUAV-Sensor%2Fconverter.c

Klasse für manuelles Switchen:
http://paradox-works.net/websvn/filedetails.php?repname=OpenUAV+OS&path=%2FUAV-Sensor%2Fmeasure.hpp

Beim Nutzen des manuellen Wandelns bekomme ich teils irreale Messwerte 
oder noch die Messwerte des Pins vorher.

Über Hilfe würde ich mich freuen!

von Praktiker (Gast)


Lesenswert?

Die MUXe brauchen eine Zeit, um die Quelle umzuschalten. Außerdem muss 
der A/D-Wandler sich erst auf den neuen Wert einstellen, dauert bei 
sukzessiver Approximation ne Weile. Guck ins Datenblatt, das erklärt das 
von die beschriebene Verhalten.

von Hans W. (hans_w30)


Lesenswert?

Hy ich hab jetzt flüchtig nur gesehen das du als Referenz PORTA Ref Pin 
0 gewählt hast. Was für ne Spannung hast du da angeschlossen?

Also Tipp die Seite von Stromflo erklärt echt gut fast alle Grundlagen 
des XMEGA (wobei er manchmal Werte nimmt und nicht wie es schöner ist 
die bit Masks oder gc).
http://www.stromflo.de/dokuwiki/doku.php?id=xmega-c-tutorial#adc

Gruß Hans

von Dominik Gausa (Gast)


Lesenswert?

Danke für die Tipps !

Im DB steht leider nicht wirklich etwas über die Zeit die zwischen dem 
umMuxen vergehen sollte. :/

Das Tut von StromFlow ist super, habe damit auch angefangen gehabt, nur 
geht es dort auch nicht um mehr als 4 Channels.

Am RevA Liegt 3V3 an, mit der auch die Sensoren gespeist werden. Deren 
Spannungen liegen dann zwischen 0V und 3V3.

Ich habe nun folgendes gemacht:

Aus dem DB geht hervor das eine 12Bit Wandlung bei 32MHz ~3.5µs dauert.
Das gibt genug Zeit um alle 1ms mal nen Wert zuholen (getestet bis 
runter auf 100µs) und nach dem Auslesen die Mux zuändern.

Habe nun also einen Timer, der mit die Werte Einliest und dann umMuxt. 
Kann die Letzten Werte dann aus einem Array auslesen.

(Alles noch bissel unschön und mit viel Code)

void timerC0_init(void){   // 1ms
  TCC0.PER = 30;
  TCC0.CTRLA |= TC_CLKSEL_DIV1024_gc;
  TCC0.INTCTRLA |= TC_OVFINTLVL_HI_gc;
  }

volatile char stat = 0;
ISR (TCC0_OVF_vect){
  if(stat == 0) {
    while(!ADCA.CH0.INTFLAGS);
        values[4] = ADCA_CH0RES;
    while(!ADCA.CH1.INTFLAGS);
        values[5] = ADCA_CH1RES;
    while(!ADCA.CH2.INTFLAGS);
        values[6] = ADCA_CH2RES;
    while(!ADCA.CH3.INTFLAGS);
        values[7] = ADCA_CH3RES;

    ADCA.CH0.MUXCTRL = ADC_CH_MUXPOS_PIN0_gc;
    ADCA.CH1.MUXCTRL = ADC_CH_MUXPOS_PIN1_gc;
    ADCA.CH2.MUXCTRL = ADC_CH_MUXPOS_PIN2_gc;
    ADCA.CH3.MUXCTRL = ADC_CH_MUXPOS_PIN3_gc;
    ADCA.CTRLA = ADC_FLUSH_bm |1;
    ADCA.CH0.CTRL = ADC_CH_START_bm | ADC_CH_INPUTMODE0_bm;
    ADCA.CH1.CTRL = ADC_CH_START_bm | ADC_CH_INPUTMODE0_bm;
    ADCA.CH2.CTRL = ADC_CH_START_bm | ADC_CH_INPUTMODE0_bm;
    ADCA.CH3.CTRL = ADC_CH_START_bm | ADC_CH_INPUTMODE0_bm;

    stat = 1;
  } else {
    while(!ADCA.CH0.INTFLAGS);
        values[0] = ADCA_CH0RES;
    while(!ADCA.CH1.INTFLAGS);
        values[1] = ADCA_CH1RES;
    while(!ADCA.CH2.INTFLAGS);
        values[2] = ADCA_CH2RES;
    while(!ADCA.CH3.INTFLAGS);
        values[3] = ADCA_CH3RES;

    ADCA.CH0.MUXCTRL = ADC_CH_MUXPOS_PIN4_gc;
    ADCA.CH1.MUXCTRL = ADC_CH_MUXPOS_PIN5_gc;
    ADCA.CH2.MUXCTRL = ADC_CH_MUXPOS_PIN6_gc;
    ADCA.CH3.MUXCTRL = ADC_CH_MUXPOS_PIN7_gc;
    ADCA.CTRLA = ADC_FLUSH_bm | 1;
    ADCA.CH0.CTRL = ADC_CH_START_bm | ADC_CH_INPUTMODE0_bm;
    ADCA.CH1.CTRL = ADC_CH_START_bm | ADC_CH_INPUTMODE0_bm;
    ADCA.CH2.CTRL = ADC_CH_START_bm | ADC_CH_INPUTMODE0_bm;
    ADCA.CH3.CTRL = ADC_CH_START_bm | ADC_CH_INPUTMODE0_bm;

    stat = 0;
    }
}

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.