[wiki] AVR Flag verodern wirklich falsch?

Gast #1916048
Hi,

http://www.mikrocontroller.net/articles/AVR_Checkliste#Flag_richtig_gel.C3.B6scht.3F

> Zusätzlich ist zu beachten, dass in C die Interrupt-Flags nicht mit einer
> Veroderung des Registers (z. B. TIFR |= (1 << TOV0)) gelöscht werden
> sollten, da bei dieser Operation alle anderen evtl. gesetzten Flags im
> betreffenden Register ebenfalls gelöscht werden. Es ist die Schreibweise
> von oben zu benutzen (also TIFR = (1 << TOV0))!


??? !!! Stimmt das wirklich?

Wenn ich wirklich nur zu doof bin, löscht dieses Posting bitte.
Moderator (Firma: Titel) Persönliche Seite
Tom schrieb:
> ??? !!! Stimmt das wirklich?
Die Interruptflagregister verhalten sich anders als "normale" Register. 
Dort wird ein gesetztes Flag gelöscht, indem eine '1' hieneingeschrieben 
wird (siehe Datenblatt " TOV0 is cleared by writing a logic one to the 
flag.").
Wenn jetzt aber sowas dasteht:
1
TIFR |= (1 << TOV0))
Dann heißt das ja, dass zuerst das Register gelesen wird, dann ein Bit 
dazuverodert, und dann alles wieder zurückgeschrieben wird (ein 
Read-Modify-Write eben). Das könnte ausführlich auch so geschrieben 
werden:
1
h = TIFR;
2
h = h|(1 << TOV0));
3
TIFR = h;
Wenn jetzt blöderweise andere Interruptbits auch gesetzt sind, dann 
werden die als Kollateralschaden mit gelöscht.
Wenn z.B. TIFR == 0010 0001 ist und dann das alles abgearbeitet wird:
h = TIFR;            --->   h  == 0010 0001
h = h|(1 << TOV0));  --->   h  == 0010 0001
Und wenn das zurückgeschrieben wird, dann werden beide Interrupt-Flags 
gelöscht:
TIFR = h;            ---> TIFR == 0000 0000   :-o

Besser wäre also noch sowas:
TIFR &= (1 << TOV0));

Und am einfachsten geht es tatsächlich so:
TIFR = (1 << TOV0));
Gast
OK, mein Denkfehler war der, dass ich das für eine einfache Zuweisung, 
nur halt mit invertierter Wirkung, hielt.

Bei einer direkten Zuweisung des ganzen Registerinhaltes würden dann 
durch das Schreiben der Nullen in die Flagpositionen, die nicht 
ge/löscht/ werden, die Flags dort ge/setzt/ werden werden.

Aber das scheint die Hardware zu verhindern.
Tom schrieb:

> Bei einer direkten Zuweisung des ganzen Registerinhaltes würden dann
> durch das Schreiben der Nullen in die Flagpositionen, die nicht
> ge/löscht/ werden, die Flags dort ge/setzt/ werden werden.

Nein.
Du kannst diese Flags nur löschen. Gesetzt werden sie durch die 
Hardware.

Aber: Du willst immer nur dieses EINE Flag löschen, welches du löchen 
willst! Alle anderen sollen nicht beeinflusst werden.
Moderator (Firma: Titel) Persönliche Seite
Tom schrieb:
> OK, mein Denkfehler war der, dass ich das für eine einfache Zuweisung,
> nur halt mit invertierter Wirkung, hielt.
Richtig, das war der Denkfehler.

> Aber das scheint die Hardware zu verhindern.
Zum Glück...  ;-)
Dieses Verhalten findet man bei einigen anderen uC-Familien bei solch 
kritischen Registern, die auf Read-Modify-Write-Befehle allergisch 
reagieren (könnten).
Es gibt dann evtl. sogar getrennte Register zum Setzen von Flags und 
Löschen vom Flags. Wenn dann in also das "Setz-Register" eine '1' 
geschrieben wird, wird das Bit gesetzt, wenn in das "Lösch-Register" 
eine '1' geschrieben wird, wird das entsprechende Bit im Zielregister 
zurückgesetzt.
Beim AVR gibt es von dieser "Vollausstattung" quasi nur das 
Lösch-Register.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 16 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.