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.

MSP430G2553: MSP430G2553: ADC Configuration issue

Part Number: MSP430G2553


Hi,

I have referred to the sample programs to configure msp430g2553 ADC10 and deduced the following code for my application as below.

My goal is to sample a pressure sensor that has a maximum sampling frequency of 100Hz. 

1) However, I am unable to understand how to configure the sampling rate in MSP430. 

2) Also, I have enabled the interrupt but while debugging , the interrupt function is not requested and hence the LED on P2.1 is not turned on. 

I have measured the voltage at the P1.0 which is configured as my adc channel and it measure 0.5 volts. Converting that to a digital value I should be reading 256 . 

Kindly guide me on configuring the ADC10 and as to what corrections I should make.

Thank you,

int Value=0;
//
// uint16_t avg_adc = 0;

// Function prototypes
void adc_Setup();
void adc_Sam();
#pragma vector=ADC10_VECTOR

void main()
{

WDTCTL = WDTPW + WDTHOLD; // Stop WDT


BCSCTL1 = CALBC1_1MHZ; // Set DCO to 1 MHz
DCOCTL = CALDCO_1MHZ;
BCSCTL2|= (DIVS_3); //smclk=dc0=1 Mhz , SMCLK/8

P2DIR |= BIT1;
P2OUT &= ~BIT1;// configure P2.1 as output


// Fucntion call for adc_setup

while(1)
{
adc_Setup();
__delay_cycles(1000);
adc_Sam(); // Function call for adc_samp
// Add all the sampled data and divide by 10 to find average


// avg_adc = ((adc[0]+adc[1]+adc[2]+adc[3]+adc[4]+adc[5]+adc[6]+adc[7]+adc[8]+adc[9]) / 10);

}
}

// ADC10 interrupt service routine

__interrupt void ADC10_ISR(void)
{

__bic_SR_register_on_exit(CPUOFF); // Clear CPUOFF bit from 0(SR)
Value=ADC10MEM;
if (Value< 200) // ADC10MEM = A1 > 0.2V?
P2OUT &= ~BIT1; // Clear P2.0 LED off
else
P1OUT |= BIT1; // Set P2.0 LED on


}

// ADC set-up function
void adc_Setup()
{
ADC10CTL1 = CONSEQ_0 + INCH_0 + SHS0 + ADC10DIV_7 + ADC10SSEL_3; ; // Repeat single channel, A0 ,+ ADC10SC + CLK/5 + SMCLK
ADC10CTL0 = ADC10SHT_2 + ADC10ON + ADC10IE + REFON + ADC10SR + ~(REF2_5V)+SREF_0 ; // Sample & Hold Time + ADC10 ON + Interrupt Enable
ADC10DTC1 = 0x00; // 0 conversions
ADC10AE0 |= 0x01; // P1.0 ADC option select
__enable_interrupt();
__bis_SR_register(GIE);// Low Power Mode 0, ADC10_ISR
}

