ADC beim ATMega128 liefert stets 1023 (single ended I.)

OP #947674
Lesenswert?

Hallo zusammen,

folgendes Problem:
Mein ATMega128 liefert stets bei der AD Wandlung (ADC0 bis ADC7) als 
Ergebnis 1023, gleichgültig welche Spannung am Eingang der 8 Pins liegt.

folgendes hab ich schon versucht:
- alle Pins auf Masse gelegt, dann bei jedem ADC-Pin eine AD-Wandlung 
unternommen
- das gleiche mit +5 V
- im Register ADMUX hab ich die drei gültigen Kombinationen für 
REFS1/REFS0 ausprobiert
- die getesteten MUX-Kombinationen: 0 bis 7 (also ADC0 bis ADC7)
- mit und ohne Beschaltung von AREF
Bei allen Versuchen war stets das Ergebnis im Register ADC 1023.

hier der C-code:
1
void AD_Conversion (uint8_t mux_dest){
2
  ADMUX = mux_dest;
3
  ADCSRA = 0xC0;
4
  while (!(ADCSRA&(1<<ADIF)))
5
   ;
6
  adc_result = ADC;  //Inhalt von ADC in globale Variable schreiben
7
  ADCSRA |= (1<<ADIF);
8
}

meine Hardwareconfig:
- ATMega128, betrieben an +5 V
- AVCC ist mit 100nF an GND und über 10µH an VCC angeschlossen
- AREF: Offen, über 22nF auf GND oder an +5 V (habe alle drei Varianten 
getestet)
- AGND ist mit GND verbunden

Ich lasse mir den Wert der globalen Variable "adc_result" auf einem LCD 
anzeigen. Die Anzeige ist offenbar nicht das Problem, wenn ich in 
adc_result einen beliebigen Wert statt der Zuweisung mit ADC 
hineinschreibe, wird auch dieser Wert angezeigt. Sobald aber die 
Zuweisung mit ADC stattfindet, steht immer 1023 drin.

Vielleicht kann mir jemand weiterhelfen.
Vielen Dank!
Gast #947720
Lesenswert?

>> ADMUX = mux_dest;
Überschreibt dir die Einstellungen für die Referenzspannung
1
#define MUX_MASK 0x1F
2
int16_t get_adc_channel(uint8_t mux_dest){
3
  // schreibe nur MUXn Bits, behalte REFSm und ADLAR:
4
  uint8_t tmp = ADMUX;
5
  ADMUX  = (tmp & ~MUX_MASK) | (mux_dest & MUX_MASK);
6
  ADCSRA |= (1<<ADSC); /* Der ADC _ist_ doch schon an _und_ initialisiert, oder? */
7
  // wenn du das ADSC-Bit pollst, brauchst du kein Flag zu loeschen:
8
  while (ADCSRA & (1<<ADSC))
9
   ;
10
  return ADC; // globals sind bestimmt unnoetig ;)
11
}

hth. Jörg
Gast #947836
Lesenswert?

Hallo,
probiers mal so



void ADC_init()
{
  ADMUX = 0x40;     //AVCC  internal , PC0 Input , Right Adjusted
  ADCSRA = 0x86;     //ADC enable , Prescaler = 64
}



unsigned int ADC_GET()
{
  ADCSRA |= 0x40;     //Startb ADC Conversion

  while ( ADCSRA & (1<<ADSC) )  //warten bis ADSC Bit gelöscht wird
  {
    ;
  }

  unsigned int ADC_Erg = ADCW;
        return(ADC_Erg);
}


falls du es unbedingt global brauchst lass die letzten beiden Zeilen weg 
und schreib adc_result = ADC; und return 0;

Gruss
Gast #947845
Lesenswert?

Aso Code war ursprünglich fürn Atmega32, ich hoffe die Register des 
ADC's vom Atmega128 sing gleich !
Und es wird wird nur PC0 initialisiert, also falls du mehr Ports 
brauchst, die ADC_init ändern.

Gruss

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