MSP430 und Interrupts

Gast #2760429
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
Gast #2760545
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
}
Gast #2760698
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
Gast #2760709
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
Gast #2760850
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
Persönliche Seite #2760897
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?
Gast #2760942
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.
Gast #2761288
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
}
Gast #2761307
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
Gast #2765326
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren