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.

Accelerometer to trigger LED

Other Parts Discussed in Thread: MSP430F5529

So I am using an ADXL 335 analog accelerometer to light the LED on a MSP430F5529 launchpad. It seems as if I can't get the MCU to read in data from accelerometer. Below is the code I have so far.

#include <msp430.h>
#include <stdint.h>

// POWER CONFIG
#define ACC_PWR_PIN BIT0
#define ACC_PWR_PORT_DIR P6DIR
#define ACC_PWR_PORT_OUT P6OUT

// CHANNEL CONFIG
#define ACC_PORT_DIR P6DIR
#define ACC_PORT_OUT P6OUT
#define ACC_PORT_SEL P6SEL
#define ACC_X_PIN BIT1 // P6.1
#define ACC_Y_PIN BIT2 // P6.2
#define ACC_Z_PIN BIT3 // P6.3

// ACCELEROMETER INPUT CHANNEL
#define ACC_X_CHANNEL ADC12INCH_1
#define ACC_Y_CHANNEL ADC12INCH_2
#define ACC_Z_CHANNEL ADC12INCH_3

void CalibrateADC(void);
void SetupACC(void);
void LongDelay(void);


unsigned int ADC_counter = 0;
unsigned int ADCResult_X, ADCResult_Y, ADCResult_Z;
unsigned int CalValue_X, CalValue_Y, CalValue_Z;
unsigned int temp, i;

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


// ************************************************************************************
// Initialize Clock
// ************************************************************************************

// Configure system clock MCLK = SMCLK = 10 MHz
UCSCTL3 = SELREF_2; // FLL = REFOCLK 32768 Hz

uint16_t srRegState = _get_SR_register() & SCG0; // Save register state
_bic_SR_register(SCG0); // clear SCGO to configure clock

UCSCTL0 = 0x0000; // lowest DCO tap first
UCSCTL2 &= ~0x03FF; // Mask to set N = 0
UCSCTL1 = DCORSEL_4; // Frequency range ~= 2-20 MHz
UCSCTL2 = FLLD_0 + 244; // D = 0, N+1 = 307
// fDCOCLK = D*(N+1)*fFLLREFCLK/n
// 8 MHz = 1*(244+1)*32768/1

// Clear fault flags
while(SFRIFG1 & OFIFG) {
UCSCTL7 &= ~(XT1LFOFFG+XT2OFFG+DCOFFG);
SFRIFG1 &= ~OFIFG;
for(i=0;i<0xFFFF;i++);
}
UCSCTL4 = 0x0333; // ACLK = SMCLK = MCLK = DCOCLK

_bis_SR_register(srRegState); // restore SCG0 state

REFCTL0 |= REFTCOFF;
REFCTL0 &= ~REFON;

// ************************************************************************************
// End of clock initialization
// ************************************************************************************

// ************************************************************************************
// Setup LED
// ************************************************************************************
P1OUT &= (BIT0);
P1DIR |= BIT0;
P4OUT &= BIT7;
P4DIR |= BIT7;

// ************************************************************************************
// Setup Accelerometer inputs P6.1,2,3
// ************************************************************************************
P6OUT &= ~(BIT1 + BIT2 + BIT3);
P6DIR &= ~(BIT1 + BIT2 + BIT3);
P6REN |= BIT1 + BIT2 + BIT3;

SetupACC();
CalibrateADC();

while(1) {
if (ADCResult_X > CalValue_X + 10) {
P1OUT ^= BIT0;
}
else if (ADCResult_X < CalValue_X - 10)
P4OUT ^= BIT7;

if (ADCResult_Y > CalValue_Y + 10) {
P1OUT ^= BIT0;
}
else if (ADCResult_Y < CalValue_Y - 10)
P4OUT ^= BIT7;

if (ADCResult_Z > CalValue_Z + 10) {
P1OUT ^= BIT0;
}
else if (ADCResult_Z < CalValue_Z - 10)
P4OUT ^= BIT7;

}

return 0;
}

