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.

ADXL345 Accelerometer interfacing to Msp430g2553 (Ready reference code)

Other Parts Discussed in Thread: MSP430G2553, MSP430FR2311

As i have seen many friends try to get help regarding interfacing ADXL345 with MSP430G2553 here is the ready reference samplecode for the same ......

 

//  Interfacing ADXL345 accelerometer with MSP430G2553 with I2C communication

//

//                                /|\  /|\

//               ADXL345          10k  10k     MSP430G2xx3

//                slave            |    |        master

//             -----------------   |    |  -----------------

//            |                          SDA|<-|---+->|P3.1/UCB0SDA  XIN|-

//            |                 |  |      |                 |

//            |                        |  |      |             XOUT|-

//            |             SCL|<-+----->|P3.2/UCB0SCL     |

//            |                 |         |                 |

//

//  Attribute: Code modified from I2C multiple byte TX/RX Master example by

//  D. Dang

//  Texas Instruments Inc.

//

//  Code Made By :

//  Prof. Ravi Butani

//  Marwadi Education Foundation, Rajkot GUJARAT-INDIA

//  ravi.butani@marwadieducation.edu.in

//

//  Code Released under Creative Commons By-SA  license

//  Visit http://creativecommons.org/licenses/by-sa/3.0/deed.en_US  to know more about license

//  Built with CCS Version 5.1.0

//******************************************************************************

#include <msp430.h>

 

#define NUM_BYTES_TX 2                         // How many bytes?

#define NUM_BYTES_RX 6

#define ADXL_345     0x53

int RXByteCtr, RPT_Flag = 0,x1,y1,z1;       // enables repeated start when 1

volatile unsigned char RxBuffer[6];         // Allocate 6 byte of RAM

unsigned char *PRxData;                     // Pointer to RX data

unsigned char TXByteCtr, RX = 0;

unsigned char MSData[3];

 

void Setup_TX(unsigned char);

void Setup_RX(unsigned char);

void Transmit(unsigned char,unsigned char);

void Receive(void);

 

int main(void)

{

  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT

  P1SEL |= BIT6 + BIT7;                     // Assign I2C pins to USCI_B0

  P1SEL2|= BIT6 + BIT7;                     // Assign I2C pins to USCI_B0

  P1DIR |= BIT0;

 

  // Init sequence for ADXL345

  //Transmit process

    Setup_TX(ADXL_345);

    RPT_Flag = 1;

    Transmit(0x2D,0x00);

    while (UCB0CTL1 & UCTXSTP);             // Ensure stop condition got sent

 

   //Transmit process

     Setup_TX(ADXL_345);

     RPT_Flag = 1;

     Transmit(0x2D,0x10);

     while (UCB0CTL1 & UCTXSTP);             // Ensure stop condition got sent

 

    //Transmit process

      Setup_TX(ADXL_345);

      RPT_Flag = 1;

      Transmit(0x2D,0x08);

      while (UCB0CTL1 & UCTXSTP);             // Ensure stop condition got sent

 

      // Un-comment next block to change range of ADXL345

    /*

       Setup_TX(ADXL_345);

       RPT_Flag = 1;

       Transmit(0x31,0x01);                            // Range Select at add 0x31 write 0x00 for 2g(default)/ 0x01 for 4g/ 0x02 for 8g/ 0x03 for 16g

        while (UCB0CTL1 & UCTXSTP);         // Ensure stop condition got sent

    */

 

  while(1){

 

         //Transmit process

          Setup_TX(ADXL_345);

          RPT_Flag = 1;

          Transmit(0x32,0xFE);                                   // Request Data from ADXL345 in 2g Range 10Bit resolution

          while (UCB0CTL1 & UCTXSTP);             // Ensure stop condition got sent

 

 

  //Receive process

  Setup_RX(ADXL_345);

  Receive();

  while (UCB0CTL1 & UCTXSTP);             // Ensure stop condition got sent

 

  x1 = (((int)RxBuffer[1]) << 8) | RxBuffer[0];

  y1 = (((int)RxBuffer[3]) << 8) | RxBuffer[2];

  z1 = (((int)RxBuffer[5]) << 8) | RxBuffer[4];

 

  // now You have XYZ axis reading in x1,x2,x3 variable....Bingo... you can play with it as you like....

  // Below if sense x and y angle and Red led is on if its more then 45 or less then -45...

  // you can put your own condition here...

   if ((x1 > 128) || (y1 > 128) || (x1 < -128) || (y1 < -128))

         {

                P1OUT |= BIT0; // red led on

         }

 

         else

         {

                P1OUT &= ~BIT0; // red led off

         }

  __delay_cycles(10000);  // sample rate ~100 samples/sec

                                            // you can change by changing delay

  }

}

 

