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.

Interfacing MSP430G2553 with ADXL345 (I2C) and serial port (UART)

Other Parts Discussed in Thread: MSP430G2553, MSP-EXP430G2, MSP430F5438A, ENERGIA

I have been searching on how to interface MSP430G2553 with ADXL345 using I2C. I found example code in many forums, but all of them are incomplete or buggy. I finally managed to modify the example code from this post and made it work! I also added a functionality to print the x,y,z values out to serial port through UART.

I saw many people replied in those forums saying that they couldn't get them working, so I decided that I should share my working solution here.

 

Hardware Setup

First, make sure the connection between MSP430 and ACXL346 is correct.

This diagram is modified from this site.

Program

The program below read x,y,z accelerometer values every one second and print the values out to the serial port using UART. It also turns on or off the red LED according to the  x and y values. Don't worry if you don't have UART set up properly, the code should still works. If you want to enable UART, don't forget to rotate the RXD and TXD jumpers on J3 by 90 degrees on the lauchpad. The UART interfacing code is modified from this site.

Here is my complete program.

//  Interfacing ADXL345 accelerometer with MSP430G2553 with I2C communication
//  and printing restuls to serial port using UART.
//
//                                /|\  /|\
//               ADXL345          10k  10k     MSP430G2xx3
//                slave            |    |        master
//             -----------------   |    |  -----------------
//            |              SDA|<-|---+->|P1.7/UCB0SDA  XIN|-
//            |                 |  |      |                 |
//            |                 |  |      |             XOUT|-
//            |              SCL|<-+----->|P1.6/UCB0SCL     |
//            |                 |         |                 |
//
//  For Sparkfun ADXL345,
//    * connect SDO to ground
//    * connect CS to VCC
//
//  Original I2C code by :
//  Prof. Ravi Butani
//  Marwadi Education Foundation, Rajkot GUJARAT-INDIA
//  ravi.butani@marwadieducation.edu.in
//  e2e.ti.com/.../260094
//
//  Original UART code by :
//  Benn Thomsen
//  bennthomsen.wordpress.com/.../
//  
//
//  Modified By :
//  Phitchaya Mangpo Phothilimthana
//  mangpo@eecs.berkeley.edu

//******************************************************************************
#include <msp430g2553.h>

#define NUM_BYTES_TX 2  
#define NUM_BYTES_RX 6
#define ADXL_345     0x53

int RXByteCtr;
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[2];

// Functions for I2C
void Setup_TX(unsigned char);
void Setup_RX(unsigned char);
void Transmit(unsigned char,unsigned char);
void TransmitOne(unsigned char);
void Receive(void);

// Function for UART: printing output to serial port
void Setup_UART();
void UARTSendArray(unsigned char *TxArray, unsigned char ArrayLength);
void UARTSendInt(unsigned int x);

int main(void)
{
  WDTCTL = WDTPW + WDTHOLD;  // Stop WDT

  // LED
  P1DIR |= BIT0; // P1.0 = red LED
  P1OUT |= BIT0; // P1.0 = red LED

  // UART
  BCSCTL1 = CALBC1_1MHZ; // Set DCO to 1MHz
  DCOCTL = CALDCO_1MHZ; // Set DCO to 1MHz

  // Configure hardware UART
  P1SEL |= BIT1 + BIT2 ;  // P1.1 = RXD, P1.2=TXD
  P1SEL2 |= BIT1 + BIT2 ; // P1.1 = RXD, P1.2=TXD

  // ADXL345
  P1SEL  |= BIT6 + BIT7;  // Assign I2C pins to USCI_B0, P1.6 = SCL, P1.7 = SDA
  P1SEL2 |= BIT6 + BIT7;  // Assign I2C pins to USCI_B0, P1.6 = SCL, P1.7 = SDA

  // Init sequence for ADXL345
  Setup_TX(ADXL_345);
  Transmit(0x2D,0x00);                    
  while (UCB0CTL1 & UCTXSTP);             // Ensure stop condition got sent

  Setup_TX(ADXL_345);
  Transmit(0x2D,0x10);
  while (UCB0CTL1 & UCTXSTP);             // Ensure stop condition got sent

  Setup_TX(ADXL_345);
  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);
    TransmitOne(0x32);                  // 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

    int x = (((int)RxBuffer[1]) << 8) | RxBuffer[0];
    int y = (((int)RxBuffer[3]) << 8) | RxBuffer[2];
    int z = (((int)RxBuffer[5]) << 8) | RxBuffer[4];

    // Now we have x,y,z reading.
    // Below red LED is on, if x or y angle is more then 45 or less then -45 degree.
    if ((x > 128) || (y > 128) || (x < -128) || (y < -128)) {
      P1OUT |= BIT0; // red LED on
    }
    else {
      P1OUT &= ~BIT0; // red LED off
    }

    // Print x,y,z to serial port in hew.
    Setup_UART();
    UARTSendArray("sample\n", 7);
    UARTSendInt(x);
    UARTSendInt(y);
    UARTSendInt(z);
    __delay_cycles(1000000);  // delay 1 sec
  }
}

