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.

MSP430F5529 communication with accelerometer LSM330DLCH dosn't work

Other Parts Discussed in Thread: MSP430F5529, ENERGIA

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!

  • Have a look at F55xx code examples (SLAC300). Or at the examples in driverlib.
  • Hi, thanks for your reply.

    I just tried the examples from SLAC300 (MSP430F55xx_uscib0_i2c_0X), but it doesnt fix my problem.

    Can you tell me how I have to customize the source code ?

    Do you need more information about the hardware ?

    Thanks!
  • I doesn't fix the problem.

    Can you please tell me how to initialize the i2c ? Do I need a master AND a slave code or only the master code?

    I slowly despair of the problem....
  • Since your microcontroller requests data from the accelerometer, your microcontroller is the master and the accelerometer is the slave, means you have to write the master code.
  • Show the circuit diagram, and your code (to insert code, use the "Insert Code" button 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.

  • Thanks for your help!
    I do not know if we're talking past each other or not.

    I have the problem that when I use the sample code from TI simply nothing happens when I e.g. set the start or stop bit.

    According to User Guide I have to set the UCSWRST bit, but that does not work as described in the Guide.

    What now?
    Thanks!
  • Do you know what a repeated start condition is, and when the LSM303DLH needs it?
  • 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(...);
    	}
    }
  • Hi, thanks for the code.

    I understand how the initialization must be programmed and how the process should be . The code in the last post he remains in the while loop , and nothing else happens ( "wait for byte being sent" ) . Unfortunately I do not know why that is . In addition, the Start or Stop bits are not set.

    I slowly despair of my problem . Does anyone have an idea?


    Thanks!

**Attention** This is a public forum