//-------------------------------------------------------------------------------

// The USCI_B0 data ISR is used to move received data from the I2C slave

// to the MSP430 memory. It is structured such that it can be used to receive

// any 2+ number of bytes by pre-loading RXByteCtr with the byte count.

//-------------------------------------------------------------------------------

#pragma vector = USCIAB0TX_VECTOR

__interrupt void USCIAB0TX_ISR(void)

{

  if(RX == 1){                              // Master Recieve?

  RXByteCtr--;                              // Decrement RX byte counter

  if (RXByteCtr)

  {

    *PRxData++ = UCB0RXBUF;                 // Move RX data to address PRxData

  }

  else

  {

    if(RPT_Flag == 0)

        UCB0CTL1 |= UCTXSTP;                // No Repeated Start: stop condition

      if(RPT_Flag == 1){                    // if Repeated Start: do nothing

        RPT_Flag = 0;

      }

    *PRxData = UCB0RXBUF;                   // Move final RX data to PRxData

    __bic_SR_register_on_exit(CPUOFF);      // Exit LPM0

  }}

 

  else{                                     // Master Transmit

      if (TXByteCtr)                        // Check TX byte counter

  {

    UCB0TXBUF = MSData[TXByteCtr];          // Load TX buffer

    TXByteCtr--;                            // Decrement TX byte counter

  }

  else

  {

    if(RPT_Flag == 1){

    RPT_Flag = 0;

    TXByteCtr = NUM_BYTES_TX;                // Load TX byte counter

    __bic_SR_register_on_exit(CPUOFF);

    }

    else{

    UCB0CTL1 |= UCTXSTP;                    // I2C stop condition

    IFG2 &= ~UCB0TXIFG;                     // Clear USCI_B0 TX int flag

    __bic_SR_register_on_exit(CPUOFF);      // Exit LPM0

    }

  }

 }

 

}

 

void Setup_TX(unsigned char Dev_ID){

  _DINT();

  RX = 0;

  IE2 &= ~UCB0RXIE; 

  while (UCB0CTL1 & UCTXSTP);               // Ensure stop condition got sent// Disable RX interrupt

  UCB0CTL1 |= UCSWRST;                      // Enable SW reset

  UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC;     // I2C Master, synchronous mode

  UCB0CTL1 = UCSSEL_2 + UCSWRST;            // Use SMCLK, keep SW reset

  UCB0BR0 = 12;                             // fSCL = SMCLK/12 = ~100kHz

  UCB0BR1 = 0;

  UCB0I2CSA = Dev_ID;                         // Slave Address is 048h

  UCB0CTL1 &= ~UCSWRST;                     // Clear SW reset, resume operation

  IE2 |= UCB0TXIE;                          // Enable TX interrupt

}

void Setup_RX(unsigned char Dev_ID){

  _DINT();

  RX = 1;

  IE2 &= ~UCB0TXIE; 

  UCB0CTL1 |= UCSWRST;                      // Enable SW reset

  UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC;     // I2C Master, synchronous mode

  UCB0CTL1 = UCSSEL_2 + UCSWRST;            // Use SMCLK, keep SW reset

  UCB0BR0 = 12;                             // fSCL = SMCLK/12 = ~100kHz

  UCB0BR1 = 0;

  UCB0I2CSA = Dev_ID;                       // Slave Address is 048h

  UCB0CTL1 &= ~UCSWRST;                     // Clear SW reset, resume operation

  IE2 |= UCB0RXIE;                          // Enable RX interrupt

}

void Transmit(unsigned char Reg_ADD,unsigned char Reg_DAT){

    MSData[2]= Reg_ADD;

       MSData[1]= Reg_DAT;

    TXByteCtr = NUM_BYTES_TX;                  // Load TX byte counter

    while (UCB0CTL1 & UCTXSTP);             // Ensure stop condition got sent

    UCB0CTL1 |= UCTR + UCTXSTT;             // I2C TX, start condition

    __bis_SR_register(CPUOFF + GIE);        // Enter LPM0 w/ interrupts

}