//-------------------------------------------------------------------------------
// I2C
//-------------------------------------------------------------------------------
#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
      {
        UCB0CTL1 |= UCTXSTP;                // No Repeated Start: stop condition
        *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
      {
        TXByteCtr--;                        // Decrement TX byte counter
        UCB0TXBUF = MSData[TXByteCtr];      // Load TX buffer
      }
    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 &= ~UCA0RXIE; // Disable USCI_A0 RX interrupt (UART)
  IE2 &= ~UCB0RXIE; // Disable USCI_B0 RX interrupt (I2C)
  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 &= ~UCA0RXIE; // Disable USCI_A0 RX interrupt (UART)
  IE2 &= ~UCB0TXIE; // Disable USCI_B0 TX interrupt (I2C)
  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[1]= Reg_ADD;
  MSData[0]= 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 TransmitOne(unsigned char Reg_ADD){
  MSData[0]= Reg_ADD;
  TXByteCtr = 1;                          // 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;               // 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
}

//-------------------------------------------------------------------------------
// UART
//-------------------------------------------------------------------------------

void Setup_UART() {
  _DINT();
  IE2 &= ~UCB0RXIE; // Disable USCI_B0 RX interrupt (I2C)
  IE2 &= ~UCB0TXIE; // Disable USCI_B0 TX interrupt (I2C)
  UCA0CTL1 |= UCSSEL_2; // Use SMCLK
  UCA0BR0 = 104;        // Set baud rate to 9600 with 1MHz clock (Data Sheet 15.3.13)
  UCA0BR1 = 0;          // Set baud rate to 9600 with 1MHz clock
  UCA0MCTL = UCBRS0;    // Modulation UCBRSx = 1
  UCA0CTL1 &= ~UCSWRST; // Initialize USCI state machine
  IE2 |= UCA0RXIE; // Enable USCI_A0 RX interrupt
}

// Print an array of char
void UARTSendArray(unsigned char *TxArray, unsigned char ArrayLength){

  while(ArrayLength--){         // Loop until StringLength == 0 and post decrement
    while(!(IFG2 & UCA0TXIFG)); // Wait for TX buffer to be ready for new data
    UCA0TXBUF = *TxArray;       // Write the character at the location specified py the pointer
    TxArray++;                  //Increment the TxString pointer to point to the next character
  }
  IFG2 &= ~UCA0TXIFG;           // Clear USCI_A0 int flag
}

// Print int in hex
void UARTSendInt(unsigned int x){
  unsigned char buff[10];
  unsigned char data[10];
  unsigned char index = 0, i = 0;

  while(x > 0) {
    unsigned char val = x % 16;
    if(val < 10)
      buff[index] = 48+val;
    else
      buff[index] = 97+val-10;
    index++;
    x /= 16;
  }
  buff[index] = '\n';

  while(index > 0) {
    index--;
    data[i] = buff[index];
    i++;
  }

  if(i==0) {
    data[0] = '0';
    i++;
  }
  data[i] = '\n';
  UARTSendArray(data, i+1);
}


  • Phitchaya,

    Thank you for providing a detailed description of your solution, I'm sure it will be very useful for any community members seeking to use the ADXL345 with the MSP-EXP430G2 LaunchPad.

    Regards,
    Ryan
  • Hey, I'm having issues with this losing connection with the ADXL345 when in the run mode. I am using it with a 8Mhz clock and incrementing Vcore, with a sampling rate of 400hz. Do you have any suggestions for data results returning only 0s? I am also getting a NACK interrupt, suggesting that the ADXL345 is not acknowledging the MSP430.... 

  • Hi Shoa,

    Are you losing connection or do you never have connection to begin with? Return values of 0 could indicate that your pull-up resistors are not connected properly, therefore keeping the lines low. Are you using a MSP430G2553, and in what ways have you modified the existing code?

    Regards,
    Ryan
  • Hey, so this is what I have for code. It's a modification of what you posted to work with the MSP430f5438a. I have a connection and am getting acknowledgments for a few cycles and getting data, but after a moment or two I start getting Nacks and the device doesn't send any more data to the RXbuffer. I've checked the pull up resistors I am using, there are some on the break out board for the ADXL345 and I am using 180ohms externally. These produce a min and max voltage on the data line that meets the criteria on the ADXL345. This issue has been driving me crazy for weeks, any help is highly appreciated! :)



    #include <msp430f5438a.h>
    #include <msp430.h>
    #include "ADXL345.h"

    extern int IncrementVcore(void);


    #define NUM_BYTES_TX 2
    #define NUM_BYTES_RX 6
    #define ADXL_345 0x53

    int RXByteCtr;
    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[2];
    int x,y,z,p;

    // Functions for I2C
    void Setup_TX(unsigned char);
    void Setup_RX(unsigned char);
    void TransmitOne(unsigned char);
    void Receive(void);



    void Setup_UART();
    void UARTSendArray(unsigned char *TxArray, unsigned char ArrayLength);
    void UARTSendInt(unsigned int x);


    int main(void)
    {


    IncrementVcore();
    IncrementVcore();
    IncrementVcore();
    IncrementVcore();
    WDTCTL = WDTPW + WDTHOLD; // Stop WDT
    // UART
    //UCSCTL6 |= XT1BYPASS; // uses the internal clock instead of the external
    UCSCTL1 |= DCORSEL_4; //selects the range of the DCO select to 4 for 8 mhz
    UCSCTL2 |= 225; // PART I sets the N+1 value to 8Mhz
    UCSCTL3 |= SELREF__XT1CLK; // selects the XT1clock as the reference clock
    UCSCTL4 |= SELS__DCOCLK; // sets Smclk to the DCOclk as reference
    UCSCTL0 |= DCO4 + DCO3 + DCO2 + DCO1 + MOD3 +MOD2 +MOD1 +MOD0;




    P5SEL = BIT6 + BIT7; //A1
    // ADXL345
    P3SEL |= BIT7; // Assign I2C pins to USCI_B0, P1.6 = SCL, P1.7 = SDA
    P5SEL |= BIT4; // Assign I2C pins to USCI_B0, P1.6 = SCL, P1.7 = SDA
    P11DIR |= BIT2; //PART I sets pin 11.2 to output
    P11SEL |= BIT2; //PART I sets pin 11.2 to output mclk
    ADXL_setup();

    while(1){
    // Transmit process
    Setup_TX(ADXL_345);
    TransmitOne(0x32); // Request Data from ADXL345 in 2g Range 10Bit resolution
    while (UCB1CTL1 & UCTXSTP); // Ensure stop condition got sent

    // Receive process
    Setup_RX(ADXL_345);
    Receive();
    while (UCB1CTL1 & UCTXSTP); // Ensure stop condition got sent

    x = (((int)RxBuffer[1]) << 8) | RxBuffer[0];
    y = (((int)RxBuffer[3]) << 8) | RxBuffer[2];
    z = (((int)RxBuffer[5]) << 8) | RxBuffer[4];

    __delay_cycles(10000000); // delay 1 sec



    }
    }
    void ADXL_setup(void){
    //see header for comments
    Setup_TX(ADXL_345);
    ADXL_I2C_WRITE(ADXL_POWER_CTL,0x00);
    Setup_TX(ADXL_345);
    ADXL_I2C_WRITE(ADXL_POWER_CTL,0x10);
    Setup_TX(ADXL_345);
    ADXL_I2C_WRITE(ADXL_POWER_CTL,0x08);
    Setup_TX(ADXL_345);
    ADXL_I2C_WRITE(ADXL_DATA_FORMAT,0x02);
    }


    //-------------------------------------------------------------------------------
    // I2C
    //-------------------------------------------------------------------------------
    void I2C_B1_irs(void) __interrupt[USCI_B1_VECTOR]
    {

    if(RX == 1){ // Master Recieve?
    RXByteCtr--; // Decrement RX byte counter
    if (RXByteCtr)
    {
    *PRxData++ = UCB1RXBUF; // Move RX data to address PRxData
    }
    else
    {
    UCB1CTL1 |= UCTXSTP; // No Repeated Start: stop condition
    *PRxData++ = UCB1RXBUF; // Move final RX data to PRxData
    // __bic_SR_register_on_exit(CPUOFF); // Exit LPM0
    }}
    else{ // Master Transmit
    if (TXByteCtr) // Check TX byte counter
    {
    TXByteCtr--; // Decrement TX byte counter
    UCB1TXBUF = MSData[TXByteCtr]; // Load TX buffer
    }
    else
    {
    UCB1CTL1 |= UCTXSTP; // I2C stop condition
    UCB1IFG &= ~UCTXIFG; // Clear USCI_B0 TX int flag
    // __bic_SR_register_on_exit(CPUOFF); // Exit LPM0
    }
    }
    }

    void Setup_TX(unsigned char Dev_ID){
    //_DINT();
    RX = 0;
    UCA1IE &= ~UCRXIE; // Disable USCI_A0 RX interrupt (UART)
    UCB1IE &= ~UCRXIE; // Disable USCI_B0 RX interrupt (I2C)
    while (UCB1CTL1 & UCTXSTP); // Ensure stop condition got sent// Disable RX interrupt
    UCB1CTL1 |= UCSWRST; // Enable SW reset
    UCB1CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode
    UCB1CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset
    UCB1BR0 = 80; // fSCL = SMCLK/20 = ~100kHz
    UCB1BR1 = 0;
    UCB1I2CSA =0x53; // Slave Address is 048h
    UCB1CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
    UCB1IE |= UCTXIE; // Enable TX interrupt
    }

    void Setup_RX(unsigned char Dev_ID){
    // _DINT();
    RX = 1;
    UCA1IE &= ~UCRXIE; // Disable USCI_A0 RX interrupt (UART)
    UCB1IE &= ~UCTXIE; // Disable USCI_B0 TX interrupt (I2C)
    UCB1CTL1 |= UCSWRST; // Enable SW reset
    UCB1CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode
    UCB1CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset
    UCB1BR0 = 80; // fSCL = SMCLK/20 = ~100kHz
    UCB1BR1 = 0;
    UCB1I2CSA = Dev_ID; // Slave Address is 048h
    UCB1CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
    UCB1IE |= UCRXIE; // Enable RX interrupt
    }

    void ADXL_I2C_WRITE(unsigned char ADXL_reg_add, unsigned char ADXL_data_add){
    MSData[1]= ADXL_reg_add;
    MSData[0]= ADXL_data_add;
    TXByteCtr = NUM_BYTES_TX; // Load TX byte counter
    while (UCB1CTL1 & UCTXSTP); // Ensure stop condition got sent
    UCB1CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition
    __bis_SR_register( GIE); // Enter LPM0 w/ interrupts

    }

    void TransmitOne(unsigned char Reg_ADD){
    MSData[0]= Reg_ADD;
    TXByteCtr = 1; // Load TX byte counter
    while (UCB1CTL1 & UCTXSTP); // Ensure stop condition got sent
    UCB1CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition
    __bis_SR_register(GIE); // Enter LPM0 w/ interrupts
    }

    void Receive(void){
    PRxData = (unsigned char *)RxBuffer; // Start of RX buffer
    RXByteCtr = NUM_BYTES_RX; // Load RX byte counter
    while (UCB1CTL1 & UCTXSTP); // Ensure stop condition got sent
    UCB1CTL1 |= UCTXSTT; // I2C start condition
    while(UCB1IFG & UCNACKIFG); //WAIT FOR ACKNOLEDGMENT

    __bis_SR_register(GIE); // Enter LPM0 w/ interrupts
    }
  • Can you please provide a specific link to the ADXL345 breakout board you are using? 180 ohms seems much too small for I2C pull-up resistors but I do not know what is already on-board. Total pull-up resistance should be near 10 kOhms.

    I would refer to the msp430x54xA_UCS_2.c example for setting SMCLK to 8 MHz from the DCO. Increasing Vcore should be unecessary (and can only be done 3 times, up to a PMMCOREV value of 3) since operation is limited to 8 MHz, although this does not harm the device so long as Vcc is greater than 2.4 V.

    Regards,
    Ryan
  • Hi, I try to test your code with adxl345, but it does not work properly. Most of the time I get full most significant byte and it is not possible, because ADC converter is just 10 bits. I do not know where is the problem :(

    The same code results (100 Hz frequency)

    Just X and Y axis sending just 4 bytes the same problem 

  • how can we running servo motors with data which take adxl345?

  • Hello

    I have a question about the UART receive buffer (UCA0RXBUF) of MSP430G2553, should I clear the buffer before the arrival of new data or the data will be overwritten?

    Thank you

  • When you have not read the old value, the UCOE ("overflow") error bit will be set. You can choose to ignore it.
  • Murtadha A said:
    should I clear the buffer before the arrival of new data or the data will be overwritten?

    You do not have to clear it, but the buffer is only one byte, so your existing data will be overwritten and is lost.

  • Thank you guys,

    Would you please take a look at my code and tell me what is wrong with it. I am using this to communicate with BN055 IMU which is connected to and MSP430G2553 launchpad via UART.
    The problem is in the last line, when I send TXSTRING("\xAA\x01\x08\x06") to the BNO055 to read the acceleration I get BB 06 00 00 00 00 00 00. The BB 06 is header but the data are not there (all 00).

    Should I clear the uart.rxbuffer in this case before transmitting a new set of bytes? if so, how to clear the uart.rxbuffer. I tried uart.rxbuffer[0]=0, uart.rxbuffer[1]=0, etc. but this did not clear the memory.

    Thank you

    M


    #include "msp430g2553.h" #include <stdio.h> char xLSB, xMSB, yLSB, yMSB, zLSB, zMSB; #define TXD BIT2 #define RXD BIT1 typedef struct uart // UART { char *bufTXpnt; // UART TX buffer pointer unsigned int TXbuflen; // the lenght of TX block char *bufRXpnt; // UART RX buffer pointer unsigned int RXbuflen; // the lenght of RX block char TXbuffer[8]; char RXbuffer[8]; } uartstruct; void set_UCS() { //------------------- Configure the Clocks -------------------// WDTCTL = WDTPW + WDTHOLD; // Stop the Watch dog DCOCTL = 0; // Select lowest DCOx and MODx settings BCSCTL1 = CALBC1_12MHZ; // Set range DCOCTL = CALDCO_12MHZ; // Set DCO step + modulation // DCO -> SMCLK (Default) IE1 &= 0xFD; /* Disable UCS interrupt */ return; } void setMSP430Pins() { //--------- Setting the UART function for P1.1 & P1.2 --------// // P2DIR = 0xFF; // All P2.x outputs< //P2OUT &= 0x00; // All P2.x reset P1SEL |= RXD + TXD ; // P1.1 = RXD, P1.2=TXD P1SEL2 |= RXD + TXD ; // P1.1 = RXD, P1.2=TXD // P1OUT &= 0x00; return; } void uart_init(void){ IE2 &= ~(UCA0TXIE | UCA0RXIE | UCB0TXIE | UCB0RXIE); // Disable all USCIx0 TX & RX interrupts UCA0CTL1 = UCSWRST; // Set UCSWRST (hold USCI in Reset state) UCA0CTL1 |= UCSSEL_2; // CLK = SMCLK // ------------ Configuring the UART(USCI_A0) ----------------// // 115200 BAUD, CLK=12MHz UCA0BR0 = 6; UCA0BR1 = 0; // //*ours: UCBRF = 8, UCBRS = 0, UCOS16 = 1 // // BITS| 7 6 5 4 | 3 2 1 | 0 | // UCAxMCTL = | UCBRFx | UCBRSx | UCOS16 | UCA0MCTL = 0x81; //this works fine UCA0CTL1 &= ~UCSWRST; // Clear UCSWRST to enable USCI_A0-UART UCA0CTL1 &= ~UCSYNC; IFG2 |= UCA0TXIFG; // preset IFG flag always left on IE2|=UCA0RXIE; } #define TXSTRING(pnt) (TXdata((pnt), sizeof(pnt)-1)) // macro to get string and string len uartstruct uart; // declare a struct from typedef uartstruct void TXdata( char* pnt, unsigned int len){ uart.bufTXpnt = pnt; uart.TXbuflen = len; uart.bufRXpnt = uart.RXbuffer; // reset it to beginning of ram buffer IE2 |= UCA0TXIE + UCA0RXIE; // enable USCI_A0 TX & RX interrupt } //¦----------------------------- Delay Function ---------------------------------------¦ // This function will give us 1ms wait time, so for getting 10 ms, // then delay_ms(10) will give 10ms and delay_ms(100) will give 100ms void delay_ms(unsigned int ms) { unsigned int i; for (i = 0; i<= ms; i++) __delay_cycles(6000); // 6000 will give us 1ms } //¦----------------------------- US0TX ISR ---------------------------------------¦ #pragma vector=USCIAB0TX_VECTOR __interrupt void USCIAB0TX(void) // Shared A0/B0 TX IRQ vector { if (IFG2 & UCA0TXIFG){ // check for UART TX if (uart.TXbuflen){ // if not zero UCA0TXBUF = *uart.bufTXpnt++; --uart.TXbuflen; } else IE2 &= ~UCA0TXIE; // suspend IE if zero } else IFG2 &= ~UCA0TXIFG; // clear a false UCB0 trigger } //¦----------------------------- US0RX ISR ---------------------------------------¦ #pragma vector=USCIAB0RX_VECTOR __interrupt void USCIAB0RX(void) // A0/B0 RX IRQ vector { if (IFG2 & UCA0RXIFG){ // check for UART RX *uart.bufRXpnt++ = UCA0RXBUF; // copy data byte if (uart.bufRXpnt == uart.RXbuffer+8 && uart.RXbuffer[0]==0xBB) // got 8 bytes in yet? <<<< uart.RXbuflen=uart.RXbuffer[1]; __bic_SR_register_on_exit(LPM3_bits); } else IFG2 &= ~UCA0RXIFG; } //¦----------------------------- Main -------------------------------------------¦ void main(void) { set_UCS(); setMSP430Pins(); uart_init(); delay_ms(500); TXSTRING("\xAA\x00\x3D\x01\x00"); // Send this to the BNO055 to set up the config mode while( !(IFG2 & UCA0TXIFG) && uart.RXbuffer[1]==0x01); TXSTRING("\xAA\x00\x3F\x01\x20"); // reset delay_ms(60); while( !(IFG2 & UCA0TXIFG) && uart.RXbuffer[1]==0x01); TXSTRING("\xAA\x00\x3E\x01\x00"); // Normal power mode delay_ms(10); // while( !(IFG2 & UCA0TXIFG) && uart.RXbuffer[1]==0x01); TXSTRING("\xAA\x00\x07\x01\x00"); // Send this to the BNO055 to set up page 0 delay_ms(10); while( !(IFG2 & UCA0TXIFG) && uart.RXbuffer[1]==0x01); TXSTRING("\xAA\x00\x3D\x01\x07"); // Send this to the BNO055 to set up the 9DOF mode delay_ms(120); // while( !(IFG2 & UCA0TXIFG) && uart.RXbuffer[1]==0x01); TXSTRING("\xAA\x01\x08\x06"); while( !(IFG2 & UCA0TXIFG)); delay_ms(120); xLSB = uart.RXbuffer[2]; xMSB = uart.RXbuffer[3]; yLSB = uart.RXbuffer[4]; yMSB = uart.RXbuffer[5]; zMSB = uart.RXbuffer[6]; zMSB = uart.RXbuffer[7]; __bis_SR_register(LPM3_bits + GIE); // Enter LPM3 w/ int until Byte RXed while(1) { } }

  • Has anybody run into the condition where the red LED on the launchpad stays on constantly? No matter if the ADXL345 is connected or not the red LED is on all the time. I copied and pasted the code to CCS6 and loaded it to the launchpad.

    Thanks !!

    Jake
  • I tried compiling this code but this is what I keep receiving, could someone please help with that, thank you (by the way I am a beginner):
    sketch_jan24a.cpp: In function 'int main()':
    sketch_jan24a.cpp:124:32: error: invalid conversion from 'const char*' to 'unsigned char*' [-fpermissive]
    sketch_jan24a.cpp:54:6: error: initializing argument 1 of 'void UARTSendArray(unsigned char*, unsigned char)' [-fpermissive]
  • I forgot the exact command I used to compile this code. What happens if you compile with the -fpermissive flag? Do you still get this error?

  • yes it is still happening, I am using the energia software if that info can you help me :)

  • Oh, I think I used msp430-gcc: mitchtech.net/.../
    I've never used energia.
  • that could be the reason, I am going to try that launchpad compiler and keep you updated on how it goes, since I am a novice I admit there are still a few things I don't know, I just need this code to work real bad. Thank so much for your willingness to help I truly appreciate it

  • Sorry to bother you again , msp430-gcc isn't working for me, the version of code composer I have won't compile it, the license I have exclude msp430 and some XDS510 emulators.. :/
    This is not looking for me, did you run your on an ubuntu machine if I may ask, because I am using a windows pc, could that be reason it doesn't work for me, maybe needs some tweaking ?
  • Right, I'm using ubuntu. It's quite difficult to get gcc working on windows...
  • Ok sorry, so I managed to my hand on a computer running ubuntu now , also got the code to run I see the Red LED on, my difficulty now is how to print out the values, by the way I am using the ubuntu terminal. what specific software did you use if you don't mind me asking. Thank you
  • I'm also using terminal. I followed the first half of Section 11 to set up the serial interface: 

    http://dbindner.freeshell.org/msp430/#Talking_to_MSP430

    Before, you run my code with the accelerator, you should try if your UART is working properly with this code: 

    https://bennthomsen.wordpress.com/engineering-toolbox/ti-msp430-launchpad/msp430g2553-hardware-uart/

    Remember that "it is necessary to rotate the RXD and TXD jumpers on J3 by 90 degrees on the lauchpad to enable UART" 
    My UART code is based on this blog post. I don't remember if I had to change anything to make this code work.

  • Ah my fault I had not pay attention to that step before, this information is Gold, Thank you so I'll go back and work on it a bit more. I will let you know what I get Thanks again for the continuous support :)
  • Hi

    I am using this ADXL345 from adafruit:

    https://www.adafruit.com/product/1231   

    In this case, do I need the pull/ pull down resistors? I assume they are already included in the adafruit board.

    If I do not need them, then how does the connection look like?


    Thank you

  • To find out whether there a pull-up resistors, look at the schematic.

    Connections can be done with headers, wires, jumper cables, or something like that.
  • Here is the link for the schematic, would you please take a look at it as I am confused whether I should add these 10K resistors or they are already there!

    learn.adafruit.com/.../36127

    Thank you
  • OK, I looked at the schematic of another board from adafruit (that embeds the BNO055) and I compared it with the one of ADXL345, seems that the resistors are already there
  • Hi guys

    Would you please help me as the code did not work for me.

    First I connected the Accelerometer to an Arduino uno and used the Arduino version of the code for testing and it worked. However, when I used the same connection with the MSP430G2553 launchpad it did not work.

    The code get stuck in line 205 (i.e. after loading 2D & 00 to the TX buffer, and I can see 00 in RX buffer). 

    Is that because of __bis_SR_register(CPUOFF + GIE); ? as this will put the MCU to sleep and then an event is waited to awake the MCU?

    I am bad in using interrupts, so please help me.

    Thank you

  • __bis_SR_register(CPUOFF + GIE) will put the MCU to sleep with interrupt enabled.

    When an interrupt occurs, it should execute the function __interrupt void USCIAB0TX_ISR(void). This function may call __bic_SR_register_on_exit(CPUOFF), which make the MCU continues running the main function.

    My guess is that your code is stuck because the interrupt somehow doesn't occur.

    I used a circuit analyzer to probe what signals actually get sent to and received from the accelerometer when I debugging my program + circuit.

  • Offtopic, but I'm impressed that this thread has over 20000 views already!! Looks like it is quite interesting for a lot of people.