Guten Tag und frohe Weihnachten in die Runde ... Ich möchte den Overflow eines Atmega328P Timers nicht über einen Interrupt sonder via polling erfassen. Das Programm im Anhang soll das versuchen. Timer 1 lifert ca. alle 4 s einen Overflow (hochzählen bis 2^16 -1, Prescaler 1024, CPU Takt 16 Mhz). Der Timer Overflow Interrupt ist ausgeschaltet. Ich habe im Handbuch nichts darüber gefunden, das das TOV Bit in TIRF1 nur gesetzt wird, wenn der entsprechende Interrupt enabled ist. Beim Overflow wird das Bit auf 0 gesetzt, eine 1 kennzeichnet hier den nicht-overflow Zustand (so interpretiere ich das Datenblatt). Also sollte das doch mit Polling funktionieren. In der main loop wird das TOV Bit im TIFR1 alle 500µs abgefragt, und je nach Ergebnis eine Ausgabe angezeigt. Ggf. bit das TOV bit wieder deaktiviert. Ich würde jetzt alle 4 s eine Reaktion in der Ausgabe erwarten, aber das passiert nicht. Keine Ahnung was da los ist, vielleicht bin ich nur betriebsblind :( Wer eine Idee hat, wie das Problem zu lösen ist ... ich würde mich feuen VG, Andreas
Du könntest dir bei jeder Abfrage den aktuellen Timerstand merken und beim nächsten Aufruf mit dem dann aktuellen Zählerstand vergleichen. Ist der momentane Zählerstan kleiner als der beim letzten Aufruf, ist ein Überlauf passiert.
> Wer eine Idee hat, wie das Problem zu lösen ist .
Welches Problem?
Du hast eine überzeugende Idee geäußert und sie bereits mit dem
Datenblatt abgeglichen. Ich sehe da kein Problem.
Tu es!
Das stimmt .... beantwortet aber noch nicht die Frage, warum es mit Polling des TOV Flag nicht klappt.
Hallo Andreas, Du solltest Dir immer das Datenblatt zu deinem AVR µC aufmachen und auch lesen! Das zeigt dieser falsche Kommentar in deinem Code "// TOV-bit auf 1, somit nicht gesetzt?" Siehe Abschnitt 16.11.9 *TIFR1 – Timer/Counter1 Interrupt Flag Register* Bit 0 – TOV1: Timer/Counter1, Overflow Flag The setting of this flag is dependent of the WGM13:0 bits setting. In Normal and CTC modes, the TOV1 Flag is set when the timer overflows. Refer to Table 16-4 on page 133 for the TOV1 Flag behavior when using another WGM13:0 bit setting. TOV1 is automatically cleared when the Timer/Counter1 Overflow Interrupt Vector is executed. Alternatively, TOV1 can be cleared by writing a logic one to its bit location. Alle Welt schreibt
1 | if (TIFR1 & (1<<TOV1)) {} |
nur Du nicht, warum? Ein Hinweis: ja man kann einen Überlauf abfragen, muss dann auch gleich das Flag/ Signal auch selbst wieder löschen. Bei Dir also das Bit TOV1 "Timer/Counter1, Overflow Flag", dafür gibt es eine besondere Zuweisung.
Hallo, auch liest sich diese Zeile einfacher, wenn man die Bit-Namen CS12, CS11 und CS10 verwendet: *TCCR1B – Timer/Counter1 Control Register B*
1 | TCCR1B = (1<<CS12)^(0<<CS11)^(1<<CS10); |
Karl M. schrieb: > Bit 0 – TOV1: Timer/Counter1, Overflow Flag > The setting of this flag is dependent of the WGM13:0 bits setting. In > Normal and CTC modes, the TOV1 Flag is set > when the timer overflows. Refer to Table 16-4 on page 133 for the TOV1 > Flag behavior when using another > WGM13:0 bit setting. > TOV1 is automatically cleared when the Timer/Counter1 Overflow Interrupt > Vector is executed. Alternatively, TOV1 > can be cleared by writing a logic one to its bit location. > > Alle Welt schreibt if (TIFR1 & (1<<TOV1)) {} nur Du nicht, warum? ad 1: Da steht doch "Alternatively, TOV1 can be cleared by writing a logic one to its bit location. Also ist 1 der nicht aktive Zustand und 0 siganlisiert den stattgehabten Überlauf. ad 2: In einer Headerdatei steht "#define TOV1 0", d.h. (1<<TOV1) ist 0x01 und genau das steht da.
Hallo Andreas Ru, Andreas R. schrieb: > Karl M. schrieb: >> Bit 0 – TOV1: Timer/Counter1, Overflow Flag >> The setting of this flag is dependent of the WGM13:0 bits setting. In >> Normal and CTC modes, the TOV1 Flag is set >> when the timer overflows. Refer to Table 16-4 on page 133 for the TOV1 >> Flag behavior when using another >> WGM13:0 bit setting. >> TOV1 is automatically cleared when the Timer/Counter1 Overflow Interrupt >> Vector is executed. Alternatively, TOV1 >> can be cleared by writing a logic one to its bit location. >> >> Alle Welt schreibt if (TIFR1 & (1<<TOV1)) {} nur Du nicht, warum? > > ad 1: Da steht doch "Alternatively, TOV1 can be cleared by writing a > logic one to its bit location. Ja genau, wenn man kein interrupt service routine definiert hat, muss man es selbst machen ! Also im Programm machen man dies genauso wie folgt: man muss Schreiben TIFR1 = (1<<TOV1); > Also ist 1 der nicht aktive Zustand und 0 siganlisiert den stattgehabten Überlauf. Nein. Du kannst gerne diskutieren, aber das steht dort nicht! > ad 2: In einer Headerdatei steht "#define TOV1 0", d.h. (1<<TOV1) ist > 0x01 und genau das steht da. Ja und ? Ich habe nicht geschrieben, das 1 != (1<<TOV1) in genau diesem Fall ist. Frage dich doch bitte warum man TOV1, wenn es kein Mensch nutzen soll. Es ist viel einfacher und portabel mit den Bit-Namen zu arbeiten, auch vermeidet man Konvertierungsfehler.
Hallo Andreas, noch ein Argument gegen deine Interpretation des englischen Textes. Im Datenblatt findet man immer die Initialisierungswerte für jedes Register. Hier TIFR1 = 0x00. _Angenommen_: 0 würde einen aktiven Zustand beschreiben, wann würde ohne Programmausführung sofort ein Timer1 Überlauf signalisiert, der auch gelöscht würde! Siehe Bild.
Da hast Du recht. Ich habs sorumm probiert und es scheint zu klappen. Es bleibt die Frage, warum im Datenblatt steht, das das Schreiben einer 1 das Register löscht??
Wenn jemand schreibt "this flag is set" dann meint er damit immer, dass das Bit auf HIGH gesetzt wird. Es sei denn, im selben Absatz steht etwas anderes. Komische negative Logik gibt es bei AVR nur bei den Fuses.
Andreas R. schrieb: > Es bleibt die Frage, warum im Datenblatt steht, das das Schreiben einer > 1 das Register löscht?? Du meinst DAS Bit TOV1 im Register TIFR1, nun weil es da steht.
Andreas R. schrieb: > Es bleibt die Frage, warum im Datenblatt steht, das das Schreiben einer > 1 das Register löscht?? Na ja, Atmel hat seinen µC so gebaut und deshalb das auch ins Datenblatt geschrieben. So ein Interruptflag ist übrigens kein Register sondern ein Bit in einem Register.
> Es bleibt die Frage, warum im Datenblatt steht, das das Schreiben einer > 1 das Register löscht?? Das ist nicht ungewöhnlich, auch nicht bei anderen Mikrocontrollern.
Karl M. schrieb: > Ja genau, wenn man kein interrupt service routine definiert hat, muss > man es selbst machen ! > > Also im Programm machen man dies genauso wie folgt: man muss Schreiben > TIFR1 = (1<<TOV1); Aber dann wäre ja das TOV1 Bit auf 1 gesetzt!?!
> Es bleibt die Frage, warum im Datenblatt steht, das das Schreiben einer > 1 das Register löscht?? > Aber dann wäre ja das TOV1 Bit auf 1 gesetzt!?! kann es sein, dass du deine eigene Aussage nicht verstanden hast? Wenn du eine 1 in dieses Bit schreibst, wird es auf 0 zurück gesetzt. Das ist wie die Störungs-Lampe an der Gasheizung. Drückst du drauf, geht sie aus.
Andreas R. schrieb: > Aber dann wäre ja das TOV1 Bit auf 1 gesetzt!?! JA das ist doch das Ziel, dadurch wird das Bit gelöscht und bei zurück lesen erhält man eine "0", siehe das Datenblatt.
Ich glaube, der TO unterliegt hier dem Irrtum, Register wie Speicherzellen zu betrachten. Das ist aber nicht der Fall. Tatsächlich können Schreibzugriffe sogar ganz woanders hin gelangen, als Lesezugriffe. Das haben wir zum Beispiel beim seriellen Port. Wenn man das UDR Register liest, erhält man das zuletzt empfangene Byte. Wenn man das UDR Register beschreibt, wird es bei nächster Gelegenheit gesendet. Das sind in diesem Fall zwei völlig unabhängige Funktionen, wo das Schreiben in keinem Zusammenhang zum Lesen steht.
Stefan U. schrieb: > Ich glaube, der TO unterliegt hier dem Irrtum, Register wie > Speicherzellen zu betrachten. Das ist aber nicht der Fall. > Diesem Irrtum bin ich tatsächlich unterlegen. Danke für diesen konstuktiven Hinweis :)
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.
