Forum: Mikrocontroller und Digitale Elektronik Wie I2C von MSP430F1611 auf MSP430F5435 umprogrammieren


von Wolle G. (wolleg)


Lesenswert?

Als Beispiel soll eine Uhr DS32C35 über I2C betrieben werden. Dazu habe 
ich ein funktionierendes MSP430F1611-Programm, welches mir die Uhrzeit 
und das Datum ausliest und anzeigt.
Hier das gekürzte Programm (nur für Sekunden) mit einem MSP430F1611 :

void I2C_Init (void)
{
  P3SEL |= 0x0A;          // Assign I2C pins to module
  U0CTL &= ~I2CEN;        // Recommended init procedure ---schaltet I2C 
aus
  U0CTL |= I2C + SYNC;    // schaltet UART auf I2C bzw. auch SPI
  I2CTCTL |= I2CSSEL1;    // Übertragungsregister mit SMCLK laden
  U0CTL |= I2CEN;
}

void uhrzeit_lesen (void)
{
  I2CSA  =  Adresse_DS32C35;    // 110 1000 -->0x68
  I2CNDAT = 0x01;      // Anzahl der Bytes
  U0CTL |= MST;             // Master mode
  I2CTCTL |= I2CSTT+I2CSTP+I2CTRX;     // Initiate transfer +I2CSTP
  while ((I2CIFG & TXRDYIFG) == 0);  // Wait for transmitter to be ready
  I2CDRB = 0x00;                     // Register Sekunden
  while ((I2CTCTL & I2CSTP) == 0x02);

  I2CTCTL &= ~I2CTRX;            // Umschalten auf Empfänger
  I2CNDAT = 0x01;                // Anzahl der Bytes
  U0CTL |= MST;                  // Master
  I2CTCTL |= I2CSTT + I2CSTP;    // Read, ST, SP (clears MST)
  while ((I2CTCTL & I2CSTP)==  I2CSTP);  // Auf Stop warten
  sekundehex= I2CDRB;

Leider ist es mir nicht gelungen, mit einem MSP430F5435, der ja 
offensichtlich andere Befehle hat, die Uhr auszulesen.
Könnte mir jemand behilflich sein und den obigen Code so umschreiben, 
dass er auf einem MSP430F5435 laufen würde.

Damit nicht jemand denkt, ich würde mir nur alles vorkauen lassen, hier 
meine Initialisierungs-"Idee", aufgebaut aus dem TI-Beispielprogrammen 
(slac166y) --- könnte natürlich schon fehlerhaft sein

void I2C_Init (void)
  {
  P3SEL |= 0x0A;    // Assign I2C pins to module P3.1 (SDA) + P3.3(SCL)
  UCB0CTL1= UCSWRST;    // USCI Software Reset
  UCB0CTL0= UCMST + UCMODE_3 + UCSYNC ;// schaltet UART auf I2C-Master, 
synchron modus
  UCB0CTL1= UCSSEL_2 + UCSWRST;   // SMCLK und SW zurücksetzen
  UCB0BR0 =12;                    // fSCL = SMCLK/12
  UCB0BR1 =0;
  UCB0I2CSA =  Adresse_DS32C35;     //Adresse des Uhren-IS DS32C35
  UCB0CTL1 &= ~UCSWRST;
  UCB0IE|=UCTXIE;
  }
void uhrzeit_lesen (void)
{ ???
Vielen Dank im voraus.

von Clemens L. (c_l)


Lesenswert?

Wolle G. schrieb:
> P3SEL |= 0x0A;    // Assign I2C pins to module P3.1 (SDA) + P3.3(SCL)

Falscher Pin.

> UCB0IE|=UCTXIE;

Willst du Interrupts benutzen? Ich vermute mal nicht.

Ungetestet:
1
void uhrzeit_lesen (void)
2
{
3
  UCB0I2CSA = Adresse_DS32C35;
4
  UCB0CTL1 |= UCTR + UCTXSTT;
5
  while (!(UCB0IFG & UCTXIFG));
6
  UCB0TXBUF = 0x00;
7
  while (!(UCB0IFG & UCTXIFG));
8
  UCB0CTL1 = (UCB0CTL1 & ~UCTR) | UCTXSTT;
9
  UCB0IFG &= ~UCTXIFG;
10
  while (UCB0CTL1 & UCTXSTT);
11
  UCB0CTL1 |= UCTXSTP;
12
  while (!(UCB0IFG & UCRXIFG));
13
  sekundehex = UCB0RXBUF;
14
}

: Bearbeitet durch User
von Wolle G. (wolleg)


Lesenswert?

Clemens L. schrieb:
> Wolle G. schrieb:
>> P3SEL |= 0x0A;    // Assign I2C pins to module P3.1 (SDA) + P3.3(SCL)
>
> Falscher Pin.
>
>> UCB0IE|=UCTXIE;
>
> Willst du Interrupts benutzen? Ich vermute mal nicht.
Das habe ich erst einmal geändert:
neu:
a)   P3SEL |= 0x06;    // Assign I2C pins to module P3.1 (DATA) + P3.2 
(SCL)
b)   UCB0IE|=UCTXIE; --> gelöscht

In der Funktion gibt es noch Probleme:

