Forum: Compiler & IDEs MSP430 und Interrupts


von Olaf (Gast)


Lesenswert?

Kann mir mal jemand erzaehlen wie das mit den Interrupts beim
msp430 funktioniert? (genauer gesagt einem MSP430F135)

Ich weiss das ich hiermit:

interrupt (UART0RX_VECTOR) recievebyte(void)
{

}

eine Interruptfunktion erzeuge. Aber die muss ja noch irgendwie in die 
Interrupttabelle kommen. Der Controller hat wohl nur eine Tabelle im 
Flash.

Der gcc liefert eine crt430x135.0 file wo die angeblich drin definiert 
wird.
Muss ich dieses file jetzt neu erzeugen, oder erzeugt der gcc eine 
Sprungtabelle im Ram und traegt da meine funktion ein?

Wie ist da die uebliche vorgehensweise?

Olaf

von User (Gast)


Lesenswert?

Beispiel von TI:
1
#include "cc430x613x.h"
2
3
void main(void)
4
{
5
  WDTCTL = WDTPW + WDTHOLD;                 // Stop watchdog timer
6
  P1DIR |= BIT0;                            // Set P1.0 to output direction
7
  P1REN |= BIT4;                            // Enable P1.4 internal resistance
8
  P1OUT |= BIT4;                            // Set P1.4 as pull-Up resistance
9
  P1IE |= BIT4;                             // P1.4 interrupt enabled
10
  P1IES |= BIT4;                            // P1.4 Hi/Lo edge
11
  P1IFG &= ~BIT4;                           // P1.4 IFG cleared
12
13
  __bis_SR_register(LPM4_bits + GIE);       // Enter LPM4 w/interrupt
14
  __no_operation();                         // For debugger
15
}
16
17
// Port 1 interrupt service routine
18
#pragma vector=PORT1_VECTOR
19
__interrupt void Port_1(void)
20
{
21
  P1OUT ^= 0x01;                            // P1.0 = toggle
22
  P1IFG &= ~0x010;                          // P1.4 IFG cleared
23
}

von Olaf (Gast)


Lesenswert?

> Beispiel von TI:

Aehem...du beantwortest meine Frage nicht!

> #pragma vector=PORT1_VECTOR __interrupt void Port_1(void)

Wer traegt das in deine Vectortabelle ein? Du? Oder verwaltet der 
Compiler das automatisch? Wie kommt die Adresse von Port_1 nach 0xffxx?

Ich kenne bisher nur Controller die haben ein Register fuer die 
Vektortabelle. Da habe ich die dann im Ram liegen und trage die Adresse 
meiner Tabelle in das Register ein. Aber so fortschrittlich scheinen die 
MSP noch nicht zu sein.

Olaf

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Olaf schrieb:
> Oder verwaltet der Compiler das automatisch?

So ist es, auch wenn es im Detail der Linker sein dürfte.

von ich (Gast)


Lesenswert?

die MSP's haben soweit ich das in Erinnerung habe eine fixe Zuordnung 
der Peripherie-Interrupts zur Tabelle.

Falls am Prot1 ein interrupt auftritt und du diesen auch freigegeben 
hast, wird an die festgelegte Adresse gesprungen.

such mal nach MSP430F135.h

dort müssten die Adresse zu finden sein

von Olaf (Gast)


Lesenswert?

> Falls am Prot1 ein interrupt auftritt und du diesen auch freigegeben
> hast, wird an die festgelegte Adresse gesprungen.

Tja, mein Problem ist aber das der Interrupt eben nicht dazu fuehrt das 
die Routine ausgefuehrt wird, sondern das sich der Prozessor weghaengt.
Daher habe ich den Verdacht das der Compiler/Linker die Adresse eben 
nicht eintragen.

Olaf

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Sieh Dir doch mal das resultierende Hexfile an, darin müsstest Du 
eigentlich die Interrupttabelle finden können.

Und wenn der Interrupt nicht ausgelöst wird, dann liegt das vielleicht 
auch daran, daß Du die Peripherie nicht korrekt initialisierst und 
stattdessen ein anderer Interrupt ausgelöst wird, für den es aber keinen 
Handler gibt ...

Was macht denn Dein Programm genau?

von ISR (Gast)


Lesenswert?

Olaf schrieb:
> Wer traegt das in deine Vectortabelle ein? Du? Oder verwaltet der
> Compiler das automatisch? Wie kommt die Adresse von Port_1 nach 0xffxx?
>
> Ich kenne bisher nur Controller die haben ein Register fuer die
> Vektortabelle.

Der MSP430 ist da nichts besonderes. Zu jeder Interruptquelle gibt es 
eine feste Adresse, die bei einem Interrupt event angesprungen wird. Das 
ist die Interruptvektor-Tabelle aus dem Datenblatt. Manche 
Interruptquellen teilen sich eine Adresse. Dann muss in der ISR die 
Quelle ermittelt werden. Auf der Adresse der Interruptvektor-Tabelle 
steht meist ein jump in die programmierte ISR, die der Linker irgendwo 
hingelegt hat.

von Pako (Gast)


Lesenswert?

Olaf schrieb:
> Tja, mein Problem ist aber das der Interrupt eben nicht dazu fuehrt das
> die Routine ausgefuehrt wird, sondern das sich der Prozessor weghaengt.

Meines Wissens hat der MSP430 eine "Besonderheit":
Das Interrupt Request Flag muß von Hand gelöscht werden.
Falls Du das nicht machst, wird die ISR immer und immer wieder 
ausgeführt und der Prozessor "hängt sich weg".

Guckst Du beispiel:
1
// Port 1 interrupt service routine
2
#pragma vector=PORT1_VECTOR
3
__interrupt void Port_1(void)
4
{
5
  P1OUT ^= 0x01;                            // P1.0 = toggle
6
  P1IFG &= ~0x010;                          // P1.4 IFG cleared
7
}

von PW (Gast)


Lesenswert?

@Pako:
Beim Port Interruppt stimmt das, hier muss das PxIFG flag von Hand 
gelöscht werden, hängt aber beim MSP vom Derivat und vom vernwedeten 
Paripheral ab.

@olaf: wie hast du getestet, ob die Funktion nicht aufgerufen wird? 
Breakpoint im debugger?
Wenn der nicht zuschlagt hast du evtl. den Port nicht richtig 
configuriert, schau mal nach dem PxIE bit


Peter

von ISR (Gast)


Lesenswert?

Pako schrieb:
> Meines Wissens hat der MSP430 eine "Besonderheit":
> Das Interrupt Request Flag muß von Hand gelöscht werden.

PW schrieb:
> Beim Port Interruppt stimmt das, hier muss das PxIFG flag von Hand
> gelöscht werden,

Nichts besonderes. Der Vektor wird geteilt. Er kann nicht durch HW 
gelöscht werden, da ja mehrere Ereignisse anstehen können.

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.