I2C stehe auf dem Schlauch (CC430)

#4090336
Lesenswert?

Hallo I2C,
ein wenig Code würde Dein Problem hier besser beschreiben.

Ich habe mir mal meinen Code für einen MSP430F2013 angesehen. Danach 
wird nach jedem empfangen Byte ein Ack gesendet und zum Schluss ein 
NAck.

#####################################
 case 6: // Receive Data Ack/Nack bit
    if (WriteMode)
      USICTL0 &= ~USIOE;         // SDA = input
    else
    {
      USICTL0 |= USIOE;          // SDA = output
      OutCode[pntOutCode++] = USISRL; // Lesen des empfangenen Bytes
      if (LoopsToRead > 0)
      {
        USISRL = 0x00;           // Send Ack,
        USICNT |= 0x01;          // Bit counter = 1, send Ack bit
        I2C_State = 8;           // Go to next state
        break;
      }
      USISRL = 0xFF;             // Send NAck, hier generell senden,
    }
    USICNT |= 0x01;              // Bit counter = 1, receive (N)Ack bit
    I2C_State = 8;               // Go to next state: check (N)Ack
    break;
#####################################

Dieser Code ist zwar den rudimentären Samples von TI entnommen, wurde 
von mir aber für Rx und Tx zusammengefasst und etwas ergänzt. Die 
damalige I2C-Lib bekam ich nicht zum Laufen. Heute sieht das aber 
bestimmt anders aus. Versuch mal die Lib einzusetzen.

mfg klaus.
#4090419
Lesenswert?

USI (F2xx) ist nicht das gleiche wie USCI (CC430).

Siehe Abschnitt 24.3.4.1.2 und Abbildung 4-10 des User's Guide.
Ein ACK wird automatisch gesendet, wenn im Eingabepuffer Platz ist, weil 
deine Software das vorherige Byte aus UCBxRXBUF gelesen hat.
(Und mehr als ein Byte wird nicht gepuffert.)
#4090479
Lesenswert?

Hallo Clemens,
ich bin zwar nicht der Ersteller des Threads aber ich werde mich 
demnächst auch mit einem cc430x513x befassen. Ich weiss noch welchen 
Aufwand (Try/Error) ich 2007/2008 betreiben musste um aus den 
TI-Samples, die sehr rudimentär gehalten waren und noch sind, etwas 
Lauffähiges wie für einen TMP102, bzw. dem DS1631, hinzubekommen.

In den TI-Samples wird zwar beschrieben wie man ein Byte zum Slave 
sendet, aber auch nur das. Und im anderen Sample, wie man ein Byte 
empfängt. Ja, und dann bastele mal dies zusammen zu einem Code und das 
noch für 16Bit-Anworten des Slave. Für einen damaligen Anfänger etwas 
Anspruchsvolles.

Ich habe mich in den letzten Tagen wieder wegen dem cc430x513x durchs 
Internet gewühlt um ein paar Samples zufinden. Vielleicht suche ich an 
den falschen Stellen.

Mir ging es für das erste darum:
-Über I2C bei einem TMP102 (12 Bit Temperatursensor) den Messvorgang
 einleiten
-Empfang der 2 Byte des Sensors

Beim MSP430F2013 läuft mein Code seit Jahren einwandfrei. Der 
Sample-Code für den cc430x513x sieht etwas anders aus.

Kannst Du mir Quellen nennen die mir weiterhelfen könnten?
mfg klaus
#4090791
Lesenswert?

Normalerweise empfehle ich driverlib:
http://www.ti.com/tool/mspdriverlib
entweder direkt, oder den Quellcode als Vorlage nehmen.

Die CC430-Familie wird zwar von driverlib nicht direkt unterstützt, aber
das USCI-Modul ist das gleiche wie in der F5xx-Familie.
Siehe examples/MSP430F5xx_5xx/usci_b_i2c/ und
driverlib/MSP430F5xx_5xx/usci_b_i2c.*.

