Forum: Mikrocontroller und Digitale Elektronik MSP430: Interrupt Handling


von Laura (Gast)


Lesenswert?

Hi zusammen,

Ich möchte bei meinem MSP430 F1611 alle Interrupts ausschalten und zu 
beliebigen Zeitpunkten beliebige Interrupts zu- und wieder ausschalten 
können. Nachdem meine Routine durchgearbeitet wurde, sollten alle 
Interrupts in ihren ursprünglichen Zustand zurückgesetzt werden.

Bei mir fallen folgende Probleme an:

- Z.B möchte ich nur nur die Interrupts von Timer B0 (aber nicht 
diejenigen von TB1...7) aktiviert haben.
- Wie soll ich die Interruptzustände während der Routine 
zwischenspeichern?

Gibt es dazu eine besonders elegante Lösung? Oder ist dies nur über 
Flags und temporäre Variablen lösbar?

von Johnny (Gast)


Lesenswert?

Irgendwas sagt mir, dass Du wahrscheinlich alles zu kompliziert 
implementierst.
Warum willst Du denn bestimmte Interrupts überhaupt zur Laufzeit aus- 
und wieder einschalten?

von Laura (Gast)


Lesenswert?

Ich möchte mehrere zeitkritische Messungen durchführen. Unter Anderem 
eine Anstiegszeit am ADC und auch eine Time-Difference zwischen zwei 
Pulsen. Diese Zeitmessungen müssen möglichst exakt sein und dürfen 
deswegen nicht gestört werden.

von Laura (Gast)


Lesenswert?

OK, ich kann mein problem reduzieren:

Kann ich beim Timer_B nur die Interrupts von Timer 0 aktiviert haben? 
Die Interrupts von Timer 2...7 sollen deaktiviert werden.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

> Kann ich beim Timer_B nur die Interrupts von Timer 0 aktiviert haben?
> Die Interrupts von Timer 2...7 sollen deaktiviert werden.

Sieh Dir mal die Bedeutung des Bits CCIE in den Registern TBxCCTLn (n = 
Nummer der Capture/Compare Unit) an.

von Christian R. (supachris)


Lesenswert?

Beim GCC gibts außerdem das Attribut _critical_ oder so. Das kann man 
für Funktionen verwenden, da wird beim Start der Funktion der GIE 
ausgeschaltet, falls an, und am Ende wieder der Ausgangszustand 
hergestellt. Vielleicht hilft dir das auch. Prinzipiell kannst du aber 
bei jedem Timer-Block das CCIE löschen.

von Laura (Gast)


Lesenswert?

Wie funktioniert eine Lösung über Intrinsics? (IAR Embedded Workbench)
1
__istate_t s = __get_interrupt_state();
2
__disable_interrupt();
3
4
/* Do something */
5
6
__set_interrupt_state(s);
7
__enable_interrupt();

Kann ich im Abschnitt "Do something" Interrups ein- und ausschalten?

von Stefan (Gast)


Lesenswert?

1.) Du solltest Dir mal den Unterschied zwischen den einzelnen lokalen 
IE-Bits der jeweiligen Peripherie-Einheit und dem globalen GIE-Bit 
klar machen!

2.)
>Wie funktioniert eine Lösung über Intrinsics? (IAR Embedded Workbench)
Genauso wie die __monitor Funktion (s. Compiler Reference Guide)

3.) Dein Code-Fragment von oben ist sinnlos, denn nach Herstellen des 
ursprünglichen GIE-Zustands (__set_interrupt_state(s);) setzt Du in der 
nächsten Zeile bedingungslos wieder das GIE-Bit!

4.)
>Kann ich im Abschnitt "Do something" Interrups ein- und ausschalten?
Du kannst Ein- und Ausschalten was und wann immer Du es willst... ob's 
Sinn macht oder funktioniert ist 'ne andere Frage.

5.) Wenn Du einzelne IRQs beliebig aktivieren und deaktivieren willst, 
wirst Du nicht drum herum kommen, Dir selbst den Status zu merken und 
ggf. wieder herzustellen! Wenn Du alle IRQs de-/aktivieren willst, 
dann eben mit __monitor Funktion oder per __get/__set-Interrupt_state() 
aber ohne __enable_interrupt()

von geb (Gast)


Lesenswert?

Ich denke die durchsichtigste Variante ist immer noch das ablegen des 
Interrupt-enable bits in einer variablen. Da weißt du wenigstens immer 
genau was du tust.
Dennoch führt das ein und ausschalten von interrupts gerne zu seltsamen 
Fehlern, die oft erst nach tagelangem Testen "zufällig" auftreten. Es 
ist daher ratsam, genauestens zu überlegen, was alles in der kritischen 
Phase passieren könnte.

Grüße Gebhard

von Marco B. (Gast)


Lesenswert?

Stefan schrieb:

>3.) Dein Code-Fragment von oben ist sinnlos, denn nach Herstellen des
>ursprünglichen GIE-Zustands (__set_interrupt_state(s);) setzt Du in der
>nächsten Zeile bedingungslos wieder das GIE-Bit!

Laut Compiler Reference Guide reicht es, wenn man folgende Zeilen 
schreibt:
1
__istate_t s = __get_interrupt_state();
2
__disable_interrupt();
3
/* Do something */
4
__set_interrupt_state(s);

Warum benutzt man __enable_interrupt() nicht? Was bedeutet es, wenn das 
GIE-Bit wieder gesetzt wird?

von Stefan (Gast)


Lesenswert?

Der Sinn des ganzen ist es doch durch:
1
__set_interrupt_state(s);
den ursprünglichen Interruptzustand wiederherzustellen!
Wenn vorher GIE gesetzt war, soll es danach auch wieder gesetzt sein.
Wenn vorher GIE nicht gesetzt war, darf es hinterher auch nicht gesetzt 
werden... genau das würde aber __enable_interrupt(); gnadenlos tun!

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.