Forum: Mikrocontroller und Digitale Elektronik Xmega ADC verhaut sich um 25 LSB. Hilfe


von Dome (Gast)


Angehängte Dateien:

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.

von Hannes J. (Firma: _⌨_) (pnuebergang)


Lesenswert?

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

von wt (Gast)


Lesenswert?

welche Ref verwendest Du?

von Dome (Gast)


Lesenswert?

Hallo.

wt schrieb:

>welche Ref verwendest Du?

Vcc/1,6


Gruß

von wt (Gast)


Lesenswert?

und du bist sicher, daß deine zu messende Spg. immer kleiner als Vcc/1,6 
und liegt stabil an? mit Oszi geprüft?

von Dome (Gast)


Lesenswert?

Hannes Jaeger schrieb:

>Der Xmega128A1 ADC ist ziemlich am Arsch.

Ich hätte noch einen  Xmega128A3, gäbe damit mehr Chancen auf Erfolg?


Gruß

von wt (Gast)


Lesenswert?

Übrigens wenn ich datenblatt richtig lese, sind +-25LSB ok

von Dome (Gast)


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?

von Dome (Gast)


Lesenswert?

wt schrieb:

> Übrigens wenn ich datenblatt richtig lese, sind +-25LSB ok

In doc8067 "XMEGA A1 Microcontroller" im Kapitell 35.Errata steht:

• The ADC has up to ±2 LSB inaccuracy

von nicht Gast (Gast)


Lesenswert?

CPU am compiler richtig?
Ich etwas ähnliches (XPlain Board), schon erlebt (2MHz bei WinAVR 
eingetragen, CPU lief aber mit 32MHz).

von wt (Gast)


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.

von Dome (Gast)


Lesenswert?

nicht Gast schrieb:
>CPU am compiler richtig?

Weiß gar nicht davon. Muss Clk auch in Compiler eingestellt werden?
System Clock ist 32 MHz.

von Dome (Gast)


Lesenswert?

HW gucke ich morgen nach.
Danke für den Tipp.

von Dome (Gast)


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ß

von Bingo (Gast)


Lesenswert?


von GG (Gast)


Angehängte Dateien:

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

von Simon K. (simon) Benutzerseite


Lesenswert?

Du hast den ADC auf Unsigned Mode stehen. Da gibts einen fest 
einprogrammierten Offset um Nulldurchgänge erkennen zu können. Steht 
aber auch im Datenblatt (Welch ein Wunder!).

von GG (Gast)


Lesenswert?

Hallo,


Simon K. schrieb:
> Du hast den ADC auf Unsigned Mode stehen. Da gibts einen fest
>
> einprogrammierten Offset um Nulldurchgänge erkennen zu können. Steht
>
> aber auch im Datenblatt (Welch ein Wunder


danke für die Info, werde mir das anschauen.

Gruß GG

von GG (Gast)


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

von Simon K. (simon) Benutzerseite


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.

von Simon K. (simon) Benutzerseite


Lesenswert?

Ach so, hast du eigentlich auch die Offset-Kalibrierwerte aus der 
Calibration Row geladen? (Bin mir gerade nicht sicher ob das automatisch 
geht).

von GG (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

nochmals zu deinem Code.

Mir fehlen die Timing-Code

wie zum Beispiel:

while(!ADCA.CH0.INTFLAGS);         // wait for conversion complete flag
 ADCA.CH0.INTFLAGS=ADC_CH_CHIF_bm;// clear int flags (cleared by 
writing)

Schau Dir nochmal meinen Code an.

Gruß GG

von Dome (Gast)


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

von Dome (Gast)


Lesenswert?

gg schrieb:

>Mir fehlen die Timing-Code

Dumm von mir, ich hätte gedacht, das nach 10us adc fertig sein soll.

von Helmut R. (heru01)


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

von Dome (Gast)


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


    }

von Dome (Gast)


Lesenswert?

Noch eine Dummheit meinerseits.
Habe gemessen an 100k Spannugsteiler, ist wahrscheinlich ein bischen zu 
hochohmig für ADC.
Mit 5 Ohm sind es nur 5LSB.

von Simon K. (simon) Benutzerseite


Lesenswert?

Hast du denn jetzt wenigstens den ADC kalibriert? Könnte auch noch was 
bringen. Und womit misst du die Spannungen zum Vergleich? Bedenke, dass 
Multimeter Marke "Aldi" auch nicht ganz soo genau sind.

von Helmut R. (heru01)


Lesenswert?

Hallo Dome,

Spannungsteiler ist ok. Lass aber danch bitte inen Spannungsfolger 
folgen.
5 Ohm sind bissle wenig. Spannungsfolger ist eine saubere Lösung.
Und dann: Multimeter Genauigkeit überprüfen... We misst misst Mist!

;-)

Gruß
Helmut

von Dome (Gast)


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

von Dome (Gast)


Lesenswert?

Habe noch ein paar Widestände parallel rein getan.
Acht Kanäle laufen jetzt mit 2LSB.

Also Fehler lag von Anfang an an meinem Spannungsteiler.

Gruß

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.