mikrocontroller.net

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


Autor: Dome (Gast)
Datum:
Angehängte Dateien:

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

Autor: Hannes Jaeger (pnuebergang)
Datum:

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

Autor: wt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
welche Ref verwendest Du?

Autor: Dome (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo.

wt schrieb:

>welche Ref verwendest Du?

Vcc/1,6


Gruß

Autor: wt (Gast)
Datum:

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

Autor: Dome (Gast)
Datum:

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

Autor: wt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Übrigens wenn ich datenblatt richtig lese, sind +-25LSB ok

Autor: Dome (Gast)
Datum:

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

Autor: Dome (Gast)
Datum:

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

Autor: nicht Gast (Gast)
Datum:

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

Autor: wt (Gast)
Datum:

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

Autor: Dome (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
nicht Gast schrieb:
>CPU am compiler richtig?

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

Autor: Dome (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
HW gucke ich morgen nach.
Danke für den Tipp.

Autor: Dome (Gast)
Datum:

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

Autor: Bingo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: GG (Gast)
Datum:
Angehängte Dateien:

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

Autor: Simon K. (simon) Benutzerseite
Datum:

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

Autor: GG (Gast)
Datum:

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

Autor: GG (Gast)
Datum:

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

Autor: Simon K. (simon) Benutzerseite
Datum:

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

Autor: Simon K. (simon) Benutzerseite
Datum:

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

Autor: GG (Gast)
Datum:
Angehängte Dateien:

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

Autor: Dome (Gast)
Datum:

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

Autor: Dome (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
gg schrieb:

>Mir fehlen die Timing-Code

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

Autor: Helmut Ru (heru01)
Datum:

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

Autor: Dome (Gast)
Datum:

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


    }

Autor: Dome (Gast)
Datum:

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

Autor: Simon K. (simon) Benutzerseite
Datum:

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

Autor: Helmut Ru (heru01)
Datum:

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

Autor: Dome (Gast)
Datum:

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

Autor: Dome (Gast)
Datum:

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

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.