Hi Leute!
Folgender Text hat mich grad etwas "verwirrt" (ist aba wahrscheinlich
nur ein Denkfehler):
"The bit TOV0 is set (one) when an overflow occurs in
Timer/Counter0. TOV0 is cleared by hardware when executing the
corresponding interrupt Handling Vector. Alternatively,
TOV0 is cleared by writing a logic one to the flag. When the SREG I-
bit, TOIE0 (Timer/Counter0 Overflow Interrupt Enable), and TOV0 are
set (one), the Timer/Counter0 Overflow interrupt is executed."
-> Das Overflow-Flag vom Timer 0 wird ja auf "1" gesetzt wenn ein
Overflow kommt, ok alles klar - aber wie kann ich es dann löschen
indem ich es auf 1 setzen muss? Gibts da in der schreibweise
("set" bzw. "logical one") einen unterschied?
-> wie schaut der Befehl genau aus, um abzufragen ob TOV0 gesetzt ist
und wenn ja, wie wird es dann wieda gelöscht?
besten Dank im vorraus!
gruß,
semo
hmmm... mal sehen:
Das TOV0-Bit wird gesetzt, sobald ein Überlauf auftritt. Hast Du!
Zum Löschen wird entweder die Interrupt-Routine aufgerufen und das Bit
hardwaremässig gelöscht. Hast Du!
Will man es manuell löschen, muss man das Bit setzen. Ist zwar etwas
komisch, aber es gibt noch weitere Bits, die auf diesem Weg gelöscht
werden.
Abfragen kannst du es mit den üblichen Abfrageoperationen in C z.B.
mit ("Timerregister" && (1<<TOV0)); (Ich weiß gerade nicht, wie das
Register-Byte heisst...).
Vielleicht hilft dir das ja...
Gruß Rahul
Hi,
steht doch da aber so richtig da...
das Flag wird gesetzt, wenn der Timeroverflow auftrat. Dieses bleibt
solange gesetzt, bis der Atmel endlich Zeit gefunden hat, in die
Interruptroutine zu springen (kann ja sein, das Du das gerade mit
"cli" verboten hattest). Jetzt springt der AVR in seine Timer0
Routine und das Flag wird gelöscht damit in der Zwischenzeit ein
eventuel erneut auftretender Interrupt nicht verloren geht. Das gleiche
gilt ja auch für die ganzen anderen Interrupts. immer wenn einer
auftritt, merkt sich das der AVR und wenn Zeit ist(also das "i"Flag
gestzt), werden diese in Rangfolge ihrer Priorität abgearbeitet. Ob das
Bit nun High-oder Low-Pegel hat, wenn es gesetzt oder gelöscht ist steht
doch nirgends...
Wie man dis jetzt abfragt? habe ich noch nicht gemacht, glaube ich.
Wann muss man denn das abfrgaen?
AxelR.
Schön, daß Du Dir das Datenblatt zuerst durchliest und nicht tagelang
verzweifelt den Fehler suchst.
Ja es ist so, manche Bits müssen auf 1 gesetzt werden und sind dann
hinterher 0.
Der Befehl ist der gleiche, wie wenn Du einen Portpin auf 1 setzen
willst (der ist dann aber auch 1).
Irgendwie wollen manche Entwickler eine eigene Note reinbringen
(Duftmarke setzen), auch wenn sie damit Scharen von Programmierern in
die Verzweiflung treiben.
Und die AVR-Entwickler haben sich nun mal diesen Blödsinn ausgedacht
und Dir bleibt leider nichts weiter übrig, als Dich damit abzufinden
und es auch ständig im Hinterkopf zu behalten.
Peter
Hi Rahul!
danke, bin also doch net so falsch gelegen wie ich dachte...
zum Abfragen: if (TIFR & (1<<TOV0)) { //Kontrolliere, ob TOV0-Bit
//in TIFR gesetzt ist
zum Löschen: TIFR &= ~(1<<TOV0);
müsste also stimmen, oder?
gruß,
semo
Da ist deshalb noch ne böse Falle drin !
Da das TOV1 ebenso blöde ist und mit im selben Register sitzt, wird es
automatisch mit gelöscht.
Deshalb geht das hier auch:
zum Löschen: TIFR &= ~(1<<TOV1);
Das löscht alle blöden Bits im TIFR mit Ausnahme des TOV1.
Ich hoffe, ich habe Dich jetzt nicht zu sehr verwirrt.
Peter
also, ich glaub bei mir stimmt irgendwas mit dem timer oder so nicht...
habe folgende funktion für eine warte-zeit:
void delay_ms (unsigned int x) {
int c=0;
while (c < x) {
TCNT0=0x62; // Timer0 value for 10ms steps (0x62 = 98
TIFR |= (1<<TOV0);
if (TIFR & (1<<TOV0)) {
c++;
USART_transmit_string("c++");
}
}
}
-> somit würde ich doch z.B. bei "delay_ms(5)" eine verzögerung von
50ms erreichen, oder!? Aber es schaut so aus als würde ich garnet in
die if-Schleife kommen (hab mir zur kontrolle was am PC anzeigen
lassen)! Der Code müsste doch stimmen, oder?
siehst du vielleicht einen fehler?
gruß,
semo
ok, alles klar...glaube hab den fehler gefunden (bin anscheinend
zwischen while + if "steckengeblieben"!)
void delay_ms (unsigned int x) {
int c=0;
TCNT0=0x62;
TIFR |= (1<<TOV0);
while (c < x) {
if (TIFR & (1<<TOV0)) {
c++;
TIFR |= (1<<TOV0);
TCNT0=0x62;
}
}
}
so müsste es jetzt klappen!
,o)
semo
Hallo,
ich weiß, der Beitrag ist alt. Ich bin drauf gestoßen bei der Suche nach
einer Lösung.
Würde gerne im Atmega32 den Timer0 Interrupt an einer bestimmten Stelle
auslösen. Er könnte zufällig schon gerade feuern, falls aber nicht so
will ich das dort erzwingen um den Timer an einer bestimmten Stelle
"frisch" loszählen zu lassen.
Wie mache ich das? Peter schreibt ja dass es so nicht geht, wie denn
dann?
Schönen Sonntag und danke für ein Feedback
Thomas