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
Implizit bedeutet das auch, Du kannst ein solches Bit nie selber setzen, um z.B. einen Softwareinterrupt zu erzeugen. Peter
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
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.