www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Mal wieder XMEGA ADC über shunt widerstand


Autor: Felix H. (masterq)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,
ich hänge fest...
Folgendes:
Ich möchte mit dem atxmega16a4 den Spannungsabfall über ein 
Shunt-Widerstand messen, und mir den Strom auf einem Display ausgeben, 
außerdem möchte ich mir die Möglichkeit vorbehalten, die 
Versorgungsspannung zu unterbrechen, wenn ein bestimmter Strom 
überschritten wird.
Der Shunt Widerstand liegt am gleichen ground wie der uC. Dennoch wollte 
ich gerne den Differenz-Modus mit Gain benutzen um die Referenzen DIREKT 
am Widerstand zu messen.
Der Widerstand ist nicht sooo klein: 1/3 Ohm, und ich möchte damit 
Spannungen bis 700mA messen können.
Spannungsquelle ist ein PC Netzteil. Versorgung für den uC GND -> 3,3 V.
Zu messender Strom GND -> 5V.
Beide Spannung sind geglättet durch Kondensatoren verschiedener Größe, 
wobei ich mit dem Oszilloskop auch keine Spannungsschwankungen 
feststellen konnte.
Der Aufbau des Ganzen ist auf einem Steckbrett. Deshalb sind gewisse 
Schwankungen sicher nicht ungewöhnlich. Jedoch schwanken die 
Messergebnisse mit mehr als 20%. Das finde ich viel.

Hier der relevante Code:
#include "main.h"
#include "bla/iox16a4.h"
#include <inttypes.h>

#include <stdio.h>
#include <stdint.h>

#include <stddef.h>


#include "includes/lcd.c"
#include "includes/uart/uart.c"
#include "includes/out.c"
#include "includes/adc.c"
#include "includes/osc.c"


void init_uart(void);


int16_t Result = 234;

float ResultVolts;

int main(void)
{
  PORTD.DIR = 0xff;
  PORTD.OUT = 0x00;
  

  ext_osc_init();
  uart_init();
  adc_init();
  
  printf_init();

  lcd_init();
  
    // *** Interruptcontroller: Highlevelinterrupts aktivieren ***
  PMIC.CTRL |= PMIC_HILVLEN_bm;
    //************************************************************
  sei();

  while(1)
  {
    Result = adc_read();
    _delay_ms(200);
    if(Result >= 60000)
      Result = 0;

    ResultVolts = (float) (Result*1.75)/4096;
    printf("ADC Ch. 0: %1.3f   \n", ResultVolts);
    printf("ADC Ch. 0: %u   \n", Result);
  }
}


adc.c:
#include "includes/adc.h"
#include <bla/iox16a4.h>


void adc_init(void)
{
  PORTA.DIR = 0;
  ADCA.CTRLA |= ADC_ENABLE_bm;        // enable adc
  ADCA.CTRLB = ADC_CONMODE_bm | ADC_RESOLUTION_12BIT_gc;    // 12 bit signed conversion (pos 11bits)
  ADCA.REFCTRL = ADC_REFSEL_INT1V_gc | 0x02;           // internal 1V bandgap reference
  ADCA.PRESCALER = ADC_PRESCALER_DIV512_gc;             // peripheral clk/16 (2MHz/16=125kHz)
  ADCA.CH0.CTRL = ADC_CH_INPUTMODE_DIFFWGAIN_gc | ADC_CH_GAIN_16X_gc;     // differential, 4x front end gain
  ADCA.CH0.MUXCTRL = ADC_CH_MUXPOS_PIN2_gc | ADC_CH_MUXNEG_PIN4_gc;      // PORTA:2 wrt PORTA:4
  ADCA.CH0.INTCTRL = ADC_CH_INTLVL_HI_gc;              // hi level interrupt
  ADCA.EVCTRL = ADC_EVSEL_0123_gc | ADC_EVACT_CH0_gc;  // trigger ch0 conversion on event0

  ADCA.CALL = adc_read_calibration_byte(offsetof(NVM_PROD_SIGNATURES_t, ADCACAL0));
  ADCA.CALH = adc_read_calibration_byte(offsetof(NVM_PROD_SIGNATURES_t, ADCACAL1));
}

