www.mikrocontroller.net

Forum: Compiler & IDEs Timer Problem


Autor: Fabian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich bin gerade dabei etwas den Umgang mit GCC zu lernen und bin dabei
auf folgendes Problem gestoßen.

Bei einem Timer gibt es doch im TIFR ein Overflow Flag namens TOV
welches beim Timerdurchlauf auf "1" gesetzt wird und welches man dann
selbst wieder auf "0" setzen muss, damit es beim nächsten Durchlauf
wieder auf "1" gesetzt wird. Richtig?????.

So nun habe ich mir einen 8-Bit timer gebastelt und wollte das TOV Flag
abfragen dann das Prog. in eine If Abfrage laufen lassen und dann das
TOV flag wieder auf "0" setzen.

Um das TOV Flag auf "0" zu setzen habe ich folgenden Befehl
verwendet.

TIFR &=~ (1<<TOV0);

leider klappt es nicht. das Flag bleibt einfach "1"

Nun ist mir aber aufgefallen, dass ich wenn ich den Befehl zum setzen
des Flags sprich

TIFR |= (1<<TOV0);

einsetze, das Flag zurückgesetzt wird.... Das verwirrt mich nun
etwas..
Kann mir jemand erklären, was ich falsch gemacht habe??

danke

Fabian

Autor: Volker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Fabian,

das ist völlig normal. Hier ein Auszug aus einem AVR-Datenblatt.
----
TOV0 is cleared by
hardware when executing the corresponding interrupt handling vector.
Alternatively,
TOV0 is cleared by writing a logic one to the flag.
----

Es wird also geöscht, wenn man eine 1 reinschreibt.


Bin ich auch schon mal drüber gestolpert.

Gruß Volker

Autor: Fabian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hm das is ja irgendwie seltsam. Naja okay wenn man es weiß.

Okay aber vielen Dank dann is mein Syntax schonmal nicht Falsch..

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich sach mal, jeder der die AVRs anfäßt, stolpert unweigerlich
mindestens einmal darüber (ich auch).

Verstehen kann man es nicht, man muß es eben akzeptieren.


Beim 8051 löscht man die Bits mit ner 0, wie es sich gehört und man
kann sie sogar setzen (= Software-Interrupt), gefällt mir viel besser.


Peter

Autor: Michael U. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

@Peter Dannegger:

dazu muß man nicht erst auf den AVR warten, da bin ich schon vor Jahren
drüber gestolpert. Weiß nicht mehr, ob Z80 oder 6510 oder beide. Ist
zumindest nicht neu, das Problem. ;)

Gruß aus Berlin
Michael

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Verstehen kann man es nicht, man muß es eben akzeptieren.

Doch, man könnte in der FAQ nachlesen, warum das so Sinn hat:

http://www.nongnu.org/avr-libc/user-manual/FAQ.htm...

Natürlich hat es nur bei denen richtig Sinn, die in einem eigenen
Register liegen, das ausschließlich Interrupt-Flags hat.  Bei allen
anderen kann man ja nicht so ohne weiteres ein 1-Bit drüberbügeln
bzw. man muss sich den Status der restlichen Bits anderweitig merken.
Dennoch wurde es wohl bei allen Interruptflags, die man überhaupt ,,zu
Fuß'' löschen kann, so gemacht, vermutlich aus Konsistenzgründen.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Okay aber vielen Dank dann is mein Syntax schonmal nicht Falsch..

Doch, ist es, wiederum siehe FAQ.

TIFR |= (1<<TOV0);

riskiert eine race condition, während

TIFR = (1<<TOV0);

diese vermeidet.  Sieht auf den ersten Blick widersinnig aus,
ist aber so.  Ist natürlich egal, wenn du keinen weiteren
Timer-Interrupt benutzt, aber man gewöhnt es sich besser gleich
richtig an.

Autor: Fabian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Puh Race Condition?
Ich bin erst seit 3 Tagen dabei also weiß ich nicht gerade worum es
geht.
Ich dachte durch |= wird das Ergebnis mit dem Register "Verodert"
oder nicht?

Autor: Michael U. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

zwar ist C nicht meine Stärke, aber das Problem ist, wenn Du ihm sagst
er soll "verodern", dann holt er den Wert in ein Register, führt das
OR aus und schreibt zurück.
Da aber in diesem Register mit dem Schreiben einer 1 das Flag gelöscht
wird, werden auch alle anderen INT-Flags mit gelöscht, das aber soll ja
nicht passieren.

Eine "race condition" sagt nur, daß unter Umständen beim
Zusammentreffen bestimmter Umstände ein fehlerhaftes Verhlaten
auftritt. Sowas sollte man möglichst früh erkennen und immer
vermeiden.

Die meisten Fehler baut man sich in Programme ein, weil man zwar den
gewollten Ablauf x-mal durchdenkt, die Überprüfung, was passiert bei
allen anderen möglichen Umständen, aber versäumt.

Naja, das geht nicht nur Dir so. ;)

Gruß aus Berlin
Michael

Autor: Fabian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Achso.... Okay denn is es klar. Nochmals vielen Dank.

Eine kleine Frage hätte ich aber noch zu dem Thema.
Kann ich auf die einzelnen Bits des TCNT Registers nicht direkt
zugreifen?
Ich arbeite mit dem GCC Tutorial dieser Seite und dort ist (falls es
jmd. vorliegen hat) auf Seite 36 das TCNT0 Register abgebildet. So nun
spricht man die einzelnen Bits ja mit z.B.

TCNT0 |=(1<<Bitname);

nur bei den Bit´s steht im Tutorial kein Name.
Heisst das ich kann nur indirekt drauf zugreifen durch
TCNT0 |=0xff;

Es macht zwar keinen direkten Sinn die Bits zu beschreiben, es ist eher
so ne allgemeine Frage, wie man auf Bits zugreift, die keinen direkten
Namen haben?

Autor: Michael U. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

naja, wie sollte ein Bit im TCNT0 auch sinnvoll heißen?
Die Namen sollen das Ganze ja nur lesbarer machen, wenn Du auf andere
Bits unbedingt einzeln zugreifen willst, kannst Du so machen, wie Du
schreibst oder Du benutzt die Bitnummer.

TCNT0 |=(1<<Bitnummer);  Bitnummer eben 0...7

Gru0 aus Berlin
Michael

Autor: Fabian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Achso das geht?
Okay vielen Dank... hätte ich eigentlich auch ma selbst drauf kommen
können.

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.