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.

PROBLEM MSP432 I2C with BMP180 pressure sensor



Hi,

I'm currently trying to use the BMP180 sensor with the MSP432P401R launchpad.

Since there are only examples that use addresses of slaves but not addresses of registers, I have a lot of problems to make it work.

My goal is to send the address of the slave ;  I understood that  the read/write bit is automatically set. Then, I would like to send the address of the register I want to read, then the restart (address of the slave followed by the read/write bit) and to finish I would like to read the received value. In fact, I want to do exactly what is described in the datasheet  of the sensor in page 22.

I managed to send the slave address and apparently I have the acknoledgement from the slave. But, when I try to go ahead to send the value of the register, I can't manage to do it. 

Following is my source code. Note that it works for the first part but I think that the mix of the different examples I found on the Internet is bad...

#include "msp.h"
#include <stdint.h>


uint8_t a = 0;
int main(void)
{
    volatile uint32_t i;
    WDTCTL = WDTPW | WDTHOLD;                         // Stop watchdog timer
    P1DIR |= 0xFF; P1OUT |= 0;
    // Configure Pins for I2C
    P1SEL0 |= BIT6 | BIT7;                            // I2C pins

    __enable_interrupt();
    NVIC_ISER0 = 1 << ((INT_EUSCIB0 - 16) & 31); // Enable eUSCIB0 interrupt in NVIC module

    // Configure USCI_B0 for I2C mode
    UCB0CTLW0 |= UCSWRST;                             // put eUSCI_B in reset state
    UCB0CTLW0 |= UCMODE_3 | UCMST | UCSYNC;                    // I2C master mode, SMCLK
    UCB0BRW = 0x0018;                                 // baudrate = SMCLK /24
    UCB0CTLW0 &=~ UCSWRST;                            // clear reset register
    UCB0IE |= UCTXIE0 | UCNACKIE | UCRXIE0;                     // transmit and NACK interrupt enable



    while(1)
    {
    SCB_SCR |= SCB_SCR_SLEEPONEXIT;                   // Don't wake up on exit from ISR
    for (i = 1000; i > 0; i--);                       // Delay between transmissions
    UCB0I2CSA = 0x77;              // configure slave address
    while (UCB0CTLW0 & UCTXSTP);                      // Ensure stop condition got sent
    UCB0CTLW0 |= UCTR | UCTXSTT;                      // I2C TX, start condition

   // __sleep();
    __no_operation();
    }
}

// I2C interrupt service routine
void eUSCIB0IsrHandler(void)
{
    if (UCB0IFG & UCNACKIFG)
    {
    	UCB0IFG &= ~ UCNACKIFG;
        UCB0CTL1 |= UCTXSTT;                  // I2C start condition
    }
    if (UCB0IFG & UCTXIFG0)
    {
    	UCB0IFG &= ~ UCTXIFG0;

            UCB0TXBUF = 0xF6;            // Load TX buffer
            //UCB0I2CSA = 0x77;
            //UCB0CTLW0 |= UCTR | UCTXSTT;                      // I2C TX, start condition
            //UCB0TXBUF = 0xEF;            // Load TX buffer


            UCB0CTLW0 |= UCTXSTP;                     // I2C stop condition
            UCB0IFG &= ~UCTXIFG;                      // Clear USCI_B0 TX int flag
            SCB_SCR &= ~SCB_SCR_SLEEPONEXIT;          // Wake up on exit from ISR

    }
    if (UCB0IFG & UCRXIFG0)
    {
    	a = UCB0RXBUF;
    	__no_operation();
    }
}

Thank you for helping me,

Sylvain

  • Hi Sylvain,

    For I2C communication to register based I2C devices, typically, the communication looks like this.

    For reading the contents of a register
    Start condition -> Slave Address (write) -> (slave ACKs) -> Register Address -> (slave ACKs) -> ReStart condition -> Slave Address (read) -> (slave ACKS) -> Slave sends first byte -> (master ACKs) -> ... -> slave sends last byte -> (master NACKS) -> Stop condition

    For modifying the contents of a register, the procedure is much the same as reading, but instead of the master switching to read mode after the restart, the master stays in write mode. Some I2C devices require the restart when modifying registers, but some do not. If no restart is required, the master can start sending the new data immediately after the register address (without the restart condition).

    If you take a look at your sensor's datasheet, it should describe the I2C communication to interact with the sensor's registers. You can use the TI example code for I2C reads and I2C writes to determine how to put the appropriate data (register address/contents) on the bus and to read in the data.

    Mike

**Attention** This is a public forum