This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Hi,
my name is Tobias and i'm a Student.
In a project with the MSP430F5529 the data is to be received via I2C from a sensor (accelerometer).
Unfortunately, I can not build Kommuniktion and the examples on the TI website also does not help me.
Can someone tell me how I have to begin and how it works? The principle of the transmission ( start , slave address , ...... , Stop ) I understood , but I do not know how the source code should look like .
Thanks!
Show the circuit diagram, and your code (to insert code, use the "Insert Code" button), and tell us what particular I²C transfer you want to do.
Thanks for your reply!!
I'm using the code from TI which you can find in the file "MSP430F55xx_uscib0_i2c_04.c", which you can find on the TI-Website. I have the code attached below. What do I need to adjust ? Can I use this code at all?
At the moment I'm using the MSP430F5529 Launchpad and connectet a circuit board from Sparkfun ( LSM303DLH, with an acceleration sensor) on P4.1 and P4.2 (SDA and SCL). So there is no circuit diagram.
#include <msp430.h> unsigned char RXData; unsigned char RXCompare; int main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop WDT P1OUT &= ~0x01; // P1.0 = 0 P1DIR |= 0x01; // P1.0 output P4SEL |= 0x03; // Assign I2C pins to USCI_B0 --> Modified from P3 to P4 is that correct? UCB0CTL1 |= UCSWRST; // Enable SW reset UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK UCB0BR0 = 12; // fSCL = SMCLK/12 = ~100kHz UCB0BR1 = 0; UCB0I2CSA = 0x32; // Slave Address --> 32 or 33 ? Write or Read? UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation UCB0IE |= UCRXIE; // Enable RX interrupt RXCompare = 0x0; // Used to check incoming data while (1) { while (UCB0CTL1 & UCTXSTP); // Ensure stop condition got sent UCB0CTL1 |= UCTXSTT; // I2C start condition while(UCB0CTL1 & UCTXSTT); // Start condition sent? UCB0CTL1 |= UCTXSTP; // I2C stop condition __bis_SR_register(LPM0_bits + GIE); // Enter LPM0, enable interrupts __no_operation(); // For debugger if (RXData != RXCompare) // Trap CPU if wrong { P1OUT |= 0x01; // P1.0 = 1 while(1); } RXCompare++; // Increment correct RX value } } // USCI_B0 Data ISR #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) #pragma vector = USCI_B0_VECTOR __interrupt void USCI_B0_ISR(void) #elif defined(__GNUC__) void __attribute__ ((interrupt(USCI_B0_VECTOR))) USCI_B0_ISR (void) #else #error Compiler not supported! #endif { switch(__even_in_range(UCB0IV,12)) { case 0: break; // Vector 0: No interrupts case 2: break; // Vector 2: ALIFG case 4: break; // Vector 4: NACKIFG case 6: break; // Vector 6: STTIFG case 8: break; // Vector 8: STPIFG case 10: // Vector 10: RXIFG RXData = UCB0RXBUF; // Get RX data __bic_SR_register_on_exit(LPM0_bits); // Exit active CPU break; case 12: break; // Vector 12: TXIFG default: break; } }
Both the LaunchPad and the breakout board have schematics. You have no circuit diagram just because you didn't bother to create one.
You could at least describe the connections you've made. (Two connections, as described, are not enough.)
That example code reads a single byte from the I²C slave. However, to read a register, you need to write the register address, create a repeated start condition, and then read a byte. You have to combine multiple example programs for that.
"P4SEL |= 0x03;" enables P4.0 and P4.1. However, the second I²C module is connected to P4.1 and P4.2, and that's UCB1, not UCB0.
As shown in the User's Guide, the I2CSA register has only seven bits, for the seven bits of the slave address. The read/write bit gets set depending on the state of the UCTR bit in the CTL1 register.
Consider using driverlib, then you don't have to write so much code by hand. (And no, driverlib doesn't have examples with a repeated start condition either.)
Or try to use the Arduino example code with Energia.
The following code is based on Sparkfun's Arduino code, and completely untested. Please note that it does not use interrupts, and has no error checking (NACKs, timeouts).
#include <msp430.h> #include <stdint.h> #define LSM303_MAG 0x1e #define LSM303_ACC 0x18 static void LSM303_write(uint8_t data, uint8_t address) { while (UCB1CTL1 & UCTXSTP) // wait for last stop ; if (address >= 0x20) // slave address UCB1I2CSA = LSM303_ACC; else UCB1I2CSA = LSM303_MAG; UCB1CTL1 |= UCTR | UCTXSTT; // transmit mode, start bit while (!(UCB1IFG & UCTXIFG)) // wait for transmit buffer ; UCB1TXBUF = address; while (!(UCB1IFG & UCTXIFG)) // wait for byte being sent ; UCB1TXBUF = data; while (!(UCB1IFG & UCTXIFG)) // wait for byte being sent ; UCB1CTL1 |= UCTXSTP; // stop bit } static uint8_t LSM303_read(uint8_t address) { while (UCB1CTL1 & UCTXSTP) // wait for last stop ; if (address >= 0x20) // slave address UCB1I2CSA = LSM303_ACC; else UCB1I2CSA = LSM303_MAG; UCB1CTL1 |= UCTR | UCTXSTT; // transmit mode, start bit while (!(UCB1IFG & UCTXIFG)) // wait for transmit buffer ; UCB1TXBUF = address; while (!(UCB1IFG & UCTXIFG)) // wait for byte being sent ; UCB1CTL1 &= ~UCTR; // receive mode UCB1CTL1 |= UCTXSTT; // start bit while ((UCB1CTL1 & UCTXSTT)) // wait for start being sent ; UCB1CTL1 |= UCTXSTP; // stop bit while (!(UCB1IFG & UCRXIFG)) // wait for byte received ; return UCB1RXBUF; } int main() { WDTCTL = WDTPW | WDTHOLD; P4SEL |= BIT1 | BIT2; // P4.1, P4.2 UCB1CTL1 = UCSWRST; // reset, clear all other bits UCB1CTL0 = UCMST | UCMODE_3 | UCSYNC; // master, I2C, synchronous UCB1CTL1 = UCSSEL_2 | UCSWRST; // clock soure: SMCLK UCB1BRW = 12; // SMCLK/12 UCB1CTL1 &= ~UCSWRST; LSM303_write(...); while (1) { LSM303_read(...); } }
**Attention** This is a public forum