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.
Fang damit an das Errata-Kapitel aus dem Datenblatt zu lesen. Der Xmega 128A1 ADC ist ziemlich am Arsch.
Hallo.
wt schrieb:
>welche Ref verwendest Du?
Vcc/1,6
Gruß
und du bist sicher, daß deine zu messende Spg. immer kleiner als Vcc/1,6 und liegt stabil an? mit Oszi geprüft?
Hannes Jaeger schrieb:
>Der Xmega128A1 ADC ist ziemlich am Arsch.
Ich hätte noch einen Xmega128A3, gäbe damit mehr Chancen auf Erfolg?
Gruß
Übrigens wenn ich datenblatt richtig lese, sind +-25LSB ok
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?
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
CPU am compiler richtig? Ich etwas ähnliches (XPlain Board), schon erlebt (2MHz bei WinAVR eingetragen, CPU lief aber mit 32MHz).
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.
nicht Gast schrieb:
>CPU am compiler richtig?
Weiß gar nicht davon. Muss Clk auch in Compiler eingestellt werden?
System Clock ist 32 MHz.
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ß
Hilft diser info ? http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=88006 mfg Bingo
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
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!).
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
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
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.
Ach so, hast du eigentlich auch die Offset-Kalibrierwerte aus der Calibration Row geladen? (Bin mir gerade nicht sicher ob das automatisch geht).
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
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
gg schrieb:
>Mir fehlen die Timing-Code
Dumm von mir, ich hätte gedacht, das nach 10us adc fertig sein soll.
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
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 }
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.
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.
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
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.