Forum: Mikrocontroller und Digitale Elektronik MSP430 I2C Interrupt wird nicht angesprungen


von Christoph K. (littledragonfly)


Angehängte Dateien:

Lesenswert?

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);
}

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

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.

von Christoph K. (littledragonfly)


Lesenswert?

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?

von Jörg S. (joerg-s)


Angehängte Dateien:

Lesenswert?

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.

von Christoph K. (littledragonfly)


Lesenswert?

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?

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

>   IE2 |= UCB1RXIE;                     // Enable RX interrupt
>   UC1IE |= UCB1RXIE;

Bist Du Dir hiermit sicher? Hier verwendest Du die gleiche 
Bitbezeichnung für zwei unterschiedliche Register.

von Christoph K. (littledragonfly)


Lesenswert?

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.

von Christoph K. (littledragonfly)


Lesenswert?

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?

von Yagan Ζ. D. (yagan)


Lesenswert?

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

von Christoph K. (littledragonfly)


Lesenswert?

und wie funktioniert dieser Interrupt ?
Wo ist die passende Einsprungstelle?

von Christoph K. (littledragonfly)


Lesenswert?

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
Noch kein Account? Hier anmelden.