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.

CCS/MSP430FR5969: accessing accelerometer by using i2c in msp430fr5969

Part Number: MSP430FR5969

Tool/software: Code Composer Studio

hiii..this is hariirkishna ..i am having a trouble when i reading the register values in adxl345 accelerometer...this is the code that wrote to access the values..and from the first time it reads correct value but atfer again restarting the program then i getting the 0x00 value as 0..and i write the correct stop condition also...please once check and let me know the problem where in my code....

#include <msp430.h>

volatile unsigned char RXData;

int main(void)
{
WDTCTL = WDTPW | WDTHOLD;

// Configure GPIO
P1OUT &= ~BIT0; // Clear P1.0 output latch
P1DIR |= BIT0; // For LED
P1SEL1 |= BIT6 | BIT7;

PM5CTL0 &= ~LOCKLPM5;
__bis_SR_register( GIE);
UCB0CTLW0 |= UCSWRST; // Software reset enabled
UCB0CTLW0 |= UCMODE_3 | UCMST | UCSYNC; // I2C mode, Master mode, sync
UCB0CTLW1 |= UCASTP_2; // Automatic stop generated
UCB0BRW = 0x0008; // baudrate = SMCLK / 8
UCB0I2CSA = 0x53; // Slave address
UCB0CTL1 &= ~UCSWRST;

while (1)
{
//UCB0CTLW0 &= ~UCTXSTP;
while (UCB0CTL1 & UCTXSTP); // Ensure stop condition got sent
UCB0CTL1 |= UCTXSTT+UCTR;
P1OUT|=BIT0;
UCB0TXBUF=0xA6;//slave address in wite mode
while(UCB0STATW&UCBUSY);
UCB0TXBUF=0x00;//register adddress that i want to read in adxl345
while(UCB0STATW&UCBUSY);
UCB0CTL1 &= ~UCTR; // I2C read operation
UCB0CTL1 |= UCTXSTT;
UCB0TXBUF=0xA7;//slave address in read mode
UCB0IE&=~UCTXIE;
while(UCB0STATW&UCBUSY);
UCB0IE|=UCRXIE;

}
}

#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, USCI_I2C_UCBIT9IFG))
{
case USCI_NONE: break; // Vector 0: No interrupts
case USCI_I2C_UCALIFG: break; // Vector 2: ALIFG
case USCI_I2C_UCNACKIFG: // Vector 4: NACKIFG
UCB0CTL1 |= UCTXSTT;
break;
case USCI_I2C_UCSTTIFG: break; // Vector 6: STTIFG
case USCI_I2C_UCSTPIFG: break; // Vector 8: STPIFG
case USCI_I2C_UCRXIFG3: break; // Vector 10: RXIFG3
case USCI_I2C_UCTXIFG3: break; // Vector 12: TXIFG3
case USCI_I2C_UCRXIFG2: break; // Vector 14: RXIFG2
case USCI_I2C_UCTXIFG2: break; // Vector 16: TXIFG2
case USCI_I2C_UCRXIFG1: break; // Vector 18: RXIFG1
case USCI_I2C_UCTXIFG1: break; // Vector 20: TXIFG1
case USCI_I2C_UCRXIFG0: // Vector 22: RXIFG0
RXData = UCB0RXBUF;//after reading seeting atop condotion
while (UCB0CTL1 & UCTXSTT);
UCB0CTLW0&=~UCTXSTP;
__bic_SR_register_on_exit(LPM0_bits); // Exit LPM0
break;
case USCI_I2C_UCTXIFG0: break; // Vector 24: TXIFG0
case USCI_I2C_UCBCNTIFG: // Vector 26: BCNTIFG
P1OUT ^= BIT0; // Toggle LED on P1.0
break;
case USCI_I2C_UCCLTOIFG: break; // Vector 28: clock low timeout
case USCI_I2C_UCBIT9IFG: break; // Vector 30: 9th bit
default: break;
}
}

#include <msp430.h>

volatile unsigned char RXData;

