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?
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.
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); }
> 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.
Upps, vertippt:
> Das ADC-Ergebnisregister ist Write-Only!
Muss natürlich "Read-Only" heißen...
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.
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.