mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik MSP430: Interrupt Handling


Autor: Laura (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Johnny (Gast)
Datum:

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

Autor: Laura (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Laura (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Christian R. (supachris)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Laura (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie funktioniert eine Lösung über Intrinsics? (IAR Embedded Workbench)
__istate_t s = __get_interrupt_state();
__disable_interrupt();

/* Do something */

__set_interrupt_state(s);
__enable_interrupt();

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

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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()

Autor: geb (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Marco B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
__istate_t s = __get_interrupt_state();
__disable_interrupt();
/* Do something */
__set_interrupt_state(s);

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

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Sinn des ganzen ist es doch durch:
__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

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
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.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.