void Receive(void){

    PRxData = (unsigned char *)RxBuffer;    // Start of RX buffer

    RXByteCtr = NUM_BYTES_RX-1;             // Load RX byte counter

    while (UCB0CTL1 & UCTXSTP);             // Ensure stop condition got sent

    UCB0CTL1 |= UCTXSTT;                    // I2C start condition

    __bis_SR_register(CPUOFF + GIE);        // Enter LPM0 w/ interrupts

}

 

 

  • i had compile this but error

    " UCB0CTL1 undefined "

    i'm not change anything, please help me!!!

  • Did you get result for this???? 

  • this is a very good example of how to use the USCi module in I2C mode but why repeat the sending of the data and address? I try with and without the repeat bit and works fine in both. maybe is a way to ensure the sending of the commands?Thank You.
  • I doubt the TO will answer this question since it was two years ago he posted this code. But maybe you're lucky.

    Dennis
  • This code only appears to work when in single step debug mode. If you let it run freely the received values are zero. Has anyone else experienced this issue?
  • I found a few bugs in this code. First, as Juan pointed out that the code repeats sending of the data and address, the repetition caused the accelerometer to return unexpected values for me. Second, RXByteCtr isn't set up properly. With the current code, PRxData[4] will contain the 6th byte instead of the 5th byte received, PRxData[5] is never assigned to anything, and the 5th byte received is gone (replaced by the 6th byte).

    I modified this code and it worked! I posted my working program here: e2e.ti.com/.../490264
  • Did you ever figure this out? I'm trying to get it to work and its only working in debug mode as well 

  • Yes I did. You will not seeing a continuous stream  of values in the memory registers. You'll have to pause or break the code in order to see the values change if that's what you mean.  

  • :) yes I am aware you have to pause it to get the values out. I don't think the interrupt route was the correct route to go with my project. I ended up not being able to service the interrupt service routine fast enough to get the values, but have resolved the issue by getting the values outside of the interrupt.
  • Dear Ravi Butani,

    My Self Kelvin Kalariya.
    I got your reference from Ti Fourm.

    I have a interface ADXL345 with MSP430FR2311 with the help of I2C Protocol. The below code is working properly without error. But the data from the sensor what I am receiving is raw data. when I tilting this sensor the data from the sensor is remain same.
    The Data receiving in RX Buffer Every time is:

    RX_Data[0] = 0x22;

    RX_Data[1] = 0x22;

    RX_Data[2] = 0x00;

    RX_Data[3] = 0x00;

    RX_Data[4] = 0x00;

    RX_Data[5] = 0x00;

    During Next Cycle:

    RX_Data[0] = 0x00;

    RX_Data[1] = 0xFE;

    RX_Data[2] = 0x00;

    RX_Data[3] = 0xFE;

    RX_Data[4] = 0x00;

    RX_Data[5] = 0x00;

    The Above Sequence is repeated continuously.

    ================================================================================

    ////////////////////////////////////////////////////////////// Code //////////////////////////////////////////////////////////////////

    =================================================================================

    #include <msp430fr2311.h>


    volatile unsigned char TxData[3];
    volatile unsigned char RX_Data[6];
    volatile int Tx_Counter;
    int RX_Counter;
    volatile unsigned int Tx_Int_Counter;
    volatile unsigned int Rx_Int_Counter;
    volatile unsigned char Transmit[10];
    volatile int Reg_Add1;
    void TX_Data_For_Data_Demand(unsigned char Reg_Add);
    void TX_Data_Format_Bit(unsigned char Reg_Add,unsigned char Reg_Data);

    unsigned int UCB0CTVALUE;

    int main(void)
    {
    WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer

    // Configure Pins for I2C
    P1SEL0 |= BIT2 | BIT3; // I2C pins

    // Disable the GPIO power-on default high-impedance mode
    // to activate previously configured port settings
    PM5CTL0 &= ~LOCKLPM5;

    // Configure USCI_B0 for I2C mode
    UCB0CTLW0 |= UCSWRST; // put eUSCI_B in reset state
    UCB0CTLW0 |= UCMODE_3 | UCMST | UCSYNC; // I2C master mode, SMCLK
    UCB0BRW = 0x8; // baudrate = SMCLK / 8
    UCB0CTLW0 &=~ UCSWRST; // clear reset register
    UCB0I2CSA |= 0x0053;


    __bis_SR_register(GIE);



    //TX_Data_Format_Bit(0x2C,0x0A); // Power control
    //while (UCB0CTLW0 & UCTXSTP); // Ensure stop condition got sent

    TX_Data_Format_Bit(0x2D,0x00); // Power control
    while (UCB0CTLW0 & UCTXSTP); // Ensure stop condition got sent

    TX_Data_Format_Bit(0x2D,0x08); // Power control
    while (UCB0CTLW0 & UCTXSTP); // Ensure stop condition got sent

    TX_Data_Format_Bit(0x31,0x00); // Data format
    while (UCB0CTLW0 & UCTXSTP); // Ensure stop condition got sent



    while(1)
    {

    while (UCB0CTLW0 & UCTXSTP); // Ensure stop condition got sent

    TX_Data_For_Data_Demand(0x32);
    while (UCB0CTLW0 & UCTXSTP); // Ensure stop condition got sent



    }

    }

    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector = USCI_B0_VECTOR
    __interrupt void USCIB0_ISR(void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(USCI_B0_VECTOR))) USCIB0_ISR (void)
    #else
    #error Compiler not supported!
    #endif
    {
    switch(__even_in_range(UCB0IV,USCI_I2C_UCBIT9IFG))
    {
    case USCI_NONE: break; // Vector 0: No interrupts break;
    case USCI_I2C_UCALIFG: break;
    case USCI_I2C_UCNACKIFG:
    UCB0CTL1 |= UCTXSTT; //resend start if NACK
    break; // Vector 4: NACKIFG break;
    case USCI_I2C_UCSTTIFG: break; // Vector 6: STTIFG break;
    case USCI_I2C_UCSTPIFG: break; // Vector 8: STPIFG break;
    case USCI_I2C_UCRXIFG3: break; // Vector 10: RXIFG3 break;
    case USCI_I2C_UCTXIFG3: break; // Vector 14: TXIFG3 break;
    case USCI_I2C_UCRXIFG2: break; // Vector 16: RXIFG2 break;
    case USCI_I2C_UCTXIFG2: break; // Vector 18: TXIFG2 break;
    case USCI_I2C_UCRXIFG1: break; // Vector 20: RXIFG1 break;
    case USCI_I2C_UCTXIFG1: break; // Vector 22: TXIFG1 break;
    case USCI_I2C_UCRXIFG0:
    RX_Data[RX_Counter] = UCB0RXBUF;
    RX_Counter++;
    Rx_Int_Counter++;
    break; // Vector 24: RXIFG0 break;
    case USCI_I2C_UCTXIFG0: // Check TX byte counter
    // Reg_Add1 = TxData[Tx_Counter];
    UCB0TXBUF = TxData[Tx_Counter];
    Tx_Counter--;
    Tx_Int_Counter++;
    break; // Vector 26: TXIFG0 break;
    case USCI_I2C_UCBCNTIFG: break; // Vector 28: BCNTIFG
    case USCI_I2C_UCCLTOIFG: break; // Vector 30: clock low timeout
    case USCI_I2C_UCBIT9IFG: break; // Vector 32: 9th bit
    default: break;
    }
    }


    void TX_Data_Format_Bit(unsigned char Reg_Add, unsigned char Reg_Data)
    {
    Tx_Counter = 2;
    UCB0IE |= UCTXIE0| UCNACKIE; // transmit and NACK interrupt enable
    TxData[2] = Reg_Add;
    TxData[1] = Reg_Data;
    while (UCB0CTLW0 & UCTXSTP); // Ensure stop condition got sent
    UCB0CTLW0 |= UCTR | UCTXSTT; // I2C TX, start condition

    while(Tx_Counter != 0)
    {
    __no_operation();
    }

    UCB0CTLW0 |= UCTXSTP;
    UCB0IE &= ~UCTXIE; // Clear USCI_B0 TX int flag
    }

    void TX_Data_For_Data_Demand(unsigned char Reg_Add)
    {
    Tx_Counter = 1;
    TxData[1] = Reg_Add;
    RX_Counter=0;
    while (UCB0CTLW0 & UCTXSTP); // Ensure stop condition got sent
    UCB0CTLW0 |= UCTR | UCTXSTT; // I2C TX, start condition
    UCB0IE |= UCTXIE0; // transmit and NACK interrupt enable

    while(Tx_Counter != 0)
    {
    __no_operation();
    }
    UCB0IE &= ~UCTXIE; // Clear USCI_B0 TX int flag

    UCB0CTLW0 |= UCTXSTP;
    UCB0CTVALUE = UCB0CTLW0;

    while (UCB0CTLW0 & UCTXSTP); // Ensure stop condition got sent
    UCB0CTLW0 &= ~UCTR;
    UCB0CTLW0 |= UCTXSTT; // I2C TX, start condition

    UCB0IE |= UCRXIE0; // transmit and NACK interrupt enable
    while (RX_Counter<6)
    {
    __no_operation();
    }
    UCB0CTLW0 |= UCTXNACK | UCTXSTP;

    UCB0IE &= ~UCRXIE; // Clear USCI_B0 TX int flag
    __no_operation();
    }

    Please check whether my code is correct or whether it needs any modification for proper working.

    I hope you will do Help me.

    Thank You.

**Attention** This is a public forum