Hallo zusammen,
Ich habe eine ADC Funktion geschrieben, welche die ADC Kanäle 0 bis 5
auslesen soll. Mein Problem ist nun, dass wenn ich den Laufindex der
For- Schleife gleichzeitig als ADMUX Adressen verwenden möchte, kein ADC
Wert gelesen wird. Beim Eintragen von z.B. ADMUX = 1 funktioniert
folgendes Programm.
if(n==6)n=0;//Rücksetzen des For-Schleifen-Zählers
53
if(c==6)c=0;//siehen Oben
54
55
56
57
58
}
59
60
61
62
63
64
65
intmain(void){
66
67
floatwerte[7];
68
69
unsignedcharadcl[6],adch[6],n,b;
70
71
unsignedintadc[7];
72
73
DDRB=0xff;
74
init_adc();
75
76
77
78
79
80
for(;;)
81
{
82
83
84
messung(adc,werte,adcl,adch);
85
86
87
if(photo_u>15.00)
88
{
89
PORTB|=(1<<PB0);
90
}
91
else
92
{
93
PORTB&=~(1<<PB0);
94
}
95
96
}
97
98
99
}
Ich habe auch schon versucht in Abhängigkeit von n den ADMUX die
entsprechende Adresse über den case-Befehl zuzuweisen.
Kann mir vielleicht jemand einen Tipp geben, wo die Ursache sein könnte?
Stephan
> for (c=4; b<7; c++)
Was hat es denn mit der Durchlaufbedingung der Schleife auf sich? Eine
Variable b gibt es da nicht! Das müsste zumindest mal ne Fehlermeldung
geben.
Und was soll das doppelte Auslesen der ADC-Datenregister? Und bist Du
sicher, dass Du wirklich GLeitkommaberechnungen brauchst? Meist ist
Festkommaarithmetik sinnvoller...
Und noch was:
> while((ADCSRA & (1<<ADSC)) == 0){}
Überlege mal, was in dieser Zeile passiert! Kleiner Tip: Solange die
Wandlung läuft, ist ADSC gesetzt...
Das ganze scheint mir nicht sehr zeitkritisch zu sein.
Gibt es einen speziellen Grund, warum du nicht die ADC Routine aus dem
Tutorial benutzt? Die würde nämlich funktionieren.
das 'b<7' soll sicher 'c<7' heissen. Und die Float Skalierungen mit den
festen Indizes gehören nicht in die for Schleife, da wird 8mal das
Gleiche berechnet.
Und wozu das merkwürdige Rücksetzen der Schleifenzähler?
JojoS wrote:
> das 'b<7' soll sicher 'c<7' heissen. Und die Float Skalierungen mit den> festen Indizes gehören nicht in die for Schleife, da wird 8mal das> Gleiche berechnet.> Und wozu das merkwürdige Rücksetzen der Schleifenzähler?
Na, so tief in die Details bin ich noch gar nicht gegangen. Solange er
nicht auf das Ende der Wandlung wartet, bevor er das Ergebnis ausliest,
kann da nix Sinnvolles rauskommen...
Habe die angesprochene Variable "b" in "c" geändert, weil das Forum mir
eine Spammeldung gebracht hat. Das mit dem Berechnen in der Schleife ist
ein Fehler, das stimmt.
Das doppelte Auslesen dient, dazu das ADCL und ADCH über den SPI
übertragen werden sollen.
ein bischen wird ja gewartet:
//Warten bis Umwandlung startet
while((ADCSRA & (1<<ADSC)) == 0){}
man muss natürlich auf das Ende der Wandlung warten. Ob das mit dieser
Abfrage gemacht wird, weiss ich nicht, bin zu faul nachzusehen. Aber den
Teil würde ich auch dem Tutorial abschreiben.
Und die Schleife wird 7mal durchlaufen, nicht 8mal wie ich erst schrieb.
+/- 1, altes Informatikerproblem :-)
Der Grund, weshlab ich nicht die Routine aus dem Tutorial benutzte ist,
dass ich zu jedem Aufruf der Funktion alle Kanäle benötige. Ich möchte
also nicht jedesmal den zu lesenden Kanal übertragen.
Der Ablauf in der Main Routine dient nur zu Testzwecken. Im eigentlichen
Programm wird die Funktion "Messung" mehrmals aufgerufen.
ein Fehler ist die mehrfache Berechnung nicht, nur eine lange
Warteschleife weil float Mathe nicht die Stärke eines AVR ist :-)
Aber der Fehler dürfte doch in der Abfrage auf das Wandlungsende liegen,
du fragst auf ==0 ab, aber lt. Tutorial wird das Bit bei Wandlungsende
gelöscht.
Die Mittelwertbildung für die Wandlung ist auch zu empfehlen.
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#ADC_.28Analog_Digital_Converter.29
@JojoS
du hattest Recht mit dem "while ( ADCSRA & (1<<ADSC)){}"! jetzt
fnktioniert das Auslesen.
Die Mittelwertbildung und Festkommaarithmetik werde ich jetzt einmal
anschauen!
vielen Dank
Eine eigene Frage?
Dieser Thread ist über 17 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.