walter schrieb:
> Hallo Karl heinz Buchegger,
>
> danke dir für deine Antwort. Ist schön, dass hier immer so schnell
> geholfen wird.
>
> zu No.1
> eigentlich muss der Code in der while-schleife gefangen sein, bis die
> ISR den ADC startet.
Warum sollte sie?
Dein Code wartet darauf, dass das ADSC Bit 0 wird bzw. 0 ist.
Was aber, wenn es sowieso schon 0 ist, weil der Timer Interrupt noch gar
nicht da war, der es auf 1 gesetzt hätte?
Dann wird auf nichts gewartet, sondern sofort ADCW ausgelesen und
zurückgekehrt.
Im Vergleich zu der Häufigkeit, mit der diese Funktion aufgerufen wird,
kommt aber der Timer Interrupt nur alle heiligen Zeiten. Dadurch ergibt
sich diese Sequenz
Timer-ISR Hauptprogramm
------------------------------------------------
startet
setzt ADSC auf 1
adcGetValue()
wartet auf ADSC == 0
ADC wird fertig
ADSC <- 0
return ADCW
adcGetValue()
ADSC ist bereits 0
return ADCW
adcGetValue()
ADSC ist bereits 0
return ADCW
adcGetValue()
ADSC ist bereits 0
return ADCW
startet
setzt ADSC auf 1
adcGetValue()
wartet auf ADSC == 0
ADC wird fertig
ADSC <- 0
return ADCW
adcGetValue()
ADSC ist bereits 0
return ADCW
Die meiste Zeit findet adcGetValue das ADSC Bit als nicht gesetzt vor,
weil die Timer ISR den ADC noch gar nicht gestartet hat, seit
adcGetValue zuletzt den Wert abgeholt hat. Des kümmert adcGetValue aber
nicht, es liefert dann einfach den zuletzt gewandelten Wert noch einmal.
Das Problem ist, dass adcGetValue eben nicht auf das Beenden einer
Wandlung wartet, sondern nur darauf, dass das bewusste Bit 0 ist.
Oder anders ausgedrückt: Wenn du 20 mal am Tag in deinen Postkasten
schaust und ihn leer vorfindest, heisst das nicht, dass der Postler 20
mal da war und nichts hineingelegt hat.