// ************************************************************************************
// Calibrate ACD conversion
// ************************************************************************************
void CalibrateADC(void) {
uint16_t CalibCounter = 0;
unsigned int Value = 0;

__disable_interrupt(); // Turn off interrupts just incase

ADC12CTL0 &= ~ADC12ENC; // Toggle ENC bit
ADC12MCTL0 = ADC12SREF_0 + ADC12INCH_1; // Sample X Channel
while(CalibCounter < 50) {
P1OUT ^= BIT0; // Toggle LED1
CalibCounter++;
ADC12CTL0 |= ADC12ENC | ADC12SC; // Start Sample
while(ADC12CTL1 & BUSY); // Wait for sample to be done
Value += ADC12MEM0;
}
CalValue_X = Value/50; // Average of 50 samples
ADC12CTL0 &= ~ADC12ENC;
CalibCounter = 0; // Reset Counter
Value = 0; // Reset Value
ADC12MCTL0 = ADC12SREF_0 + ADC12INCH_2; // Sample Y Channel
while(CalibCounter < 50) {
P4OUT ^= BIT7; // Toggle LED2
CalibCounter++;
ADC12CTL0 |= ADC12ENC | ADC12SC; // Start Sample
while(ADC12CTL1 & BUSY); // Wait for sample to be done
Value += ADC12MEM0;
}
CalValue_Y = Value/50;
ADC12CTL0 &= ~ADC12ENC;
CalibCounter = 0; // Reset Counter
Value = 0; // Reset Value
ADC12MCTL0 = ADC12SREF_0 + ADC12INCH_3;
while(CalibCounter < 50) {
P4OUT ^= BIT7; // Toggle LED2
P1OUT ^= BIT0; // Toggle LED1
CalibCounter++;
ADC12CTL0 |= ADC12ENC | ADC12SC; // Start Sample
while(ADC12CTL1 & BUSY); // Wait for sample to be done
Value += ADC12MEM0;
}
CalValue_Z = Value/50;
ADC12MCTL0 &= ADC12ENC;
ADC12MCTL0 = ADC12SREF_0 + ADC12INCH_1;

__enable_interrupt();
}

void SetupACC(void) {

// Configure GPIO
ACC_PORT_SEL |= ACC_X_PIN + ACC_Y_PIN + ACC_Z_PIN;
ACC_PORT_DIR &= ~(ACC_X_PIN + ACC_Y_PIN + ACC_Z_PIN);
ACC_PWR_PORT_DIR |= ACC_PWR_PIN;
ACC_PWR_PORT_OUT |= ACC_PWR_PIN;

__delay_cycles(200000);

ADC12CTL0 &= ~ADC12ENC;
ADC12CTL0 = ADC12ON + ADC12SHT0_5;
ADC12CTL1 = ADC12SHS_0 + ADC12SHP + ADC12CONSEQ_0 + ADC12SSEL_0;
ADC12CTL2 = ADC12RES_2;
ADC12MCTL0 = ADC12SREF_0 + ADC12INCH_1;
ADC12IV = 0x00;
ADC12IE |= ADC12IE0;

__enable_interrupt();

}

// ************************************************************************************
// A long delay
// ************************************************************************************
void LongDelay(void) {
__delay_cycles(250000);
}