int main(void)
{
  WDTCTL = WDTPW | WDTHOLD;

  // Configure GPIO
  P1OUT &= ~BIT0;                           // Clear P1.0 output latch
  P1DIR |= BIT0;                            // For LED
  P1SEL1 |= BIT6 | BIT7;

  PM5CTL0 &= ~LOCKLPM5;
  __bis_SR_register( GIE);
  UCB0CTLW0 |= UCSWRST;                     // Software reset enabled
  UCB0CTLW0 |= UCMODE_3 | UCMST | UCSYNC;   // I2C mode, Master mode, sync
  UCB0CTLW1 |= UCASTP_2;                    // Automatic stop generated
  UCB0BRW = 0x0008;                         // baudrate = SMCLK / 8
  UCB0I2CSA = 0x53;                       // Slave address
  UCB0CTL1 &= ~UCSWRST;

  while (1)
  {
      //UCB0CTLW0 &= ~UCTXSTP;
    while (UCB0CTL1 & UCTXSTP);  // Ensure stop condition got sent
      UCB0CTL1 |= UCTXSTT+UCTR;
      P1OUT|=BIT0;
     UCB0TXBUF=0xA6;//slave address in wite mode
     while(UCB0STATW&UCBUSY);
     UCB0TXBUF=0x00;//register adddress that i want to read in adxl345
     while(UCB0STATW&UCBUSY);
     UCB0CTL1 &= ~UCTR; // I2C read operation
     UCB0CTL1 |= UCTXSTT;
     UCB0TXBUF=0xA7;//slave address in read mode
     UCB0IE&=~UCTXIE;
     while(UCB0STATW&UCBUSY);
     UCB0IE|=UCRXIE;

  }
}

