MSP430: Interrupt Handling

Gast #1320229
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?
Gast #1320284
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.
#1320383
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.
Gast #1320399
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?
Gast #1320581
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()
Gast #1320721
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
Gast #1343351
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?
Gast #1343801
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!

Antwort schreiben

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.

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.