Für den TMP102 muss man ein Byte schreiben und dann sofort zwei Bytes
lesen. Das wären USCI_B_I2C_masterMultiByteSendStart() (nicht
…SingleByte(), damit kein STOP gesendet wird), und wenn das erledigt
ist, USCI_B_I2C_masterMultiByteReceiveStart(), und dann im Interrupt
USCI_B_I2C_masterMultiByteReceiveNext() oder
USCI_B_I2C_masterMultiByteReceiveFinish().

Und wenn das nicht weiter hilft, musst du dein Englisch ausgraben und
auf http://e2e.ti.com/support/microcontrollers/msp430/ nachfragen.
Gast #4090800
Lesenswert?

Nun,

Eine weitere Frage zur Adressinitialisierung:
Ich möchte den HTU21D Feuchte-Sensor ansteuern.

Dieser hat laut Datenblatt die 7Bit-Adresse 0x40

Für einen Schreib-Vorgang wird er mit 0x80 und für einen Lesevorgang mit 
0x81 angesprochen, da das Direction-Bit am Ende mit angefügt wird.

Der CC430 möchte die Slave Adresse wissen. Schreibe ich in das 
I2CSAx-Register nun 0x80, 0x81 oder 0x40 hinein?
#4090879
Lesenswert?

Das hättest du einfach im User's Guide, Abschnitt 24.4.9, nachlesen
können:
> The I2CSAx bits contain the slave address of the external device to be
> addressed by the USCI_Bx module. It is only used in master mode.
> The address is right justified. In 7-bit slave addressing mode, bit 6
> is the MSB and bits 9-7 are ignored.
Gast #4090954
Lesenswert?

danke dir, also schreibe ich die 0x40 in das Register.

Allerdings entstehen aus der 7-Bit Adressierung bzw. aus dem Verfahren 
des CC430 für mich noch einige weitere Fragen:



Im Datenblatt des Sensors HTU21D steht in der Beispielsequenz, dass zum 
Ansprechen folgendes nötig ist:

[S][I2C Adresse + Write] ---ACK--- [COMMAND] ---ACK--- [S][I2C ADRESSE + 
READ]

d.h. ich muss eine Startsequenz, dann die Adresse mit einem 
Schreibbefehl abgeben, auf die Bestätigung warten, sodann den 
eigentlichen Messbefehl abgeben, erneut auf Bestätigung warten, dann 
einen erneuten Startvorgang initiieren und den Sensor nochmal mit einem 
Lesevorgang ansprechen und nach dem ACK sodann warten, bis der Sensor 
fertig ist.

Übersetzt muss ich also folgende Signale auf die Datenleitung legen:

[S][0x80]---ACK---[0xE5]---ACK---[S][0x81]---ACK...wait

Die Datenleitung erhält also die Bytes 0x80 / 0x81 obwohl die Adresse 
eigentlich 0x40 ist.


Nun frage ich mich:
Wozu das ganze? der CC430 hat das I2CSAx-Register, welches explizit die 
7-Bit Adresse des Slave Device aufnehmen kann.
Wozu muss bzw. kann ich meinem Controller (Master) mitteilen, welche 
Adresse mein Sensor besitzt?
Würde es nicht zum Ansprechen des Sensors genügen, einfach, die 0x80 in 
den UCB0TXBUF zu schreiben?
was macht der CC430 Controller mit der 0x40, die ich in obigem Register 
mit angeben kann?
#4090973
Lesenswert?

Clemens L. schrieb:
> Normalerweise empfehle ich driverlib:
> http://www.ti.com/tool/mspdriverlib
> entweder direkt, oder den Quellcode als Vorlage nehmen.
>
> Die CC430-Familie wird zwar von driverlib nicht direkt unterstützt, aber
> das USCI-Modul ist das gleiche wie in der F5xx-Familie.
> Siehe examples/MSP430F5xx_5xx/usci_b_i2c/ und
> driverlib/MSP430F5xx_5xx/usci_b_i2c.*.

