Statt
1 | TCNT0 = (uint8_t)(int16_t)-(F_CPU / 1024 * 10e-3 + 0.5); // preload for 10ms
|
hätte man auch einfach schreiben können:
1 | TCNT0 = (uint8_t)(256 - F_CPU / 1024 * 10e-3 + 0.5); // preload for 10ms
|
Aber dann hätte es ja jeder kapiert ;-)
F_CPU / 1024 ist die Timer-Taktfrequenz nach dem Vorteiler durch 1024.
Besser hätte man hier F_CPU / 1024.0 geschrieben, damit auch die
Division in Floating-Point berechnet wird, was in einigen Fällen ein
etwas genaueres Ergebnis liefert.
F_CPU / 1024 * 10e-3 ist die Anzahl der Timer-Taktperioden, die zusammen
den gewünschten 10 ms entsprechen.
256 - F_CPU / 1024 * 10e-3 ist der ungerundete Startwert für den Timer,
so dass dieser nach 10 ms überläuft, also von 255 nach 0 springt, und
damit einen Interrupt auslöst.
(uint8_t) konvertiert diesen Startwert – passend zum 8-Bit-Register
TCNT0 – in einen vorzeichenlosen 8-Bit-Integer-Wert, wobei eventuelle
Nachkommastellen abgeschnitten werden. Damit würde der Wert also immer
auf die nächstkleinere ganze Zahl abgerundet werden. Um ein Runden zur
nächstliegenden ganzen Zahl zur erreichen, wird vor dem Abrunden durch
(uint8_t) einfach noch 0.5 addiert.
Rene H. schrieb:
> An so einer Stelle wäre ein informativer Kommentar sehr gut angebracht
Der Kommentar steht im zugehörigen Thread, auf dem im Artikel verlinkt
wird:
Beitrag "Re: Universelle Tastenabfrage"
Ok, im Quellcode hätte er auch nicht geschadet :)