Forum: Mikrocontroller und Digitale Elektronik I2C-Verbindung zwischen zwei MSP430 Mikrocontrollern


von Thiemo B. (thiemo87)


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
}

von Rufus Τ. F. (rufus) Benutzerseite


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.

von Peter D. (peda)


Lesenswert?

Ich würde vermeiden, 2 Baustellen gleichzeitig zu öffnen.

Daher zuerst mal den Master machen und nen PCF8574 lesen und schreiben.
Und dann einen Slave, der den PCF8574 emuliert.


Peter

von Thiemo B. (thiemo87)


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

von Thiemo B. (thiemo87)


Lesenswert?

@ Peter
Das hatte ich auch vor. Habe allerdings nur zur "Labor-Zeit" Zugang zu 
den Controllern und die Kommunikation soll bis Dienstag laufen...

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.