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
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 | }
|
> 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
Olaf schrieb: > Oder verwaltet der Compiler das automatisch? So ist es, auch wenn es im Detail der Linker sein dürfte.
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
> 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
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?
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.
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 | }
|
@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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.