int16_t adc_read(void)
{
  int16_t result;
  ADCA.CH0.CTRL |= ADC_CH_START_bm;
  while(!ADCA.CH0.INTFLAGS);
  result = ADCA.CH0RES;
  return result;
}




uint8_t adc_read_calibration_byte(uint8_t index)
{
  uint8_t result;

  /* Load the NVM Command register to read the calibration row. */
  NVM_CMD = NVM_CMD_READ_CALIB_ROW_gc;
  result = pgm_read_byte(index);

  /* Clean up NVM Command register. */
  NVM_CMD = NVM_CMD_NO_OPERATION_gc;

  return(result);
} 

An alle die sich diesen Roman durchlesen um mir zu helfen:

Vielen Lieben Dank!

Autor: Jutta (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast du die Erratas über die ADCs der XMEGAs und die vernichtenden 
Kritiken im Internet darüber gelesen?

Autor: XMEGA (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Jutta schrieb:
> Kritiken im Internet darüber gelesen?

wieder jemand der hier Schauermärchen verbreitet.

Du findest keinen Punkt in diesem Code der nur annähernd ein Problem mit 
der Errata hat.

Das Übliche bei einem ADC: (und das hat fast jeder in dieser 
Preisklasse)

6LSB for sample rates above 1Msps, and up to 8 LSB for 2Msps sample 
rate.

Zu 90% ist es der Hardwareaufbau. Messen in solch rauer Umgebung wie ein 
Netzteil führt zwangsweise zu Störungen (hier Netzteil). Steckboards 
sind für AD-Wandler nicht zu empfehlen!

ADC_CH_GAIN_16X_gc verstärkt das Problem natürlich auch.

Teste deine Schaltung mal an einen kleinen Akku/Battarie mit Poti

Gruß XMEGA

Autor: total error (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>wieder jemand der hier Schauermärchen verbreitet.

Eine Integral Non-Linearity (INL) von +/-5LSB und ein Gain Error von 
+/-14LSB bei einer 3V Referenz und 500ksps findest du normal?? Das ist 
ja nicht mal 10bit-Genauigkeit.

Legt man eine 1V Referenz zugrunde, sind es sogar +/-41 LSB Gain 
Error...

Autor: Felix H. (masterq)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die Antworten,

ich werde es testen.
Allerdings ist noch zu sagen das es ziemlich egal ist ob Verstärkung 
drin ist oder nicht, aber meine Messgenauigkeit hatte ich ja auch in % 
angegeben...

Ich hatte irgendwo gelesen das es einen Haufen XMegas mit sehr 
schlechten adc gibt,

ich habe einen:
atxmega16a4
Produktionswoche:
1041

soweit ich es mitbekommen habe, wurden die Fehler im adc irgendwann 
behoben, weiß irgendjemand zu welcher Kategorie dieser gehört?

Grüße

Felix

Autor: total error (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>soweit ich es mitbekommen habe, wurden die Fehler im adc irgendwann
>behoben,

Ich glaube das ehrlich gesagt nicht. Auch sind die spezifizierten 
+/-5LSB INL für sich ja schon ein Hammer. Gut, der ADC ist sehr schnell, 
aber sehr genau scheint er nicht zu sein. Schade, ich wollte ihn auch 
schon einsetzen...

Ein guter 12bit ADC hat ein maximalen INL von +/-1LSB. Ein PIC18F2423 
bringt es schon auf +/-2LSB und der ATXMEGA auf +/-5LSB.

Ein weiterer Schwachpunkt dieses ATXMEGA ADCs ist, daß ich nirgends 
Angaben über die Monotonie finden kann. Monotonie ist aber für bestimmte 
Regelaufgaben Grundvoraussetzung!

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.