www.mikrocontroller.net

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


Autor: Christoph K. (littledragonfly)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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);
}

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christoph Kregel schrieb:
 #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)
 {
 }

Fehlen da nicht zwei #pragma-Zeilen? Du hast zwar vier 
Interruptroutinen, aber nur zwei Interruptvektoren gesetzt.

Autor: Christoph K. (littledragonfly)
Datum:

Bewertung
0 lesenswert
nicht 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.
#define USCIAB1RX_VECTOR        ".int17"                    /* 0xFFE2 USCI A1/B1 Receive */
#else
#define USCIAB1RX_VECTOR        (17 * 1u)                    /* 0xFFE2 USCI A1/B1 Receive */
/*#define USCIAB1RX_ISR(func)     ISR_VECTOR(func, ".int17")  */ /* 0xFFE2 USCI A1/B1 Receive */ /* CCE V2 Style */
#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?

Autor: Jörg S. (joerg-s)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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.

Autor: Christoph K. (littledragonfly)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nach dem Durchlauf der Zeile
  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?

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>   IE2 |= UCB1RXIE;                     // Enable RX interrupt
>   UC1IE |= UCB1RXIE;

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

Autor: Christoph K. (littledragonfly)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Christoph K. (littledragonfly)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Yagan Ζ. Dongobar (yagan)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Christoph K. (littledragonfly)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
und wie funktioniert dieser Interrupt ?
Wo ist die passende Einsprungstelle?

Autor: Christoph K. (littledragonfly)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
bin jetzt den Weg ohne Interrupt gegangen.
dabei hat mir der Forumseintrag "I2C-Hardware Modul MSP430-Lib" 
weitergeholfen.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.