XMega: ADC liefert seltsame Werte

OP #7623255
Lesenswert?

Hallo,

ich verzweifle hier langsam am ADC des XMega. Board ist das XMega A1U xplainedd pro mit einem XMega128A1U.

1
Referenz: Bandgap (1 V)
2
Eingang: Bandgap
3
Ergebnis: 4095 (richtiger Wert)
4

5
Referenz: Bandgap (1 V)
6
Eingang: Scaled VCC (0,33 V)
7
Ergebnis: 1514 (erwartet ist 1350)
8

9
Referenz: 3,3 V an Aref
10
Eingang: Bandgap
11
Ergebnis: 1761 (erwartet ist 1241)
12

13
Referenz: 3,3 V an Aref
14
Eingang: Scaled VCC (0,33 V)
15
Ergebnis: 658 (erwartet ist 410)
16

17
Referenz: Vcc / 1,6 (ca. 2,1 V)
18
Eingang: Scaled VCC (0,33 V)
19
Ergebnis: 843 (erwartet ist 655)

Konfiguriert wird der ADC so (mit jeweils anderen Werten für reference, internalInput und input. Vollständiger Code ist im Anhang.

1
  struct adc_config adcConfig = { };
2
  struct adc_channel_config adcChannelConfig = { };
3

4
  adc_set_clock_rate(&adcConfig, 62500);
5
  adc_set_conversion_trigger(&adcConfig, ADC_TRIG_MANUAL, 1, 0);
6
  adc_set_conversion_parameters(&adcConfig, ADC_SIGN_OFF, ADC_RES_12, reference);
7
  adc_enable_internal_input(&adcConfig, internalInput);
8
  
9
  adcch_set_input(&adcChannelConfig, input, ADCCH_NEG_NONE, 1);
10
  
11
  adc_write_configuration(adc, &adcConfig);
12
  adcch_write_configuration(adc, channelMask, &adcChannelConfig);
13
  
14
  adc_enable(adc);

8 statt 12 Bit verwenden hilft auch nicht, die Werte sind genauso falsch.

Hat jemand eine Idee?

Danke & Gruß Thomas

Angehängte Dateien:
(Firma: matzetronics) #7623322
Lesenswert?

  1. VREF darf AVCC-0,6V nicht überschreiten. Speist du AVCC mit 3,3V, dann ist eine VREF von 3,3V nicht erlaubt (Datenblatt von 2018, Tabelle 37.2.6)

  2. Errata beachten:

"ADC is non-functional in SE unsigned mode with VREF below 1.8V" "14. ADC is non-functional in SE unsigned mode with VREF below 1.8V When the ADC is used on single ended unsigned mode and VREF is below 1.8V, INL and DNL error is increased above +/- 10LSB, i.e. the ADC have missing codes under this condition."

DB von 2018, Seite 215.

Der ADC hat noch ein paar andere Problemchen, die aber hauptsächlich den Betrieb bei tiefen Temperaturen betreffen. Kurz - für brauchbare Ergebnisse nimmst du besser einen externen ADC. Mich hat schon der 128A1 (ohne U) zum Zweifeln gebracht. Als ich die Nase voll hatte, bin ich auf STM32 umgestiegen.

OP #7623505
Lesenswert?

Danke für die Antworten.

Auch mit 2,5V an Aref sind die Werte komplett daneben:

1
Referenz: 2,5 V an Aref
2
Eingang: Bandgap
3
Ergebnis: 2072 (erwartet ist 1638)
4

5
Referenz: 2,5 V an Aref
6
Eingang: Scaled VCC (0,33 V)
7
Ergebnis: 743 (erwartet ist 540)

Komisch ist eben auch das hier, da nur interne Werte als Eingang bzw. Referenz verwendet werden:

1
Referenz: Vcc / 1,6 (ca. 2,1 V)
2
Eingang: Scaled VCC (0,33 V)
3
Ergebnis: 843 (erwartet ist 655=4095*1,6/10)

... ah, ich glaub, ich habs :-): das delta V war verwirrend. Zum einen sagt das XMEGA A MANUAL: ΔV = VREF × 0.05

und das Datenblatt vom ATxmega128A1U: ΔV Fixed offset voltage 190 LSB

Sogar die Temperatur wird damit einigermaßen richtig geschätzt.

Der Code, vielleicht hilft er ja dem ein oder anderen:

1
static float CalcVinp(uint16_t res, float vref)
2
{
3
  const float deltav = 190;
4
  float r = (float)res - deltav;
5
  float top = 4095.0f - deltav;
6
  
7
  float vinp = r / top * vref;
8
  return vinp;
9
}
10

11
mit Hilfe von https://blog.world3.net/2012/04/working-xmega-temperature-sensor-code/
12
static float CalcTemp(uint16_t res)
13
{
14
  const float deltav = 190;
15
  float r = (float)res - deltav;
16

17
  uint16_t refHot;
18
  float degreesX10;
19
  float kelvinPerAdcC10;
20

21
  // get 358 K factory calibrated value
22
  // 2382 for our controller.
23
  refHot = adc_get_calibration_data(ADC_CAL_TEMPSENSE);
24
  
25
  kelvinPerAdcC10 = (float)((273 + 85) * 10) / (float)refHot; // reference is ADC reading at 85C, scaled by 10 to get units of 0.1C
26

27
  degreesX10 = r;
28
  degreesX10 *= kelvinPerAdcC10;
29
  degreesX10 -= 2730.0f;
30

31
  return degreesX10 / 10.0f;
32
}

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