So, nach meinem SPI-Malheur nun mal ein echtes Problem :)
Ich habe eine ISR laufen, die durch Timer1-Compare-Match alle 10ms
aufgerufen wird, ein, zwei vitale Timervariablen hochzählt und Flags
setzt. Ausserdem toggelt sie den Eingang für Timer3, entweder aus oder
externer Eingang. An dem externen Eingang liegt eine Frequenz, die
gezählt werden soll, d.h. 100 Timer1-Compare-Match-Aufrufe lang ist das
externe Signal auf T3 geschaltet, danach einen ISR-Zyklus lang aus und
dann wird ausgelesen.
Da die Frequenz deutlich über 65536Hz liegen kann, wird T3 auch mal
überlaufen - kein Problem, das High-Word wird in der T3OVF-ISR gebildet.
ABER: was passiert, wenn der entscheidende T1-Match und ein T3-Überlauf
gleichzeitig eintreten - da die externen Timereingänge ja auf den
Systemtakt synchronisiert werden, ist das recht wahrscheinlich.
Zwei Möglichkeiten: T3 kommt vor T1 - kein Problem, T3 ist übergelaufen,
also TCNT3=0, die ISR wird aufgerufen, hochgezählt, alles super.
Oder: T1 kommt zuerst. T3 ist indes schon übergelaufen, sein OVF aber
noch nicht durch die Interruptlogik wahrgenommen worden, weil
T1-Compare-Match gerade in der Verarbeitung steckt. Es wird also eine 0
aus TCNT3 gelesen, aber eigentlich wäre der Wert 65536 höher.
Meine Überlegung: ich frage in der T1-ISR vor dem Speichern des
TCNT3-Wertes ab, ob T3OVF gesetzt ist. Wenn ja, inkrementiere ich das
High-Word, löschen T3OVF, damit es nach dem Verlassen der T1-ISR keine
Fehlzählung gibt und gut - oder?
Jeder, der schon mal einen Frequenzzähler programmiert hat, wird sich
darüber (hoffentlich!!!) mal Gedanken gemacht haben. Wenn ich das so
schreibe, bevor sich hier Widerspruch regt, lasse ich mal für den Fall,
dass meine Abfrage da oben jemals true wird einen Portpin setzen. Mal
sehen...