Hi Senmeis,
der Gedanke hinter dem Macro ist (wie es der Text weiteroben
beschreibt), dass das Löschen des IEN, des globalen InterruptEnableBits,
eine ATOMIC sequence instruction ist. Das Löschen der einzelnen
EnableBits aber nicht.
Der Befehl IE_bit=0; muss also erst durch die Pipeline.
Das heißt also, wenn zum Beispiel du am Anfang einer Interrupt-Routine
den Interrupt vorübergehend sperren willst (zum Beispiel zum Entprellen)
solltest du darauf achten das inzwischen kein weiterer Interrupt
aufgetreten ist.
Folgendes Beispiel:
Du hast einen extrem prellenden Taster und willst seine Änderung mit
einem Interrupt auswerten.
Interrupts sind aktiv
Es wird der Taster gedrückt.
-> Interrupt löst aus.
-> der Controller springt zum ersten Befehl der ISR und löscht
automatisch das Interrupt-Flag.
Der erste Befehl in der ISR ist "disable Interrupt der ISR" damit das
Prellen des Testers die ISR nicht gleich noch einmal auslöst. Nun gehst
man davon aus, dass der Interrupt gesperrt ist. Dem ist aber nicht so,
dass dauert noch drei Zyklen (wenn ich mich jetzt nicht täusche) bis der
Befehl durch die Pipeline im Core angekommen ist.
das Makro sorgt nun dafür, dass nichst anderes gemacht wird bis das
lokale IEN gelöscht ist. Es sorgt sogar dafür, dass auch keine weiteren
Interrupts gemeldet werden können bis das lokale Flag gelöscht ist.
Das Makro ist also nur erforderlich, wenn man schnell auf einander
folgende Events ausblenden will, um parallele Interrupts (man kann ja
auch eine andere ISR deaktivieren) oder aber um aus dem Hauptprogramm
heraus ohne Pipelining-Effekte, definiert einen Interrupt zu
deaktivieren.
Gruß,
TManiac