Forum: Mikrocontroller und Digitale Elektronik AD-Wandler bei den Atmegas


von Phillip (Gast)


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?

von johnny.m (Gast)


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.

von Phillip (Gast)


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);
}

von johnny.m (Gast)


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.

von johnny.m (Gast)


Lesenswert?

Upps, vertippt:
> Das ADC-Ergebnisregister ist Write-Only!
Muss natürlich "Read-Only" heißen...

von johnny.m (Gast)


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.

von Karl H. (kbuchegg)


Lesenswert?

3. Sinnvollerweise wird man sich nur 1 Funktion schreiben,
   die sich um die ADC Wandlung kümmert.

   Im gcc Tutorial ist zufällig eine drinnen.

von Carsten P. (papa_of_t)


Lesenswert?

Vielleicht hilft Dir eine Pause zwischen den Messungen, siehe hier:

Beitrag "Mega8 ADC Meßproblem"

Irgendwie macht es keinen Spaß, Deinen Quelltext zu lesen - statt 
Sternchenlinien kann man doch auch einrücken?

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
Noch kein Account? Hier anmelden.