Hallo, Es ist mein erstes Projekt mit dem MSP430 und ich versuche einen Strom-Sensor über I2C anzusteuern. Die Hardware passt soweit, Pullups etc. sind vorhanden. Leider ist es mein "Einstiegsprojekt" und Softwarekenntnisse sind kaum vorhanden. Aus den Code Examples/User Guide von ti werde ich nicht ganz schlau... Die Kommunikation funktioniert soweit, dass ich nach der Slaveadresse ein ACK erhalte (UCB0I2CSA). Nun weiß ich aber nicht wie ich meinem Slave die Addressen&Contents/Daten vermittle(UCB0TXBUF).... Als Beispiel: Configuration=> Address:00h und Contents:4127h.. Shunt=> Address:01h und Contents:1f40h... Vorausgesetzt mir kann jemand folgen, hätte ich gerne die paar wesentlichen Zeilen, damit ich darauf mein Programm aufbauen kann. Ich bin um jede Hilfe dankbar! Gruß Frank
Frank schrieb: > Aus den Code Examples/User Guide von ti werde ich nicht ganz schlau... Und Du hast Dir auch das Beispiel angesehen, bei dem zwei MSP430 per I2C miteinander verbunden werden, der eine also Master und der andere Slave ist? Welchen MSP430 verwendest Du überhaupt?
Hallo Rufus, ich benutze den msp430g2553. Den Code hab ich natürlich schon angeschaut und eine grobe Vermutung... Ich werde ihn morgen mal hochladen, vlt. kann mir ja jemand sagen ob ich auf dem richtigen Weg bin :) Vielen Dank für deine Antwort.
Dann hast Du Dir auch slac485d angesehen? Darin ist das hier zu finden:
1 | msp430g2xx3_uscib0_i2c_04.c USCI_B0 I2C Master RX single bytes from MSP430 Slave |
2 | msp430g2xx3_uscib0_i2c_05.c USCI_B0 I2C Slave TX single bytes to MSP430 Master |
3 | msp430g2xx3_uscib0_i2c_06.c USCI_B0 I2C Master TX single bytes to MSP430 Slave |
4 | msp430g2xx3_uscib0_i2c_07.c USCI_B0 I2C Slave RX single bytes from MSP430 Master |
5 | msp430g2xx3_uscib0_i2c_08.c USCI_B0 I2C Master TX multiple bytes to MSP430 Slave |
6 | msp430g2xx3_uscib0_i2c_09.c USCI_B0 I2C Slave RX multiple bytes from MSP430 Master |
7 | msp430g2xx3_uscib0_i2c_10.c USCI_B0 I2C Master RX multiple bytes from MSP430 Slave |
8 | msp430g2xx3_uscib0_i2c_11.c USCI_B0 I2C Slave TX multiple bytes to MSP430 Master |
9 | msp430g2xx3_uscib0_i2c_12.c USCI_B0 I2C Master TX/RX multiple bytes from MSP430 Slave |
10 | with a repeated start in between TX and RX operations. |
11 | msp430g2xx3_uscib0_i2c_13.c USCI_B0 I2C Slave RX/TX multiple bytes to MSP430 Master |
:
Bearbeitet durch User
Hey Rufus, Vielen Dank um dein Bemühen!! Die Code Examples kannte ich schon, ohne diese wäre ich komplett aufgeschmissen. Ich hab mal das Original: msp430g2xx3_uscib0_i2c_03.c - USCI_B0 I2C Master Interface to DAC8571, Write versucht meinem Programm anzupassen und ein paar Zeilen verändert. Zum Verständnis erst mal nur eine Adresse und seine Daten... --------------------------------------------------------------------
1 | #include <msp430.h> |
2 | |
3 | |
4 | unsigned int RxByteCtr; |
5 | unsigned int RxWord; |
6 | |
7 | const unsigned char Contents[] = // WERT 4127h |
8 | {
|
9 | 0x41, |
10 | 0x27
|
11 | |
12 | |
13 | };
|
14 | |
15 | int main(void) |
16 | {
|
17 | WDTCTL = WDTPW + WDTHOLD; // Stop Watchdog Timer |
18 | // BIT1^= ALARM
|
19 | P1SEL |= BIT6 + BIT7; // Assign I2C pins to USCI_B0 |
20 | P1SEL2|= BIT6 + BIT7; // Assign I2C pins to USCI_B0 |
21 | UCB0CTL1 |= UCSWRST; // Enable SW reset |
22 | UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode |
23 | UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset |
24 | UCB0BR0 = 12; // fSCL = SMCLK/12 = ~100kHz |
25 | UCB0BR1 = 0; |
26 | UCB0I2CSA = 0x40; // Set slave address |
27 | UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation |
28 | IE2 |= UCB0TXIE; // Enable TX ready interrupt |
29 | UCB0CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition |
30 | UCB0TXBUF = 0x00; // address? |
31 | __bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ interrupts |
32 | }
|
33 | |
34 | // USCI_B0 Data ISR
|
35 | #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
|
36 | #pragma vector = USCIAB0TX_VECTOR
|
37 | __interrupt void USCIAB0TX_ISR(void) |
38 | #elif defined(__GNUC__)
|
39 | void __attribute__ ((interrupt(USCIAB0TX_VECTOR))) USCIAB0TX_ISR (void) |
40 | #else
|
41 | #error Compiler not supported!
|
42 | #endif
|
43 | {
|
44 | static unsigned char ByteCtr=0; |
45 | |
46 | UCB0TXBUF = Contents[ByteCtr++]; // Transmit data byte |
47 | ByteCtr &= 0x01; // Do not exceed table |
48 | }
|
49 | |
50 | --------------------------------------------------------------------------
|
Siehe Bild vom Signal im Anhang. Frage hierzu: 1)UCB0TXBUF = 0x00; wird dieser Bitstream als Adresse erkannt oder muss ich da noch was beachten? 2)Warum wird 0x27 ein zweites mal versendet? Brauch ich noch Stop Conditions oder kann ich mein ByteCtr anpassen... Vielen Dank -- Quelltext bitte in [ c ] [ /c ] -Tags einschließen. -rufus
:
Bearbeitet durch User
> 1)UCB0TXBUF = 0x00; wird dieser Bitstream als Adresse erkannt > oder muss ich da noch was beachten? Das ist nicht die Adresse. Die wird ein paar Zeilen weiter oben in das Register UCB0I2CSA eingetragen. Der Wert 0x00 ist das erste übertragene Datenbyte. Danach werden noch die beiden Bytes in Deiner Tabelle gesendet, 0x41 (65) und 0x27 (39). Merkwürdig ist Dein I2C-Mitschrieb, weil in dem das Adressbyte nicht die Adresse (0x40) enthält.
:
Bearbeitet durch User
Rufus Τ. Firefly schrieb: > Das ist nicht die Adresse. Die wird ein paar Zeilen weiter oben in das > Register UCB0I2CSA eingetragen. ja und mein Problem: > Der Wert 0x00 ist das erste übertragene Datenbyte. genau und diesen möchte ich als meinen Register Pointer Byte nutzen.(Bild) Oder habe ich noch eine andere Möglichkeit außer diese als Datenbyte handzuhaben, sowas wie UCBO... (Entschuldigung, dass ich mich unklar ausgedrückt habe). Und Danke.
Frank schrieb: > und mein Problem: > >> Der Wert 0x00 ist das erste übertragene Datenbyte. > > genau und diesen möchte ich als meinen Register Pointer Byte > nutzen.(Bild) Oder habe ich noch eine andere Möglichkeit außer diese als > Datenbyte handzuhaben, sowas wie UCBO... Das ist dann kein Problem, sondern in Ordnung. Daß das vom I2C-Baustein als "Register Pointer" interpretiert wird, ist egal, von der I2C-Seite her ist das ein stinknormales Datenbyte. Und jetzt klärt sich auch das "Geheimnis" um das Adressbyte 0x40 -- Dein Protokollanalysator wertet das erste Byte des I2C-Rahmens als 8-Bit-Wert aus, d.h. das R/W-Bit ist Bit 0, und damit wird aus 0x40 0x80 (128). Das ist also auch in Ordnung. Was nicht in Ordnung ist, ist, daß Du insgesamt vier Bytes sendest (was zum Resultat hat, daß es auf das vierte Byte ein NAK als Antwort gibt, weil Dein Baustein damit nichts anzufangen weiß. Das zuviel gesendete Byte liegt daran, daß Deine Routine kein Ende erkennt, das Maskieren des Zählers mit 0x1 im Interrupt hilft da nicht. Sieh Dir mal an, wie der Code aus msp430g2xx3_uscib0_i2c_08.c aussieht, hier musst Du Dir insbesondere den Interrupthandler ansehen. Was da gemacht wird, musst Du auch machen. Hier werden vier Nutzbytes versendet, und vor dem Versenden wird ein Pointer auf die zu versendenden Daten gesetzt (das ist PTxData) und ein Bytezähler initialisiert (das ist TXByteCtr). Das interruptgesteuerte Senden wird --anders als in Deinem Code-- nicht durch Beschreiben von UCB0TXBUF mit dem ersten zu sendenden Byte angestoßen, sondern durch das Setzen der Bits UCTR und UCTXSTT in UCB0CTL1. (vorher wird darauf gewartet, daß die vorangehende Übertragung beendet ist, was durch eine 0 im Bit UCTXSTP im Register UCB0CTL1 erkannt wird). Um das ganze auf Deine Anwendung anzupassen, kannst Du das Array TxData um ein Byte verkleinern. Das erste Byte ist der Wert, der als "Register Pointer" dient, das zweite und dritte Deine Daten. Natürlich musst Du auch die I2C-Adresse anpassen; Du willst 0x40 verwenden, im Beispiel wird 0x48 verwendet (und in UCB0I2CSA eingetragen). Viel Erfolg!
Rufus Τ. Firefly schrieb: > Das ist also auch in Ordnung. Super :) Das habe ich gehofft,... Damit hätte ich dann meine "Stütze" die ich gebraucht habe um weiter zu kommen. Ein gaaanz großes Dankeschön für die schnellen Antworten. Super Forum!! in diesem Sinne... Schönes Wochenende ;)
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.