Hallo, vielleicht stehe ich etwas auf dem Schlauch, aber wie genau löse ich bei dem CC430 einen ACK-Signal beim I2C aus? Schreibt man einfach ein UCB0CTL1 &=~ UCTCNACK, oder geschieht das ACK automatisch, nachdem 8 Datenbytes angekommen sind? DANKE!
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.
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.)
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
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.
:
Bearbeitet durch User
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?
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.
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?
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
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.
:
Bearbeitet durch User
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?
Hallo I2C, wenn Du die I2C-Lib verwendest dann hast Du mit den Registern direkt nichts mehr zu tun. mfg klaus
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.
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...
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?
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); |
...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...
Das Datashit des HTU21D zeigt es nicht, aber in Bild 24-3 in Abschnitt 24.3.2 des CC430 User's Guide sieht man es.
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
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?
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
Das zweite Byte, dass ich sende beinhaltet den Befehl: 1110.0011 = 0xE3. Dies ist eine Hold-Master-Sequence.
Nebenfrage: Muss ich für den hold-master-mode den synchronen oder den asynchronen Modus aktivieren? Hat dies einen Einfluss, oder ist das die falsche Fährte?
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?
Hallo Clemens, > Mehr als 8 Bit sollten ohne ACK des Masters nicht gesendet werden. Ist aber so, siehe Datenblatt. http://www.meas-spec.com/downloads/HTU21D.pdf, Seite 12. mfg klaus
Klaus Ra. schrieb: > Ist aber so, siehe Datenblatt. > http://www.meas-spec.com/downloads/HTU21D.pdf, Seite 12. Auf Seite 12 wird "No Hold master" beschrieben, was hier aber nicht verwendet wird. Und nirgendwo sehe ich mehr als 8 Datenbits vor einem ACK.
Clemens L. schrieb: > Klaus Ra. schrieb: >> Ist aber so, siehe Datenblatt. >> http://www.meas-spec.com/downloads/HTU21D.pdf, Seite 12. > > Auf Seite 12 wird "No Hold master" beschrieben, was hier aber nicht > verwendet wird. > Jau, ich habe mich mit dem F3 vertan. mfg klaus
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.