I2C-Verbindung zwischen zwei MSP430 Mikrocontrollern

#2918903
Lesenswert?

Hallo,

wir sollen für das Mikrocontroller-Labor an der Hochschule eine 
Kommunikation zwischen zwei Controllern (MSP430F5438) über I2C 
herstellen.
Da ich sehr wenig Erfahrung mit der Pogrammierung eines Mikrocontrollers 
habe, möchte ich erst einmal ein Zeichen von Slave zu Master senden.
Dazu habe ich mir die TI-Examples msp430x54xA_uscib0_i2c_04 und _05.c 
angeschaut und vereinfacht.

Die Initialisierung habe ich soweit verstanden.
Bei den Start- / Stoppbedingungen innerhalb der for-Schleifen bin ich 
mir ziemlich unsicher. Wie genau verwendet man diese?
Kann die Übertragung mit den beiden Codes so funktionieren?

Danke schonmal!

Viele Grüße
Thiemo
1
// *******************
2
//     MASTER-CODE
3
// *******************
4

5
#include <msp430.h>
6

7
unsigned char EmpfZeichen;
8

9
int main(void)
10
{
11
  WDTCTL = WDTPW + WDTHOLD;              // Watchdog aus
12
  P3SEL |= 0x06;                         // P3.1 und P3.2 für I2C
13
  UCB0CTL1 |= UCSWRST;                   // en Softwarerese zur
14
                                         // Initialisierung
15
  UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC;  // Master, synchrone Übertragung
16
  UCB0CTL1 = UCSSEL_2 + UCSWRST;         // Taktquelle: SMCLK
17
  UCB0BR0 = 0x12;                        // Einstellungen zur Übertragung
18
  UCB0BR1 = 0x00;
19
  UCB0I2CSA = 0x48;                      // Slave-Adresse = 0x48
20
  UCB0CTL1 &= ~UCSWRST;                  // clr Softwarerest, da Init.
21
                                         //  fertig
22
  UCB0IE |= UCRXIE;                      // en empf. Interrupt
23

24
  for(;;)
25
  {
26
    while (UCB0CTL1 & UCTXSTP);          // Stopp-Bed. gesendet?
27
    UCB0CTL1 |= UCTXSTT;                 // Start-Bed.
28

29
    while (UCB0CTL1 & UCTXSTP);          // Start-Bed. gesendet?
30
    UCB0CTL1 |= UCTXSTP;                 // Stopp-Bed.
31

32
    EmpfZeichen = UCB0RXBUF;             // Empfangenes Zeichen in
33
                                         // EmpfZeichen ablegen
34
  }
35
}
1
// *******************
2
//     SLAVE-CODE
3
// *******************
4

5
#include <msp430.h>
6

7
unsigned char GesZeichen;
8

9
int main(void)
10
{
11
  WDTCTL = WDTPW + WDTHOLD;              // Watchdog aus
12
  P3SEL |= 0x06;                         // P3.1 und P3.2 für I2C
13
  UCB0CTL1 |= UCSWRST;                   // en Softwarerese zur 
14
                                         // Initialisierung
15
  UCB0CTL0 = UCMODE_3 + UCSYNC;          // Slave, synchrone Übertragung
16
  UCB0I2COA = 0x48;                      // eigene Adresse des Slave (0x48)
17
  UCB0CTL1 &= ~UCSWRST;                  // clr Softwarerest, da
18
                                         // Init. fertig
19
  UCB0IE |= UCTXIE+UCSTTIE+UCSTPIE;      // en send. Interrupt 
20

21
  GesZeichen = 'A';
22

23
  for(;;)
24
  {
25
    UCB0IFG &= ~UCSTTIFG;     // Start-Bed.    
26

27
    UCB0TXBUF = GesZeichen;   // Sende 'A' an Master
28

29
    UCB0IFG &= ~UCSTPIFG;     // Stopp-Bed
30
  }
31
}
Persönliche Seite #2918944
Lesenswert?

Thiemo B. schrieb:
> for(;;)
>   {
>     UCB0IFG &= ~UCSTTIFG;     // Start-Bed.
>
>     UCB0TXBUF = GesZeichen;   // Sende 'A' an Master
>
>     UCB0IFG &= ~UCSTPIFG;     // Stopp-Bed
>   }

Das wird so sicher nicht funktionieren. Überlege mal, wie schnell diese 
Schleife durchlaufen wird, und überlege, wie lange es dauert, ein 
einzelnes Byte per I2C zu übertragen. Du stopfst also ständig neue 
Zeichen in die USCI, ohne darauf zu warten, daß sie mit dem Übertragen 
fertig wird.

Sieh Dir also nochmal genau den Code im TI-Beispiel an.
#2919643
Lesenswert?

Rufus Τ. Firefly schrieb:
> Sieh Dir also nochmal genau den Code im TI-Beispiel an.

Danke für die schnelle Antwort!
Habe es mir noch einmal angeschaut und wie folgt verbessert:
1
  for(;;)
2
  {
3
    if (UCB0IV == 0x06)    // Start-Bed. erhalten?
4
       UCB0IFG &= ~UCSTTIFG;  // dann clr Start-Bed. Int-Flag
5

6
    if (UCB0IV == 0x08)    // Stopp-Bed. erhalten?
7
       UCB0IFG &= ~UCSTPIFG;  // dann clr Stopp-Bed. Int-Flag
8

9
    if (UCB0IV == 0x0C)    // Sende-Puffer leer?
10
       UCB0TXBUF = GesZeichen;  // dann sende Zeichen
11
  }

Habe auch den Master-Code so korrigiert, dass das Zeichen nur dann in 
'EmpfZeichen' geschrieben wird, wenn wirklich Daten empfangen wurden:
1
    if (UCB0IV == 0x0A)            // wenn Daten empfangen, dann lege
2
      EmpfZeichen = UCB0RXBUF;     // Empfangenes Zeichen in EmpfZeichen ab

Ist das richtig so oder habe ich noch etwas übersehen oder vergessen?

Grüße
Thiemo

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