#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, USCI_I2C_UCBIT9IFG))
  {
    case USCI_NONE:          break;         // Vector 0: No interrupts
    case USCI_I2C_UCALIFG:   break;         // Vector 2: ALIFG
    case USCI_I2C_UCNACKIFG:                // Vector 4: NACKIFG
      UCB0CTL1 |= UCTXSTT;
      break;
    case USCI_I2C_UCSTTIFG:  break;         // Vector 6: STTIFG
    case USCI_I2C_UCSTPIFG:  break;         // Vector 8: STPIFG
    case USCI_I2C_UCRXIFG3:  break;         // Vector 10: RXIFG3
    case USCI_I2C_UCTXIFG3:  break;         // Vector 12: TXIFG3
    case USCI_I2C_UCRXIFG2:  break;         // Vector 14: RXIFG2
    case USCI_I2C_UCTXIFG2:  break;         // Vector 16: TXIFG2
    case USCI_I2C_UCRXIFG1:  break;         // Vector 18: RXIFG1
    case USCI_I2C_UCTXIFG1:  break;         // Vector 20: TXIFG1
    case USCI_I2C_UCRXIFG0:                 // Vector 22: RXIFG0
      RXData = UCB0RXBUF;//after reading seeting atop condotion
      while (UCB0CTL1 & UCTXSTT);
         UCB0CTLW0&=~UCTXSTP;
      __bic_SR_register_on_exit(LPM0_bits); // Exit LPM0
      break;
    case USCI_I2C_UCTXIFG0:  break;         // Vector 24: TXIFG0
    case USCI_I2C_UCBCNTIFG:                // Vector 26: BCNTIFG
      P1OUT ^= BIT0;                        // Toggle LED on P1.0
      break;
    case USCI_I2C_UCCLTOIFG: break;         // Vector 28: clock low timeout
    case USCI_I2C_UCBIT9IFG: break;         // Vector 30: 9th bit
    default: break;
  }
}
ADXL345 - Accelerometer.pdf

  • Hi hariirkishna,

    Please take attached codes as reference.

    Regards,

    Ling

    #include <msp430.h>
    #include "hal_ADXL345.h"
    
    unsigned char RxData = 0;
    unsigned char TxData = 0;
    unsigned char TxAddr = 0;
    
    void eUSCIB0_Config()
    {
        // Configure pins for I2C
        PORT_I2C_SEL |= BIT_SCL + BIT_SDA;
    
        //configure eUSCI for I2C
        UCB0CTL1 |= UCSWRST;                            //Software reset enabled
        UCB0CTLW0 |= UCMODE_3  + UCMST + UCSYNC + UCTR; //I2C mode, Master mode, sync, transmitter
        UCB0CTLW0 |= UCSSEL_2;                          // SMCLK = 1.04MHz
    
        UCB0BRW = 10;                       // Baudrate = SMLK/10 = 100kHz
    
        UCB0I2CSA  = 0x001D;                //slave address
        UCB0CTL1  &= ~UCSWRST;
    
        UCB0IFG  = 0x0000;
        UCB0CTL1  |= UCSWRST;
    }
    
    // Reads the register at reg_addr, returns the result
    signed char I2C_Read_Register(unsigned char reg_addr)
    {
        UCB0CTLW1 = UCASTP_1;
        UCB0TBCNT = 0x0001;
        UCB0CTL1  &= ~UCSWRST;
        UCB0CTL1 |= UCTXSTT + UCTR;     // Start i2c write operation
        while(!(UCB0IFG & UCTXIFG0));
        UCB0TXBUF = reg_addr;
        while(!(UCB0IFG & UCBCNTIFG));
        UCB0CTL1 &= ~UCTR;              // I2C read operation
        UCB0CTL1 |= UCTXSTT;            // Repeated start
        while(!(UCB0IFG & UCRXIFG0));
        RxData = UCB0RXBUF;
        UCB0CTLW0 |= UCTXSTP;           // Send stop after next RX
        while (!(UCB0IFG & UCSTPIFG));  // Ensure stop condition got sent
        UCB0CTL1  |= UCSWRST;
        return RxData;
    }
    
    //Continuous read data_length bytes and store in the area "read_data"
    void I2C_Read_Continuous(unsigned char reg_addr, signed char* read_data, unsigned char data_length)
    {
        unsigned int i;
    
        UCB0CTLW1 = UCASTP_1;
        UCB0TBCNT = 0x0001;
        UCB0CTL1  &= ~UCSWRST;
        UCB0CTL1 |= UCTXSTT + UCTR;     // Start i2c write operation
    
        while(!(UCB0IFG & UCTXIFG0));
        UCB0TXBUF = reg_addr;
        while(!(UCB0IFG & UCBCNTIFG));
        UCB0CTL1 &= ~UCTR;          //i2c read operation
        UCB0CTL1 |= UCTXSTT;        //repeated start
        while(!(UCB0IFG & UCRXIFG0));
    
        for(i = 0; i < data_length-1; i++)
        {
            while(!(UCB0IFG & UCRXIFG0));
            read_data[i] = UCB0RXBUF;
            if(i == data_length-1)
                UCB0CTL1 |= UCTXSTP;    //send stop after next RX
        }
    
        UCB0CTLW0 |= UCTXSTP;           //send stop after next RX
        while(!(UCB0IFG & UCRXIFG0));
        read_data[i] = UCB0RXBUF;
        while (!(UCB0IFG & UCSTPIFG));  // Ensure stop condition got sent
        UCB0CTL1  |= UCSWRST;
    }
    
    //writes the register at reg_addr with value
    void I2C_Write_Register(unsigned char reg_addr, signed char value)
    {
        UCB0CTLW1 = UCASTP_1;
        UCB0TBCNT = 0x0002;
        UCB0CTL1  &= ~UCSWRST;
        UCB0CTL1 |= UCTXSTT + UCTR;     // Start i2c write operation
        //write the address
        while(!(UCB0IFG & UCTXIFG0));
        UCB0TXBUF = reg_addr;
        //write the data
        while(!(UCB0IFG & UCTXIFG0));
        UCB0TXBUF = value;
        while (!(UCB0IFG & UCBCNTIFG));
        UCB0CTL1 |= UCTXSTP;
        while (!(UCB0IFG & UCSTPIFG));  // Ensure stop condition got sent
        UCB0CTL1  |= UCSWRST;
    }
    
    void ADXL345_Calibration()
    {
        signed int Data_XYZ[3];
        signed int Offset_x = 0;
        signed int Offset_y = 0;
        signed int Offset_z = 0;
        signed char Data_ready = 0;
        unsigned char i;
    
        for(i=0;i<64;i++)
        {
            do
            {
                Data_ready = I2C_Read_Register(0x30);
            }
            while(!(Data_ready & 0x80));
            ADXL345_Update(Data_XYZ);
            Offset_x += Data_XYZ[0];
            Offset_y += Data_XYZ[1];
            Offset_z += Data_XYZ[2];
        }
        Offset_x = -Offset_x >> 8;
        Offset_y = -Offset_y >> 8;
        Offset_z = -((Offset_z >> 6) - 256) >> 2;
    
        I2C_Write_Register(0x1E, (signed char)Offset_x);
        I2C_Write_Register(0x1F, (signed char)Offset_y);
        I2C_Write_Register(0x20, (signed char)Offset_z);
    }
    
    void Init_ADXL345()
    {
        char temp;
    
        eUSCIB0_Config();
    
        /****************************************************************************/
        /* Configure ADXL345 for Typical Usage Scenario                             */
        /****************************************************************************/
    
        temp = I2C_Read_Register(0x00);
        if(temp == 0xE5) // Check device ID
        {
            I2C_Write_Register(0x2C, 0x08); // 25Hz output
            I2C_Write_Register(0x2D, 0x08); // Measure
            I2C_Write_Register(0x2E, 0x00); // Disable interrupt
            I2C_Write_Register(0x2F, 0x00); //
            I2C_Write_Register(0x31, 0x20); // +/- 2g, 10 bit, LSB
        }
    
    //    __delay_cycles(100000);
    
        temp = I2C_Read_Register(0x1e);
        if(temp == 0)    // Check if calibrated ?
        {
            P1OUT |= BIT0; P4OUT |= BIT0;
            ADXL345_Calibration();
            P1OUT &= ~BIT0; P4OUT &= ~BIT0;
        }
    }
    
    void ADXL345_Update(signed int *data_XYZ)
    {
        signed char Data[8];
    
        I2C_Read_Continuous(0x32, Data, 6);
    
        data_XYZ[0] = (((signed int)Data[1] << 8) & 0xFF00) | ((signed int)Data[0] & 0x00FF);
        data_XYZ[1] = (((signed int)Data[3] << 8) & 0xFF00) | ((signed int)Data[2] & 0x00FF);
        data_XYZ[2] = (((signed int)Data[5] << 8) & 0xFF00) | ((signed int)Data[4] & 0x00FF);
    }
    

    2768.hal_ADXL345.h

  • hii... Ling Zhu2
    thank you for the replay ..i observe your code in that you are NOT using the slave write address UCB0TXBUF=0xA6;//slave address in wite mode and slave address UCB0TXBUF=0xA7; in read mode ..why?? and in adxl345 datasheet timing diagrams uses this addresses...once see the datasheet .because of that reason i used in my above program...so it is required are not really i don't no..if NO then please explain the reason....thank you
  • hii..Ling Zhu..
    i run your code only for read operation it is no working...it is struck at while(!(UCB0IFG&UCRXIFG0));...
  • hi ..Ling Zhu.
    thank you for the replay..what i am saying is for your code you used 0x1D as slave address ok..but for and write and read the addresses 0x3A and 0x3B are not used in your program see your code..

    signed char I2C_Read_Register(unsigned char reg_addr)
    {
    UCB0CTLW1 = UCASTP_1;
    UCB0TBCNT = 0x0001;
    UCB0CTL1 &= ~UCSWRST;
    UCB0CTL1 |= UCTXSTT + UCTR; // Start i2c write operation
    while(!(UCB0IFG & UCTXIFG0));
    UCB0TXBUF = reg_addr;
    while(!(UCB0IFG & UCBCNTIFG));
    UCB0CTL1 &= ~UCTR; // I2C read operation
    UCB0CTL1 |= UCTXSTT; // Repeated start
    while(!(UCB0IFG & UCRXIFG0));
    RxData = UCB0RXBUF;
    UCB0CTLW0 |= UCTXSTP; // Send stop after next RX
    while (!(UCB0IFG & UCSTPIFG)); // Ensure stop condition got sent
    UCB0CTL1 |= UCSWRST;
    return RxData;
    }
    ..this is your code and why you are not used 0X3A and 0X3b for above code..like UCB0TXBUF=0X3A AND UCB0TXBUF=0x3b...
  • Hi hariirkishna,

    Slave address(include R/W bit) will be sent automatically. You just need to put your user data into UCB0TXBUF.

    Regards,
    Ling
  • hi Ling Zhu..
    Thank you for your suggestions..finally i got the correct value by running the below code...but i am getting some problem again. when i run the program first time it gives correct value. but after again i run this program in while loop like as below. the program will struct on either this while(!(UCB0IFG&UCTXIFG0)); while loop or this while(!(UCB0IFG&UCRXIFG0)); while loop..then i want to execute this read function in several times and get the same value....please once check the errors and give me the correct read function.....and i check the program by clearing and enabling the TXIFG0 AND RXIFG0 flags manually but it will not work for me...


    #include <msp430.h>
    char RXData;
    volatile unsigned char reg_value;
    volatile unsigned char value;
    void clock_init();
    void Init_I2c();
    void write_byte(char reg_address,char data);
    char read_byte(char reg_addr);
    int main(void)
    {

    WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer
    PM5CTL0 &= ~LOCKLPM5;
    P1SEL1 |= BIT6 | BIT7; // I2C pins
    __bis_SR_register(GIE);
    clock_init();
    Init_I2c();

    while(1)
    {
    reg_value=read_byte(0x2C);//reading REG_ADD value
    if(reg_value!=0x00)
    value=reg_value;
    }
    }
    void Init_I2c()
    {
    UCB0CTLW0 |= UCSWRST;
    UCB0CTLW0 |= UCMODE_3 | UCMST | UCSYNC|UCTR;
    UCB0CTLW0|=UCSSEL__SMCLK;
    UCB0BRW = 10;
    UCB0I2CSA = 0x53;
    UCB0CTLW0 &= ~UCSWRST;
    UCB0IFG=0X0000;
    UCB0CTLW0 |= UCSWRST;
    }
    char read_byte(char reg_addr)
    {
    UCB0CTLW1 |= UCASTP_1;
    UCB0CTLW0 &= ~UCSWRST;
    UCB0CTL1 |= UCTR|UCTXSTT;
    while(!(UCB0IFG&UCTXIFG0));
    UCB0TXBUF=reg_addr;
    UCB0CTL1 &= ~UCTR;
    UCB0CTL1 |= UCTXSTT;
    while(!(UCB0IFG&UCRXIFG0));
    RXData = UCB0RXBUF;
    UCB0CTL1 |= UCTXSTP;
    UCB0CTLW0 |= UCSWRST;
    return RXData;
    }
    void clock_init()
    {
    CSCTL0_H = CSKEY >> 8; // Unlock CS registers
    CSCTL1 = DCOFSEL_0; // Set DCO to 1MHz
    CSCTL2 = SELA__LFXTCLK | SELS__DCOCLK | SELM__DCOCLK;
    CSCTL3 = DIVA__1 | DIVS__1 | DIVM__1; // set all dividers
    CSCTL0_H = 0;
    }
  • hi Ling Zhu.
    thank you for the replay..
    in the above code i am not using the UCB0TBCNT=0X0001.. because i don't want to count the values so that i am not using the that flag...it is not necessary for the reading and writing the data i think..it is only for the counting purpose only...and my question is i am getting correct value at first time then i want to run again the program it is struck at either this loop while(!(UCB0IFG&UCRXIFG0)); or this loop while(!(UCB0IFG&UCTXIFG0)); ..is this UCB0TBCNT Is necessary to read and write???
  • Hi harikrishna,

    For more details about how to use eUSCI in IIC mode, please refer to User's Guide and code examples.

     

      

    Regards,

    Ling

**Attention** This is a public forum