Das Beispiel driverlib/MSP430F5xx_5xx/usci_b_i2c.* hatte ich mir gestern 
schon mal angeschaut ...
>
> Für den TMP102 muss man ein Byte schreiben und dann sofort zwei Bytes
> lesen. Das wären USCI_B_I2C_masterMultiByteSendStart() (nicht
> …SingleByte(), damit kein STOP gesendet wird), und wenn das erledigt
> ist, USCI_B_I2C_masterMultiByteReceiveStart(), und dann im Interrupt
> USCI_B_I2C_masterMultiByteReceiveNext() oder
> USCI_B_I2C_masterMultiByteReceiveFinish().
>
... aber erst jetzt bin ich mir sicher es verstanden zu haben. Die LIB 
vereinfacht in der Tat den Umgang mit I2C.

> Und wenn das nicht weiter hilft, musst du dein Englisch ausgraben und
> auf http://e2e.ti.com/support/microcontrollers/msp430/ nachfragen.

Ja, das wird sich manchmal nicht vermeiden lassen.
Nochmals Danke, Du hast mir sehr geholfen.

mfg klaus
#4091014
Lesenswert?

I2C schrieb:
> Wozu muss bzw. kann ich meinem Controller (Master) mitteilen, welche
> Adresse mein Sensor besitzt?

Der Controller sendet nach dem START automatisch die Slave-Adresse.

> was macht der CC430 Controller mit der 0x40, die ich in obigem Register
> mit angeben kann?

Er sendet es auf dem Bus, und hängt das R/W-Bit an.
Gast #4091041
Lesenswert?

Danke dir Clemens,

d.h. nach dem [Start] wird das erste Byte bereits automatisch gesendet, 
wobei die 7 Bit-Adresse automatisch um 1 Bit verlängert wird, so dass 
ein ganzes Byte entsteht?

Frage:
Dieser Automatismus funktioniert aber nur bei dem ersten Byte, und es 
wird immer nur die "0" zum Schreiben ergänzt, richtig?

Alle weiteren Bytes  Befehle  oder Auslesewünsche muss ich nach dem 
erhalten des ersten ACK manuell in den UCB0TXBUF schreiben?
#4091067
Lesenswert?

Im I²C-Protokoll muss das erste Byte immer die Slave-Adresse sein,
deshalb kann der Controller sie automatisch senden. Die anderen Bytes
hängen von der Anwendung ab.

Der ergänzte Bit ist 0 beim Schreiben und 1 beim Lesen. (Auch bei einer
Lese-Transaktion sendet der Master die Slave-Adresse.)

Die oben erwähnten Links gelten auch für dich.
Gast #4091104
Lesenswert?

ok, hab I2C eben noch nie benutzt und muss nun erstmal die Grundlagen 
verstehen.

Das R/W Bit wird also durch das UCTR bestimmt. Da muss man auch erst mal 
drauf kommen.
Eine Suche nach dem "R/W bit" im Family Guide führt zumindest nicht zu 
dieser Erkenntnis...
Gast #4092190
Lesenswert?

Das hier habe ich aus dem Family Guide:

> USCI module checks if the bus is available,
> generates the START condition,
> and transmits the slave address.
> The UCTXIFG bit is set when the START
> condition is generated and the first
> data to be transmitted can be written
> into UCBxTXBUF

Die Startbedingung (UCTXSTT = high) wird beim Empfangen eines ACK 
gelöscht.

Der Family Guide weist darauf hin, dass das UCTXIFG ein rw-1 Bit ist, 
d.h. es ist immer high solange der TX-Buffer leer ist.

Frage: Geht der Controller dann bei gesetztem TXIE in die ISR?

Wie verhindere ich denn, dass dort kein permanentes Trap durch Sprünge 
in die ISR stattfindet?
#4092231
Lesenswert?

I2C schrieb:
> Der Family Guide weist darauf hin, dass das UCTXIFG ein rw-1 Bit ist,
> d.h. es ist immer high solange der TX-Buffer leer ist.
>
> Frage: Geht der Controller dann bei gesetztem TXIE in die ISR?
>
> Wie verhindere ich denn, dass dort kein permanentes Trap durch Sprünge
> in die ISR stattfindet?

