Forum: Mikrocontroller und Digitale Elektronik Interrupt Flag


von Georg M. (g_m)


Angehängte Dateien:

Lesenswert?

Hallo,
folgendes Verständnisproblem.

> This flag is set...
> Writing a ‘1’ to this bit clears the flag.

Wie ist das zu verstehen? Es steht schon eine "1", und um sie zu löschen 
muss man eine "1" schreiben?
Müsste eine "0" geschrieben werden, wäre es aus meiner Sicht 
selbstverständlich, aber so wie jetzt, brauche ich eine Erläuterung.

von Nop (Gast)


Lesenswert?

Georg M. schrieb:

> Wie ist das zu verstehen? Es steht schon eine "1", und um sie zu löschen
> muss man eine "1" schreiben?

Eben so.

> Müsste eine "0" geschrieben werden, wäre es aus meiner Sicht
> selbstverständlich, aber so wie jetzt, brauche ich eine Erläuterung.

Das ist ein Register, kein Speicher. Es kann alles an Logik hinter dem 
Bit stecken.

von Sebastian R. (sebastian_r569)


Lesenswert?

Es ist sehr einfach, aus Versehen eine 0 zu schreiben. Eine 1 zu 
schreiben musst du schon wollen. Dadurch verringert sich die Gefahr, das 
Bit versehentlich zu löschen.

Und eine 1 lässt sich besser maskieren. Und die internen Flipflops haben 
evtl. einen Reset-Eingang, der mit einer 1 das FF resettet.

von Programmierer (Gast)


Lesenswert?

Solche Register haben noch einen Vorteil: Man kann jeweils exakt die 
Flags löschen, die man zuvor abgefragt hat, und in einer Schleife alle 
weiter aufgetretenen Flags verarbeiten:
1
uint8_t flags = INTFLAGS;
2
do {
3
  // Die jetzt bearbeiteten Flags löschen
4
  INTFLAGS = flags;
5
  
6
  if (flags & (1 << CMP)) {
7
    // CMP aufgetreten...
8
  }
9
  if (flags & (1 << OVF)) {
10
    // OVF aufgetreten...
11
  }
12
  // Neue Flags abfragen
13
  flags = INTFLAGS;
14
} while (flags != 0);

Wenn während der Bearbeitung neue Interrupts auftreten, muss die ISR 
nicht verlassen und erneut betreten werden (langsam), sondern nur direkt 
die Schleife neu starten. Wenn nach der Schleife neue Interrupts 
auftreten, wird die ISR aber doch erneut betreten. So kann man 
sicherstellen dass kein Ereignis verschluckt wird, es sei denn es tritt 
in sehr kurzer Folge der gleiche Interrupt noch einmal auf; das lässt 
sich aber sowieso nur durch schnelle Abarbeitung verhindern.

Besonders bei komplexerer Peripherie auf größeren Controllern mit vielen 
verschiedenen Interrupts (z.B. Timer oder USB-OTG bei den STM32) ist so 
ein Vorgehen sinnvoll.

von Oliver S. (oliverso)


Lesenswert?

Sebastian R. schrieb:
> Es ist sehr einfach, aus Versehen eine 0 zu schreiben.

Na ja, wenn es nur 0 und 1 gibt, ist die Chance, eins von beiden 
ausversehen zu schreiben, ziemlich gleich verteilt.

Oliver

von m.n. (Gast)


Lesenswert?

Man liest das Flag-Register, speichert den Wert temporär und hat alle 
gesetzten Flags damit erfaßt. Um sie zu löschen, wird der gelesene Wert 
wieder geschrieben.

Wenn zwischendurch noch weitere Flags gesetzt wurden, die noch nicht 
erkannt wurden, bleiben diese weiterhin gesetzt.
Eine ganz saubere Sache!

von Georg M. (g_m)


Lesenswert?

Nop schrieb:
> Das ist ein Register, kein Speicher. Es kann alles an Logik hinter dem
> Bit stecken.

Das heißt, dieses Byte, diese 8 R/W-Bits, das ist nur eine vereinfachte 
irreführende Darstellung? In Wirklichkeit ist alles anders und viel 
komplizierter?

von Programmierer (Gast)


Lesenswert?

Georg M. schrieb:
> Das heißt, dieses Byte, diese 8 R/W-Bits, das ist nur eine vereinfachte
> irreführende Darstellung?

Es ist nunmal die Schnittstelle, auf die der CPU-Kern zugreift. In 
diesem Fall sind es ja nichtmal 8 bits. Der AVR-CPU-Kern kann 8 Bits 
über den Bus lesen und schreiben, und die Peripherie präsentiert ihre 
Signale eben als 8-Bit-Register. Die interne Logik muss sich aber nicht 
verhalten wie eine gewöhnliche Speicherzelle...

von Nop (Gast)


Lesenswert?

Georg M. schrieb:

> Das heißt, dieses Byte, diese 8 R/W-Bits, das ist nur eine vereinfachte
> irreführende Darstellung?

Es ist vereinfacht, und die entscheidende Info dabei ist, ob man die 
Bits nur lesen oder auch schreiben kann. Es gibt ja auch read-only-bits.

> In Wirklichkeit ist alles anders und viel komplizierter?

Sozusagen. Wenn man in einen Speicher was reinschreibt, wird es da 
gespeichert und gut. Bei einem Register kann dahinter alles mögliche 
passieren. Es gibt ja auch Register, wo man eine 1 reinschreiben darf, 
aber beim Zurücklesen kommt trotzdem immer 0.

von Peter D. (peda)


Lesenswert?

Beim AVR ist die Sache recht verzwickt, er kann die meisten 
Interruptbits nicht atomar löschen. D.h. liest man ein IO-Register, 
setzt einzelne Bits auf 0 und schreibt es wieder zurück, können in der 
Zwischenzeit eingetroffene Interrupts im selben IO-Register verloren 
gehen. Daher der Umweg, daß nur gesetzte Bits gelöscht werden, nicht 
gesetzte bleiben unverändert.

Z.B. beim 8051 ist ein atomares AND/OR im IO-Bereich möglich, daher 
werden dort die Interrupts mit auf 0 setzen gelöscht. Und man kann sogar 
Interrupts in SW setzen. Z.B. füllt man eine FIFO und startet dann das 
erste Byte senden mit dem Setzen des TI-Bits.

von Gleichstrom (Gast)


Lesenswert?

Sebastian R. schrieb:
> Es ist sehr einfach, aus Versehen eine 0 zu schreiben. Eine 1 zu
> schreiben musst du schon wollen. Dadurch verringert sich die Gefahr, das
> Bit versehentlich zu löschen.

Nein, das ist nicht der Grund für dieses Registerverhalten.

Der Grund ist, dass man nur so einzelne Flags löschen kann, ohne 
gleichzeitig die anderen auch zu beeinflussen. Eine 0 beeinflusst das 
Bit nicht. Es behält seinen vorherigen Zustand.
Auch durch klassisches auslesen-modifizieren-schreiben wäre das Problem 
nicht lösbar, weil sich in der Zwischenzeit das Bit ändern könnte.

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
Noch kein Account? Hier anmelden.