Xmega ADC verhaut sich um 25 LSB. Hilfe

Gast #1715416
Lesenswert?

Hallo,

ich teste einen ATxmega 128A1 Board von Alvidi und bin gerade bei ADC.
Das Ziel wäre 8 Kanäle mit 8bit Auflösug innerhalb von 80us abtasten, 
aber ich scheitere schon am Anfang.
Mein Problem ist, das xmega tut nicht das was ich erwarte.
Offset liegt bei 11 LSB in Differential Mode und ca. 90LSB im 
Singleended Mode.  Kann mir schlecht vorstellen, dass 90LSB bei 8bit 
Auflösung ok ist.
//Alle 4 Kanäle auf GND.
> adc_ch0 =     10 digits
> adc_ch1 =     11 digits
> adc_ch2 =     11 digits
> adc_ch3 =     11 digits

Weiter schlechter.
Wenn ich an einen Kanal Spannung anlege, gibts einen riesen Fehler.
> adc_ch0 =     10 digits
> adc_ch1 =     11 digits
> adc_ch2 =     11 digits
> adc_ch3 =     192 digits  // Sollwert 135

Falls ich alle 4 Kanäle an eine Spannung lege, kriege ich nur noch Käse.
// Sollwert 135
> adc_ch0 =     255 digits
> adc_ch1 =     215 digits
> adc_ch2 =     170 digits
> adc_ch3 =     136 digits

VCC ist stabil 3,292V.

Ich komme einfach nicht weiter, bitte um Ihre Ratschläge/Hilfe.
Angehängte Dateien:
Gast #1715546
Lesenswert?

wt schrieb:

>und du bist sicher, daß deine zu messende Spg. immer kleiner als Vcc/1,6
>und liegt stabil an? mit Oszi geprüft?
LM
Hatte heute keinen Oszi dabei, habe mit einem Multimeter 1,09V gemessen.
Die Spannung habe ich am Spannungsteiler von Vcc abgegriffen.
Vcc 3,292V von einem LM85 (3,3V Festspannung).

Ist was im Code verdächtigt?
Gast #1715565
Lesenswert?

Den code habe ich nicht analysiert

Du kannst aber gerne mit meiner Init vergleichen

void HAL_InitAdc(void)
{
  // Max. ADC Geschwindigkeit 2Msps
  ADCA.PRESCALER = 0b00000010 & ADC_PRESCALER_gm;

  // Setze ch0 Mode auf SINGLE_ENDED
  ADCA.CH0.CTRL = ADC_CH_INPUTMODE_SINGLEENDED_gc;

  // CH0 MUX -> ADC1
  ADCA.CH0.MUXCTRL = (1 << ADC_CH_MUXPOS_bp);

  // Reference AREF PortA
  //ADCA.REFCTRL |= (0x02 << ADC_REFSEL_bp);

  // Reference interne Vcc/1.6V
  ADCA.REFCTRL |= (0x01 << ADC_REFSEL_bp);

  // Reference interne 1V
  //ADCA.REFCTRL |= (0x00 << ADC_REFSEL_bp);

  // Enable ADC Module
  ADCA.CTRLA = ADC_ENABLE_bm;
}

void HAL_StartAdcConv(void)
{
  ADCA.CH0.CTRL |= ADC_CH_START_bm;
}

u16  HAL_GetAdcConvResult(void)
{
  return ADCA.CH0.RES;
}


Ich denke jedoch, daß Du ehe HW Problem hast. Der Multimeter als Ref. 
kannst Du vergessen. Die Schwankungen im 50mV Bereich bekommst du gar 
nicht mit.
Gast #1716286
Lesenswert?

Hallo,

habe Vcc angeguckt, AC lieg bei 4mV.

2 wt

habe deinen Code ausprobiert, nur etwas geändet, Compiler akzeptiert _bp 
nicht, bzw. findet im iox128a1.h nicht. Habe im Simulator kontroliert, 
alles wird gesetz. Es kommt trozdem nur Unsinn raus.

z.B. Spannung am Pin 1 = 0,81V  es kommt 193 raus, also 1,56V (8 bit 
Auflösung)

bei 1,63V bekomme ich 225 -> 1,8V


Wenn jemand den Code ausprobieren könnte, wäre dan klar ob das an meinem 
Hardware liegt.

Gruß
Gast #1716441
Lesenswert?

Servus,

Dome schrieb:
> Wenn jemand den Code ausprobieren könnte, wäre dan klar ob das an meinem
>
> Hardware liegt.

als Anlage ein funktionierendes Beispeiel:

// Atxmega128A1 und USARTE0 (PE2 Rx) und (PE3 TX)  115200 bps
// ADCCH0 PINA0 poitiv, GND negativ
// Intern 1 Volt
// unsigned Betrieb 0 - 4095 Samples
// keine  Offset
// zeigt bei 0,8 Volt am ADCCH0 +0.8 Volt am Terminal an !!



Gruß GG
Angehängte Dateien:
Gast #1716762
Lesenswert?

Servus,

Hannes Jaeger schrieb:
> Fang damit an das Errata-Kapitel aus dem Datenblatt zu lesen. Der Xmega
>
> 128A1 ADC ist ziemlich am Arsch.