// ADC sample conversion function
void adc_Sam()
{
ADC10CTL0 &= ~ENC; // Disable Conversion
while (ADC10CTL1 & ADC10BUSY); // Wait if ADC10 busy
// Transfers data to next array (DTC auto increments address)
ADC10CTL0 |= ENC + ADC10SC; // Enable Conversion and conversion start
__bis_SR_register(GIE+CPUOFF);// Low Power Mode 0, ADC10_ISR

}

  • Part Number: MSP430G2553

    Hi,

    I have referred to the sample programs to configure msp430g2553 ADC10 and deduced the following code for my application as below.

    My goal is to sample a pressure sensor that has a maximum sampling frequency of 100Hz. 

    1) However, I am unable to understand how to configure the sampling rate in MSP430. 

    2) Also, I have enabled the interrupt but while debugging , the interrupt function is not requested and hence the LED on P2.1 is not turned on. 

    I have measured the voltage at the P1.0 which is configured as my adc channel and it measure 0.5 volts. Converting that to a digital value I should be reading 256 . 

    Kindly guide me on configuring the ADC10 and as to what corrections I should make.

    Thank you,

    int Value=0;
    //
    // uint16_t avg_adc = 0;

    // Function prototypes
    void adc_Setup();
    void adc_Sam();
    #pragma vector=ADC10_VECTOR

    void main()
    {

    WDTCTL = WDTPW + WDTHOLD; // Stop WDT


    BCSCTL1 = CALBC1_1MHZ; // Set DCO to 1 MHz
    DCOCTL = CALDCO_1MHZ;
    BCSCTL2|= (DIVS_3); //smclk=dc0=1 Mhz , SMCLK/8

    P2DIR |= BIT1;
    P2OUT &= ~BIT1;// configure P2.1 as output


    // Fucntion call for adc_setup

    while(1)
    {
    adc_Setup();
    __delay_cycles(1000);
    adc_Sam(); // Function call for adc_samp
    // Add all the sampled data and divide by 10 to find average


    // avg_adc = ((adc[0]+adc[1]+adc[2]+adc[3]+adc[4]+adc[5]+adc[6]+adc[7]+adc[8]+adc[9]) / 10);

    }
    }

    // ADC10 interrupt service routine

    __interrupt void ADC10_ISR(void)
    {

    __bic_SR_register_on_exit(CPUOFF); // Clear CPUOFF bit from 0(SR)
    Value=ADC10MEM;
    if (Value< 200) // ADC10MEM = A1 > 0.2V?
    P2OUT &= ~BIT1; // Clear P2.0 LED off
    else
    P1OUT |= BIT1; // Set P2.0 LED on


    }

    // ADC set-up function
    void adc_Setup()
    {
    ADC10CTL1 = CONSEQ_0 + INCH_0 + SHS0 + ADC10DIV_7 + ADC10SSEL_3; ; // Repeat single channel, A0 ,+ ADC10SC + CLK/5 + SMCLK
    ADC10CTL0 = ADC10SHT_2 + ADC10ON + ADC10IE + REFON + ADC10SR + ~(REF2_5V)+SREF_0 ; // Sample & Hold Time + ADC10 ON + Interrupt Enable
    ADC10DTC1 = 0x00; // 0 conversions
    ADC10AE0 |= 0x01; // P1.0 ADC option select
    __enable_interrupt();
    __bis_SR_register(GIE);// Low Power Mode 0, ADC10_ISR
    }

    // ADC sample conversion function
    void adc_Sam()
    {
    ADC10CTL0 &= ~ENC; // Disable Conversion
    while (ADC10CTL1 & ADC10BUSY); // Wait if ADC10 busy
    // Transfers data to next array (DTC auto increments address)
    ADC10CTL0 |= ENC + ADC10SC; // Enable Conversion and conversion start
    __bis_SR_register(GIE+CPUOFF);// Low Power Mode 0, ADC10_ISR

    }

  • What value are you getting in ADC10MEM?

    > ADC10CTL1 = CONSEQ_0 + INCH_0 + SHS0 + ADC10DIV_7 + ADC10SSEL_3; ;

    Be careful here: SHS0 sets SHS=1 (TA0.1 trigger). I suspect you wanted SHS_0 to set SHS=0.

    > ADC10CTL0 = ADC10SHT_2 + ADC10ON + ADC10IE + REFON + ADC10SR + ~(REF2_5V)+SREF_0 ;

    "~(REF2_5V)" will cause all sorts of trouble. If you want to set REF2_5V=0, you can just omit it, or (what I often do) use "(0*REF2_5V)".

    SREF_0 uses Vcc/Vss as the reference, so I'm not quite sure why you're doing anything with the 1.5/2.5V reference.

  • Hi,

    ADC10MEM has 0 in it. 

    I have corrected the SHS_0 . Thank you for pointing it out. 

    I am trying to  sample the output of a pressure sensor . The output of sensor range lies in between 0.5 V to 1.5V. With respect to that , should my SREF be SREF_0 or SREF_1  ?

    Thank you 

  • I suggest SREF_1. If you can, you should use a reference, rather than Vcc, since Vcc tends to be noisier. This applies to ADCs in general, not just on the MSP430.

    You could probably use the reference at 1.5V, which would give you more resolution. If you think the sensor will sometimes exceed 1.5V, you might want to the reference at 2.5V. Exceeding the reference voltage won't hurt anything, you'll just get boring results.

  • Hi Bruce, 

    Thank you very much for the explanation. SREF_1 and SHS_0 worked and solved the issue for me. 

**Attention** This is a public forum