// ************************************************************************************
// ADC Interrupt Routine
// ************************************************************************************
#pragma vector = ADC12_VECTOR
__interrupt void ADC12_ISR(void) {
if(ADC_counter == 0) // X-axis
{
ADC12CTL1 &= ~ADC12ENC;
ADC12MCTL0 = ADC12SREF_0 + ADC12INCH_1;
ADCResult_X = ADC12MEM0;
ADC_counter++;
ADC12CTL0 |= ADC12ENC | ADC12SC;
}
else if (ADC_counter == 1) {
ADC12CTL1 &= ~ADC12ENC;
ADC12MCTL0 = ADC12SREF_0 + ADC12INCH_2;
ADCResult_Y = ADC12MEM0;
ADC_counter++;
ADC12CTL0 |= ADC12ENC | ADC12SC;
}
else {
ADC12CTL1 &= ~ADC12ENC;
ADC12MCTL0 = ADC12SREF_0 + ADC12INCH_3;
ADCResult_Z = ADC12MEM0;
ADC_counter++;
ADC12CTL0 |= ADC12ENC | ADC12SC;
}
}

  • Your code:

    #include <msp430.h>
    #include <stdint.h>
    
    // POWER CONFIG
    #define ACC_PWR_PIN BIT0
    #define ACC_PWR_PORT_DIR P6DIR
    #define ACC_PWR_PORT_OUT P6OUT
    
    // CHANNEL CONFIG
    #define ACC_PORT_DIR P6DIR
    #define ACC_PORT_OUT P6OUT
    #define ACC_PORT_SEL P6SEL
    #define ACC_X_PIN BIT1 // P6.1
    #define ACC_Y_PIN BIT2 // P6.2
    #define ACC_Z_PIN BIT3 // P6.3
    
    // ACCELEROMETER INPUT CHANNEL
    #define ACC_X_CHANNEL ADC12INCH_1
    #define ACC_Y_CHANNEL ADC12INCH_2
    #define ACC_Z_CHANNEL ADC12INCH_3
    
    void CalibrateADC( void );
    void SetupACC( void );
    void LongDelay( void );
    
    unsigned int ADC_counter = 0;
    unsigned int ADCResult_X, ADCResult_Y, ADCResult_Z;
    unsigned int CalValue_X, CalValue_Y, CalValue_Z;
    unsigned int temp, i;
    
    /*
    * main.c
    */
    
    int main( void )
    {
      WDTCTL = (WDTPW | WDTHOLD); // Stop watchdog timer
    
      // ************************************************************************************
      // Initialize Clock
      // ************************************************************************************
    
      // Configure system clock MCLK = SMCLK = 10 MHz
      UCSCTL3 = SELREF_2; // FLL = REFOCLK 32768 Hz
    
      uint16_t srRegState = _get_SR_register() & SCG0; // Save register state
      _bic_SR_register( SCG0 ); // clear SCGO to configure clock
    
      UCSCTL0  =  0x0000; // lowest DCO tap first
      UCSCTL2 &= ~0x03FF; // Mask to set N = 0
      UCSCTL1  =  DCORSEL_4; // Frequency range ~= 2-20 MHz
      UCSCTL2  =  (FLLD_0 + 244); // D = 0, N+1 = 307
      // fDCOCLK = D*(N+1)*fFLLREFCLK/n
      // 8 MHz = 1*(244+1)*32768/1
    
      // Clear fault flags
      while( SFRIFG1 & OFIFG )
      {
        UCSCTL7 &= ~(XT1LFOFFG | XT2OFFG | DCOFFG);
        SFRIFG1 &= ~OFIFG;
    
        for( i=0; i<0xFFFF; i++ );
      }
    
      UCSCTL4 = 0x0333; // ACLK = SMCLK = MCLK = DCOCLK
    
      _bis_SR_register( srRegState ); // restore SCG0 state
    
      REFCTL0 |=  REFTCOFF;
      REFCTL0 &= ~REFON;
    
      // ************************************************************************************
      // End of clock initialization
      // ************************************************************************************
    
      // ************************************************************************************
      // Setup LED
      // ************************************************************************************
      
      P1OUT &= BIT0; // COMMENT: Should this be low? Then <P1OUT &= ~BIT0;>
      P1DIR |= BIT0;
      P4OUT &= BIT7; // COMMENT: Should this be low? Then <P4OUT &= ~BIT7;>
      P4DIR |= BIT7;
    
      // ************************************************************************************
      // Setup Accelerometer inputs P6.1,2,3
      // ************************************************************************************
    
      P6OUT &= ~(BIT1 | BIT2 | BIT3);
      P6DIR &= ~(BIT1 | BIT2 | BIT3);
      P6REN |=  (BIT1 | BIT2 | BIT3);
    
      SetupACC();
      CalibrateADC();
    
      while( 1 )
      {
        if( ADCResult_X > (CalValue_X + 10) )
        {
          P1OUT ^= BIT0;
        }
        else if( ADCResult_X < (CalValue_X - 10) )
        {
          P4OUT ^= BIT7;
        }
    
        if( ADCResult_Y > (CalValue_Y + 10) )
        {
          P1OUT ^= BIT0;
        }
        else if( ADCResult_Y < (CalValue_Y - 10) )
        {
          P4OUT ^= BIT7;
        }
    
        if( ADCResult_Z > (CalValue_Z + 10) )
        {
          P1OUT ^= BIT0;
        }
        else if( ADCResult_Z < (CalValue_Z - 10) )
        {
          P4OUT ^= BIT7;
        }
      }
    
      return 0;
    }
    
    
    
    // ************************************************************************************
    // Calibrate ACD conversion
    // ************************************************************************************
    
    void CalibrateADC( void )
    {
      uint16_t CalibCounter = 0;
      unsigned int Value    = 0;
    
      __disable_interrupt(); // Turn off interrupts just incase
    
      ADC12CTL0  &= ~ADC12ENC; // Toggle ENC bit
      ADC12MCTL0  =  (ADC12SREF_0 | ADC12INCH_1); // Sample X Channel
      
      while( CalibCounter < 50 )
      {
        P1OUT ^= BIT0; // Toggle LED1
        CalibCounter++;
        ADC12CTL0 |= (ADC12ENC | ADC12SC); // Start Sample
        
        while( ADC12CTL1 & BUSY ); // Wait for sample to be done
        
        Value += ADC12MEM0;
      }
    
      CalValue_X = (Value / 50); // Average of 50 samples
      ADC12CTL0 &= ~ADC12ENC;
      CalibCounter = 0; // Reset Counter
      Value = 0; // Reset Value
      ADC12MCTL0 = (ADC12SREF_0 | ADC12INCH_2); // Sample Y Channel
    
      while( CalibCounter < 50 )
      {
        P4OUT ^= BIT7; // Toggle LED2
        CalibCounter++;
        ADC12CTL0 |= (ADC12ENC | ADC12SC); // Start Sample
    
        while( ADC12CTL1 & BUSY ); // Wait for sample to be done
    
        Value += ADC12MEM0;
      }
    
      CalValue_Y = (Value / 50);
      ADC12CTL0 &= ~ADC12ENC;
      CalibCounter = 0; // Reset Counter
      Value = 0; // Reset Value
      ADC12MCTL0 = (ADC12SREF_0 | ADC12INCH_3);
    
      while( CalibCounter < 50 )
      {
        P4OUT ^= BIT7; // Toggle LED2
        P1OUT ^= BIT0; // Toggle LED1
        CalibCounter++;
        ADC12CTL0 |= (ADC12ENC | ADC12SC); // Start Sample
    
        while( ADC12CTL1 & BUSY ); // Wait for sample to be done
    
        Value += ADC12MEM0;
      }
    
      CalValue_Z = (Value / 50);
      ADC12MCTL0 &= ADC12ENC; // COMMENT: Should ENC be disabled? Then <ADC12MCTL0 &= ~ADC12ENC;>
      ADC12MCTL0 = (ADC12SREF_0 | ADC12INCH_1);
    
      __enable_interrupt();
    }
    
    
    
    void SetupACC( void )
    {
      // Configure GPIO
      ACC_PORT_SEL     |=  (ACC_X_PIN | ACC_Y_PIN | ACC_Z_PIN);
      ACC_PORT_DIR     &= ~(ACC_X_PIN | ACC_Y_PIN | ACC_Z_PIN);
      ACC_PWR_PORT_DIR |=  ACC_PWR_PIN;
      ACC_PWR_PORT_OUT |=  ACC_PWR_PIN;
    
      __delay_cycles( 200000 );
    
      ADC12CTL0  &= ~ADC12ENC;
      ADC12CTL0   = (ADC12ON | ADC12SHT0_5);
      ADC12CTL1   = (ADC12SHS_0 | ADC12SHP | ADC12CONSEQ_0 | ADC12SSEL_0);
      ADC12CTL2   = ADC12RES_2;
      ADC12MCTL0  = (ADC12SREF_0 | ADC12INCH_1);
      ADC12IV     = 0x00;
      ADC12IE    |= ADC12IE0;
    
      __enable_interrupt();
    }
    
    
    
    // ************************************************************************************
    // A long delay
    // ************************************************************************************
    
    void LongDelay( void )
    {
      __delay_cycles( 250000 );
    }
    
    
    
    // ************************************************************************************
    // ADC Interrupt Routine
    // ************************************************************************************
    
    #pragma vector = ADC12_VECTOR
    __interrupt void ADC12_ISR( void )
    {
      if( ADC_counter == 0 ) // X-axis
      {
        ADC12CTL1   &= ~ADC12ENC;
        ADC12MCTL0   =  (ADC12SREF_0 | ADC12INCH_1);
        ADCResult_X  =  ADC12MEM0;
        ADC_counter++;
        ADC12CTL0   |=  (ADC12ENC | ADC12SC);
      }
      else if( ADC_counter == 1 )
      {
        ADC12CTL1   &= ~ADC12ENC;
        ADC12MCTL0   =  (ADC12SREF_0 | ADC12INCH_2);
        ADCResult_Y  =  ADC12MEM0;
        ADC_counter++;
        ADC12CTL0   |=  (ADC12ENC | ADC12SC);
      }
      else
      {
        ADC12CTL1   &= ~ADC12ENC;
        ADC12MCTL0   =  (ADC12SREF_0 | ADC12INCH_3);
        ADCResult_Z  =  ADC12MEM0;
        ADC_counter++;
        ADC12CTL0   |=  (ADC12ENC | ADC12SC);
      }
    }
  • Some of the more obvious bugs:

    • ADC_counter is never reset.
    • ADCResult_* is not volatile.
    • The P6 registers are initialized multiple times.
    • LongDelay() is never called.

  • Thanks I did not catch those. It's still not working but at least those have been fixed.

**Attention** This is a public forum