deine Errata Geschichte lese ich nun zum wiederholten Mal.
Ich finde das als  "Schwarzmalerei". Meine und proffesionelle ADC-Prog. 
laufen stabil und sind keinerweise Atmel-Errata geschädigt!

Gruß GG
Persönliche Seite #1716774
Lesenswert?

Xmega Datenblatt. Bei mir Seite 292:

In unsigned mode the negative input is connected to half of the voltage 
reference (VREF) volt-
age minus a fixed offset. The nominal value for the offset is:

dV = VREF * 0.05

Since the ADC is differential, unsigned mode is achieved by dividing the 
reference by two inter-
nally, resulting in an input range from VREF to zero for the positive 
single ended input. The
offset enables the ADC to measure zero cross detection in unsigned mode, 
and to calibrate any
positive offset where the internal ground in the device is higher than 
the external ground. See
Figure 25-11 on page 296 for details.





In unsigned mode the ADC transfer functions can be written as:

RES = (VINP - (-dV)) * TOP / VREF



Allerdings müsste das einem Offset von 200 LSB entsprechen. Schau da 
doch noch mal genau nach.
Gast #1716805
Lesenswert?

Hallo,

gg Danke, ADC läuft. Es lag gar nicht an Initialisirung, sonder an 
meiner
Wertabfrage.
Mit funktion get_adValue funktioniert und mit dem untensthenden Code 
nicht.
Der Mikrocontroller meldet doch "convertion complete", ich gehe dann 
davon aus, dass der richtige Wert kommt.
In der Funktion get_adValue wird doch nur ein Mittelwert gebildet.

Warum das nicht geht kopiere ich nicht.

*******Initialisierung******
ADCA.CTRLA |= ADC_ENABLE_bm;
// Start convert on channel0
ADCA.CH0.CTRL |= ADC_CH_START_bm;
ADC_Wait_32MHz(&ADCA);
      do {
     // If the conversion on the ADCA channel 0 never is
     //complete this will be a deadlock.
      temp = ADCA.CH0.INTFLAGS;
     }while (!(temp & ADC_CH_CHIF_bm));
      //Clear interrupt flag
      ADCA.CH0.INTFLAGS |= ADC_CH_CHIF_bm;

     adc_wert = ADCA.CH0RES;


Gruß
Dome
#1717592
Lesenswert?

Hallo Dome,

also ich habe 4 LSB Abweichung- der ADC liefert seine 12 Bit.
Allerdings benutze ich Aref = 2V externe Quelle (im Errata für H steht, 
dass über 2V die Fehler für AD und DA größer werden)
Den Offset habe ich nicht über Register, sondern im Code abgefangen (im 
EEPROM ist eine Ausgleichsfkt.)

Du erwartest nur 8 Bit? Was benutzt Du als externe HW? (Ich habe jetzt 
Dein Board nicht angesehen was da analog verbaut wurde.) Der XMega kann 
mehr.
Bei 2 MS kannst Du sogar Oversampling betreiben und die Auflösung 
erhöhen.

Gruß
Helmut
Gast #1717645
Lesenswert?

Hallo,

bin weiter beim Testen.
Versuche gleich an 4 Kanälen zu messen, bekomme einfach nicht hin.
Wenn alle 4 ADC Pins an gleicher Spannung liegen, unterscheiden sich die 
Ergebnisse gewaltig.
z.B. bei 1,5V krige ich zw. 1,55V und 1,33V, es sind 28 LSB.

Was mache ich schon wieder falsch?


     ADCA.CTRLA |= ADC_ENABLE_bm;

     while(true)
    {
   delay_us(1000000);     // delay 1 Sekunde
  ADCA.CTRLA |=  ADC_CH0START_bm
               | ADC_CH1START_bm
                | ADC_CH2START_bm
                | ADC_CH3START_bm;

      do {
          } while(!(ADCA.CH0.INTFLAGS & ADCA.CH1.INTFLAGS & 
ADCA.CH2.INTFLAGS & ADCA.CH3.INTFLAGS));
      // Clear interrupt flag
      ADCA.CH0.INTFLAGS |= ADC_CH_CHIF_bm;
      ADCA.CH1.INTFLAGS |= ADC_CH_CHIF_bm;
      ADCA.CH2.INTFLAGS |= ADC_CH_CHIF_bm;
      ADCA.CH3.INTFLAGS |= ADC_CH_CHIF_bm;

 // Wertausgasbe


    }
Gast #1717851
Lesenswert?

Servus,

Simon K. schrieb:

>Hast du denn jetzt wenigstens den ADC kalibriert?

ja, habe ich. Bei prescaler 8 und 8 bit Auflösung bringt nicht viel, 
lasse trozdem drin, schadet nicht.

>Und womit misst du die Spannungen zum Vergleich?

Mit einem Fluke 85. Sollte hinreiched genau sein.


Helmut schrieb:

>5 Ohm sind bissle wenig. Spannungsfolger ist eine saubere Lösung.

Sind 5 Ohm wenig? Meinst du vielleicht viel?

Wenn ich später meinen Signal vom OP Ausgang abgreife, könnte ich mir 
doch den Spannugsfolger sparen?


Gruß

Dome

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren