Wie I2C von MSP430F1611 auf MSP430F5435 umprogrammieren

OP #6282067
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.
#6282832
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
}
OP #6283639
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)
OP #6284436
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.
#6287690
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).

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