www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Timer0 Abfrage


Autor: semo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: semo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
achja, verwende ATMEGA8!
;o)

semo

Autor: Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Axel Rühl (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: semo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nein !

zum Löschen:    TIFR |=  (1<<TOV0);


Peter

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Implizit bedeutet das auch, Du kannst ein solches Bit nie selber setzen,
um z.B. einen Softwareinterrupt zu erzeugen.


Peter

Autor: semo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
danke peter

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: semo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: semo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.