Hallo Ich versuche mit einem MSP430F2418 einen Temperaturfühler TMP100, auch von Texas, auszulesen.Dies funktioniert über die I2C-Schnittstelle des MSP. Die Konfiguration des Fühlers wird über schreiben in die Register von ihm gemacht. Dies Funktioniert auch, beim auslesen kommen auch Werte zurück. Nun habe ich aber das Problem das die Interruptroutine nicht angesprungen wird, um alle Bytes einzeln empfangen zu können. Kann mir da jemand weiterhelfen? Ich verwende auch beide Uart-schnittstellen, bei denen habe ich keine Probleme mit dem Interrupt. Hier funktioniert alles reibungslos. Hab aus von der Interrputroutine den Inhalt aus Platzgründen entfernt ///////////////////////////////////////// // Interrupt routine #pragma vector=USCIAB0RX_VECTOR //UCA0 - UART0 - RX __interrupt void USCIA0RX_ISR (void) { } __interrupt void USCI0RX_ISR(void) { } #pragma vector=USCIAB1RX_VECTOR //UCA1 - UART1 - RX __interrupt void USCI1RX_ISR(void) { } //UCB1 - I2C - RX __interrupt void USCIB1RX_ISR(void) { } //////////////////////////////////////// //Initialisierung der I2C Schnittstelle am Anfang unsigned char chI2C_Init(void) { P5SEL |= 0x06; //I2C active UCB1CTL1 |= UCSWRST; // Enable SW reset UCB1CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode UCB1CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset UCB1BR0 = 73; // fSCL = SMCLK /73 = ~100kHz UCB1BR1 = 0; UCB1I2CSA = 0x048; // Slave Address is 048h UCB1CTL1 &= ~UCSWRST; // Clear SW reset, resume operation IE2 |= UCB1RXIE; // Enable RX interrupt UC1IE |= UCB1RXIE; return 1; } ///////////////////////////////////////// // Einstellen von Fühler Register void StartConfI2C(int TmpAdresse) { UCB1I2CSA = TmpAdresse; // UCB1I2CSA = 0x01; UCB1CTL1 = UCSSEL_2 + UCTR + UCTXSTT ; //Adresse nach Start auto while (!(UC1IFG & UCB1TXIFG)); UCB1TXBUF = 0x01 ; //Register while (!(UC1IFG & UCB1TXIFG)); UCB1TXBUF = 0xE1 ; UCB1CTL1 |= UCTXSTP ; wait(2); UCB1CTL1 = UCSSEL_2 + UCTR + UCTXSTT ; wait(1); while (!(UC1IFG & UCB1TXIFG)); UCB1TXBUF = 0x00 ; wait(1); UCB1CTL1 |= UCTXSTP ; } ///////////////////////////////////////// //Auslesen des Temperaturwertes int StartReadI2C(int TmpAdresse) { UC1IE |= UCB1RXIE; UCB1I2CSA = TmpAdresse; UCB1CTL1 = UCSSEL_2 + UCTXSTT ; test = UCB1RXBUF; UC1IFG = UCB1TXIFG + UCA1TXIFG; UCB1CTL1 = UCSSEL_2 + UCTXSTP ; return(test); }
Christoph Kregel schrieb:
1 | #pragma vector=USCIAB0RX_VECTOR
|
2 | |
3 | //UCA0 - UART0 - RX
|
4 | __interrupt void USCIA0RX_ISR (void) |
5 | {
|
6 | }
|
7 | __interrupt void USCI0RX_ISR(void) |
8 | {
|
9 | }
|
10 | |
11 | #pragma vector=USCIAB1RX_VECTOR
|
12 | |
13 | //UCA1 - UART1 - RX
|
14 | __interrupt void USCI1RX_ISR(void) |
15 | {
|
16 | }
|
17 | //UCB1 - I2C - RX
|
18 | __interrupt void USCIB1RX_ISR(void) |
19 | {
|
20 | }
|
Fehlen da nicht zwei #pragma-Zeilen? Du hast zwar vier Interruptroutinen, aber nur zwei Interruptvektoren gesetzt.
Habs mal ausprobiert. Mit dem gleichen Pragma geht es nicht, und ein anderes weis ich nicht.Leider kenne ich mit der Interruptroutine nicht so gut aus. Im passenden Header File von dem MSP das msp430x24x.h steht folgendes.
1 | #define USCIAB1RX_VECTOR ".int17" /* 0xFFE2 USCI A1/B1 Receive */ |
2 | #else
|
3 | #define USCIAB1RX_VECTOR (17 * 1u) /* 0xFFE2 USCI A1/B1 Receive */ |
4 | /*#define USCIAB1RX_ISR(func) ISR_VECTOR(func, ".int17") */ /* 0xFFE2 USCI A1/B1 Receive */ /* CCE V2 Style */ |
5 | #endif
|
Somit sind beide Receiver ports von A1 und B1 mit diesem Pragma verbunden, denke ich. Die A1 ist eine Uart Schnittstelle die auch einwandfrei funktioniert. Hat jemand erfahrung mit dem Interrupt handling von Uart und I2C gleichzeitig?
Ja, ich glaube darüber bin ich auch schon mal gestolpert. Wenn man sich die Vectortabelle ansieht, gibt es nur 4 Vectoren für die USCI. Den Ursprung des Aufrufs (UART oder I2C) kann man glaub ich nicht zweifelsfrei festellen. PS: Bei Prio 17 scheint ein Fehler in der Tabelle zu sein. USCI_A0 wird wohl eher USCI_A1 sein.
Nach dem Durchlauf der Zeile
1 | UCB1CTL1 = UCSSEL_2 + UCTXSTT ; |
wird im UCB1RXBUF ein 0x16 angezeigt. Gleichzeitig wird im UC1IFG das UCB1RXIFG Bit gesetzt. Das UC1IE UCB1RXIE Bit ist auch gesetzt. Der Interrupt löst aber nicht aus. Nun bekomme ich aber wenn ich versuche den Wert in test zu schreiben nur 0xff gespeichert. Das gleiche steht auch im Buffer wenn die Lesesequence durchlaufen ist. Muss man die UC1IE noch zusätzlich scharf schalten?
> IE2 |= UCB1RXIE; // Enable RX interrupt > UC1IE |= UCB1RXIE; Bist Du Dir hiermit sicher? Hier verwendest Du die gleiche Bitbezeichnung für zwei unterschiedliche Register.
Das hab ich vergessen raus zu nehmen. Im IE2 sind nur die RX/TX IE von A0 und B0. Die Zeile habe ich raus genommen, was aber leider an meinem Interrupt Problem nichts ändert.
Hatte noch niemand dieses Problem? Für den B1 Interrupt I2C muss an sich nur GIE und UCB1RXIE gesetzt werden? Die Schnittstelle A1 ist für Uart configuriert, kann diese den Interrupt stören?
Christoph, sinnvoll ist noch wenigstens den NACK-Interrupt zu aktivieren (also zusätzlich UCB1IE |= UCNACKIE zulassen), damit du es mitbekommst, wenn die Adressierung fehlschlägt oder das letzte Byte empfangen wurde. Ciao, Yagan
und wie funktioniert dieser Interrupt ? Wo ist die passende Einsprungstelle?
bin jetzt den Weg ohne Interrupt gegangen. dabei hat mir der Forumseintrag "I2C-Hardware Modul MSP430-Lib" weitergeholfen.
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.