void uhrzeit_lesen (void)
{
  UCB0I2CSA = Adresse_DS32C35;
  UCB0CTL1 |= UCTR + UCTXSTT;// hier Haltepunkt gesetzt
  //und Fortsetzung mit Einzelschritten
  while (!(UCB0IFG & UCTXIFG));
  UCB0TXBUF = 0x00;
  while (!(UCB0IFG & UCTXIFG)); // ab hier bleibt das Programm hängen
  UCB0CTL1 = (UCB0CTL1 & ~UCTR) | UCTXSTT;
  UCB0IFG &= ~UCTXIFG;
  while (UCB0CTL1 & UCTXSTT);
  UCB0CTL1 |= UCTXSTP;
  while (!(UCB0IFG & UCRXIFG));
  sekundehex = UCB0RXBUF;       // Sekunden-Register auslesen
}
Kannst du erkennen, was die Ursache sein könnte?
Und es wäre für mich schön, wenn du die einzelnen Zeilen mit Kommentaren 
versehen würdest (vorzugsweise in Deutsch, damit ich besser dazu lernen 
kann)

: Bearbeitet durch User
von Wolle G. (wolleg)


Lesenswert?

Kommando zurück.
Ich muss noch einen Verdrahtungsfehler beseitigen.

von Dr Watson (Gast)


Lesenswert?

Wolle G. schrieb:
> Kommando zurück.

Dann kannst du dir auch gleich überlegen ob du die Hinweise
beim Posten eines Beitrages gelesen und verstanden hast.
Das betrifft im Besonderen das Posten von Code den man von
normalem Text unterscheiden sollte.

von Wolle G. (wolleg)


Lesenswert?

Dr Watson schrieb:
> Wolle G. schrieb:
>> Kommando zurück.
>
> Dann kannst du dir auch gleich überlegen ob du ...........

Schade um die Mühe, soviel, zumeist unbrauchbaren Text, zu schreiben.
Welche Hinweise gilt es zu verstehen?

von Wolle G. (wolleg)


Lesenswert?

Ich hoffe, dass die Verdrahtung jetzt stimmt.
Leider hängt sich das Programm immer noch an der gleichen Stelle auf.

von Helmut -. (dc3yc)


Lesenswert?

Wolle G. schrieb:
> Welche Hinweise gilt es zu verstehen?

Wichtige Regeln - erst lesen, dann posten!

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

Formatierung (mehr Informationen...)

1
C-Code
1
AVR-Assembler-Code
1
Code in anderen Sprachen, ASCII-Zeichnungen

von A. S. (Gast)


Lesenswert?

Wolle G. schrieb:
> Schade um die Mühe, soviel, zumeist unbrauchbaren Text, zu schreiben.

Du kannst deinen Code oder Passagen ja nochmal einstellen. Oder einen 
Mod bitten. Aber es ist gut, dass Du das selber so bewertest.

von Wolle G. (wolleg)


Lesenswert?

@Clemens
Vielen Dank für Deine Hilfe.
Es funktioniert mit Deinem Originalprogrammvorschlag.
 "ungetestet" --> jetzt "getestet"
Trotzdem bleibt noch mein Wunsch bestehen, etwas Kommentar einzufügen.
Die Uhr war eigentlich nur als Beispiel gewählt worden, um die 
Grundlagen für andere I2C-Anwendungen zu schaffen.

von Clemens L. (c_l)


Lesenswert?

1
void uhrzeit_lesen (void)
2
{
3
  UCB0I2CSA = Adresse_DS32C35;
4
  while (UCB0CTL1 & UCTXSTOP);             // warte, bis vorherige Transaktion beendet
5
  UCB0CTL1 |= UCTR + UCTXSTT;              // starte Schreib-Transaktion
6
  while (!(UCB0IFG & UCTXIFG));            // warte, bis TXBUF frei
7
  UCB0TXBUF = 0x00;
8
  while (!(UCB0IFG & UCTXIFG));            // warte, bis erstes Byte gesendet wird
9
  UCB0CTL1 = (UCB0CTL1 & ~UCTR) | UCTXSTT; // starte Lese-Transaktion
10
  UCB0IFG &= ~UCTXIFG;                     // TXBUF ist immer noch leer, aber interessiert uns nicht mehr
11
  while (UCB0CTL1 & UCTXSTT);              // warte auf das ACK vom Slave
12
  UCB0CTL1 |= UCTXSTP;                     // sende NACK nach diesem Byte
13
  while (!(UCB0IFG & UCRXIFG));            // warte, bis Byte empfangen
14
  sekundehex = UCB0RXBUF;
15
}

Es wäre auch empfehlenswert, das Handbuch zu lesen (Abschnit 38.3.4.2).

von Wolle G. (wolleg)


Lesenswert?

Clemens L. schrieb:
> Es wäre auch empfehlenswert, das Handbuch zu lesen (Abschnit 38.3.4.2).
Zunächst einen Dank für die Erläuterungen.
Wie nennt sich das Handbuch und wo kann man es herunterladen? Um mit dem 
MSP430F5xx zu arbeiten, hatte ich es mit "slau208d" versucht.

von Clemens L. (c_l)


Lesenswert?

Wolle G. schrieb:
> Wie nennt sich das Handbuch und wo kann man es herunterladen? Um mit dem
> MSP430F5xx zu arbeiten, hatte ich es mit "slau208d" versucht.

SLAU208 ist inzwischen bei Revision Q: 
https://www.ti.com/lit/pdf/slau208
Der Link ist auch auf https://www.ti.com/product/MSP430F5435.

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.