Indem du etwas in the TX-Buffer schreibst, oder STOP sendest.

Beim STOP musst du das Interrupt-Flag manuell zurücksetzen.
Aus driverlib:
1
    //Send stop condition.
2
    HWREG8(baseAddress + OFS_UCBxCTL1) |= UCTXSTP;
3

4
    //Clear transmit interrupt flag before enabling interrupt again
5
    HWREG8(baseAddress + OFS_UCBxIFG) &= ~(UCTXIFG);
Gast #4094055
Lesenswert?

...so, so langsam mache Ich Fortschritte:

Eine kurze Frage:

Ist es richtig, dass das ACK ein "low" auf der Datenleitung erzeugt?


Ich habe hier ozisllografiert und das was ich auf den BUS lege macht nur 
Sinn, wenn ACK = low bedeutet, und zwar für einen Takt lang...
Gast #4094352
Lesenswert?

I2C schrieb:
> d.h. nach dem [Start] wird das erste Byte bereits automatisch gesendet,
> wobei die 7 Bit-Adresse automatisch um 1 Bit verlängert wird, so dass
> ein ganzes Byte entsteht?

Nein.

Das erste, automatisch gesendete Byte wird aus (7-Bit)-I2C Adresse und 
R/W-Bit zusammengesetzt. Da wird keine Adresse verlängert.

In der I2C-Spezifikation findest du das alles beschrieben (Fig.9+10)
http://www.nxp.com/documents/user_manual/UM10204.pdf
Gast #4102585
Lesenswert?

so, die Sendesequenz hin schaffe ich, aber mit der Antwort stimmt 
irgendetwas nicht:

Senden tue ich:

[S][1000.0000]{0-ACK}[1110.0011]{0-ACK}[S][1000.0001]{0-ACK}


In eckigen Klammern die Sequenz vom CC430 ausgehend und in geschweiften 
Klammern die Acknowledges vom HTU21D


Der Code triggert eine Temperaturmessung, die nach ca. 42ms 
abgeschlossen sein soll.
Die Datenleitung ist also die ganze Zeit high und der Takt auf low.

Nach den 42ms sehe ich dann ein Signal auf dem Bus, und zwar geht die 
Taktleitung wieder auf low sowie die Clock fängt an zu laufen, dann sehe 
ich folgendes Signal:

1100.0100.1100.100

Danach bleibt Takt und Datenleitung auf low.

In der Sequenz erkenne ich aufgrund der komischen Zahl an Bits (15 
Stück) keine Acknowledges und kann es daher nicht übersetzen...
Ich hätte eigentlich 27 Bits erwartet...

Woran mag das liegen?
#4102717
Lesenswert?

I2C schrieb:
> so, die Sendesequenz hin schaffe ich, aber mit der Antwort stimmt
> irgendetwas nicht:
>
> Senden tue ich:
>
> [S][1000.0000]{0-ACK}[1110.0011]{0-ACK}[S][1000.0001]{0-ACK}
>

So wie ich das sehe hast Du den Mode "No Hold Master communication 
sequence" gewählt. In dieser Tabelle sehe ich den Verlauf etwas anders.

[S][1000.0000]{0-ACK}[1110.0011]{0-ACK}
[S][1000.0001]{0-NACK}
[S][1000.0001]{0-ACK}

mfg klaus
#4102954
Lesenswert?

I2C schrieb:
> Nach den 42ms sehe ich dann ein Signal auf dem Bus, und zwar geht die
> Taktleitung wieder auf low sowie die Clock fängt an zu laufen, dann sehe
> ich folgendes Signal:
>
> 1100.0100.1100.100

Mehr als 8 Bit sollten ohne ACK des Masters nicht gesendet werden.
Kannst du uns mal zeigen, was das Oszilloskop dazu sagt?

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