AD-Wandler bei den Atmegas

Gast #560711
Lesenswert?

Mahlzeit

Ich habe bei meinen AD-Wandlungen das Problem, das wenn zB. drei 
AD-Wandler initialisiert wurden, aber nur zwei angeschlossen sind alle 
AD-Wandler total falsche Werte liefern. Schließ ich den dritten mit an, 
funktioniert wieder alles.

Kann doch irgendwie nicht sein. Hatte da jemand schon mal ähnliche 
Probleme?
Gast #560713
Lesenswert?

Es gibt nicht einen einzigen ATMega mit mehr als einem A/D-Wandler! Was 
Du meinst sind vermutlich die Kanäle...

Wenn Du den Code, mit dem Du die Probleme hast, mal posten könntest und 
vielleicht auch mal Deine Schaltung überprüfst, dann kann Dir vielleicht 
auch geholfen werden.
Gast #560765
Lesenswert?

Ja, schon richtig. Die Kanäle sind gemeint.

Also meine Initialisierung der Kanäle sieht so aus:

void ADC_wandlung1()    //ADC0/PCINT - PORTC, Bit0
{
  int i=0;
  int result = 0;

  ADMUX  &= ~((1 << MUX0)|(1 << MUX1)|(1 << MUX2)|(1 << MUX3));  //ADC0 
eingestellt.
  ADCSRA |= ((1 << ADEN)|(1 << ADPS0)|(1 << ADPS1)|(1 << ADPS2));
  ADMUX  |= (1 << REFS0);
  ADMUX  &= ~(1 << REFS1);


//****************************************************************
ADCSRA |= (1<<ADSC);    //Eine AD-Wandlung zur Initialisierung
while (ADCSRA & (1<<ADSC))
{
;
}
//****************************************************************


//****************************************************************

for(i=0;i<10;i++)
{
ADCSRA |= (1<<ADSC);    //AD Wandlung
while (ADCSRA & (1<<ADSC))
{
;
}
result +=ADCW;
}
//******************************************************************

ADCSRA &= ~(1<<ADSC);    //AD Wandlung deaktivieren

result /= 10;
ADCW = result;
AD_PWM = ADCW;
AD_PWM = (AD_PWM >>2);
}


void ADC_wandlung2()    //ADC2/ - PORTC, Bit2
{

  int i=0;
  int result = 0;

  ADMUX  |= (1<<MUX1);                      //ADC2 eingestellt.
  ADMUX  &= ~((1 << MUX0)|(1 << MUX2)|(1 << MUX3));
  ADCSRA |= ((1 << ADEN)|(1 << ADPS0)|(1 << ADPS1)|(1 << ADPS2));
  ADMUX  |= (1 << REFS0);
  ADMUX  &= ~(1 << REFS1);


//****************************************************************
ADCSRA |= (1<<ADSC);    //Eine AD-Wandlung zur Initialisierung
while (ADCSRA & (1<<ADSC))
{
;
}
//****************************************************************


//****************************************************************


for(i=0;i<10;i++)
{
ADCSRA |= (1<<ADSC);    //AD Wandlung
while (ADCSRA & (1<<ADSC))
{
;
}
result +=ADCW;
}
//******************************************************************

ADCSRA &= ~(1<<ADSC);    //AD Wandlung deaktivieren

result /= 10;
ADCW = result;
AD_SERVO1 = ADCW;
AD_SERVO1 = (AD_SERVO1 >> 2);
}
Gast #560776
Lesenswert?

> ADCW = result;
Was soll das denn? Das ADC-Ergebnisregister ist Write-Only!

> ADCSRA &= ~(1<<ADSC);    //AD Wandlung deaktivieren
Da passiert gar nichts. Das ADSC kann man nur setzen. Es wird am Ende 
der Wandlung automatisch gelöscht.
Gast #560786
Lesenswert?

Also mich wundert, dass da überhaupt was sinnvolles rauskommt...

Neben dem Bock mit dem ADCW noch ein paar Tips:
1.: Mittelwertbildung besser über 8 oder 16 Zyklen machen und nicht über 
10. Divisionen durch "nicht-Zweierpotenzen" sind erheblich aufwändiger.

2.: Es muss bei einem Kanalwechsel nicht jedes Mal der ganze ADC neu 
initialisiert werden. Es reicht völlig, den Kanalmux umzuschalten.

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