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.

MSP430FR2433: Multiple ADC channel sampling

Part Number: MSP430FR2433

Hello,

I am new to MSP430 series micro-controller and I am playing around the ADC of MSP430FR2433 development kit.

I have tried the msp430fr243x_adc10_01.c example for single channel ADC sampling and it works great.

However, when I modify the example to sample multiple channel ADC (P1.2 P1.3). The result seems very unstable.

Any suggestions and advice are appreciated.

1. connect both to GND pin

I expected the result should be both 0 but sometimes the suddenly jumps to 243.

Here is the log.

254 3
"▒ 0 0

"▒0 0

"▒254 4
"▒0 0

"▒0 0

"▒254 3
"▒0 0

"▒0 0

"▒254 3
"▒0 0

"▒0 0

"▒254 3
"▒0 0

"▒0 0

"▒254 4
"▒0 0

"▒0 0

"▒254 3
"▒0 0

"▒0 0

"▒254 3

2. connect both to VCC(3V3) pin

I expected the result should be both near 255 but sometimes the suddenly jumps to 4.

Here is the log.

255 255
207 207
253 4

255 255
206 206
252 3

254 255
207 203
253 3

255 254
207 207
251 3

254 254
204 207
253 4

254 255
207 207
253 3

255 255
204 207

#include <msp430.h> 
#include <stdio.h>

unsigned char ADC_Result[2];                                    // 8-bit ADC conversion result array
int i;
void print_result_to_uart(void);

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

    P1DIR |= BIT0 | BIT1;              // P1.0 & P1.1 as LED
    P1OUT = 0x00;
    P1REN = 0x00;

    SYSCFG2 |= ADCPCTL2+ADCPCTL3;       // Select P1.2 & P1.3 A2 as ADC

    P1SEL1 &= ~(BIT4 | BIT5);       // USCI_A0 UART operation
    P1SEL0 |= BIT4 | BIT5;

    UCA0CTLW0 |= UCSWRST;           // Put USCI_A0 to software reset
    UCA0CTLW0 |= UCSSEL__SMCLK;     // Use SMCLK(1048576Hz) for baud rate calculation
    UCA0BRW = 9;                    // N = f/BR = 1048576/115200 = 9
    UCA0MCTLW = 0x0800;
    UCA0CTLW0 &= ~UCSWRST;          // Release USCI_A0 software reset

    PM5CTL0 &= ~LOCKLPM5;

    ADCCTL0 |= ADCSHT_2;                // 16 ADCCLK cycles
    ADCCTL0 |= ADCON;                   // ADC on
//    ADCCTL0 |= ADCMSC;                  // ADC multiple sample-and-conversion

    ADCCTL1 |= ADCSHP;                  // ADCCLK = MODOSC; sampling timer
    ADCCTL1 |= ADCCONSEQ_1;             // Repeat-sequence-of-channels

    ADCCTL2 |= ADCRES_0;                // Resolution 8-bit
    ADCMCTL0 |= ADCINCH_2+ADCINCH_3;    // A2 & A3 ADC input select; Vref=AVCC
    ADCIE |= ADCIE0;                    // Enable ADC conv complete interrupt
    __bis_SR_register(GIE);             // LPM0, ADC_ISR will force exit

    while(1)
    {
        i = 1;
        ADCCTL0 |= ADCENC | ADCSC;      // Sampling and conversion start
        while (i >= 0);
        print_result_to_uart();
        if (ADC_Result[0] < 0x7F)
            P1OUT &= ~BIT0;             // Clear P1.0 LED off
        else
            P1OUT |= BIT0;
        if (ADC_Result[1] < 0x7F)       // P1.3 ADC3 result
            P1OUT &= ~BIT1;             // Clear P1.1 LED off
        else
            P1OUT |= BIT1;
        __delay_cycles(1048576);
    }
}

void print_result_to_uart(void)
{
    char str[20];
    sprintf(str, "%d %d\r\n", ADC_Result[0], ADC_Result[1]);
    int j = 0;
    for (j = 0; j < sizeof(str); j++){
        UCA0TXBUF = str[j];
        __delay_cycles(100);
    }
}

#pragma vector=ADC_VECTOR
__interrupt void ADC_ISR(void)
{
    switch(__even_in_range(ADCIV,ADCIV_ADCIFG))
    {
        case ADCIV_ADCIFG:
            ADC_Result[i--] = ADCMEM0;
            if (i >= 0)
                ADCCTL0 |= ADCENC | ADCSC;
            break;
        default:
            break;
    }
}

  • >     ADCMCTL0 |= ADCINCH_2+ADCINCH_3;

    ADCINCH is a small integer, not a bit field. This sets ADCINCH=(2+3)=ADCINCH_5. In your context the best you can do is:

    >    ADCMCTL0 |= ADCINCH_3;  // Sample A3->A0

    ---------

    CONSEQ=1 always counts down from INCH to A0. To get two channels in the middle, you would either

    a) Read A3->A0 and throw away the A1 and A0 readings.

    b) Since you're doing the conversions one step at a time (MSC=0), you could read A3 and A2, then toggle ENC (=0 then =1) to stop the sequence. Then the next time you set ADCSC, it will start back at ADCINCH. [Ref User Guide (SLAU445I) Fig 21-13]

    ---------

    Unsolicited:

    >     ADCCTL2 |= ADCRES_0;                // Resolution 8-bit

    This doesn't do anything, since ADCRES_0==0. To get ADCRES=0 (since it's initially =1) try instead:

    >     ADCCTL2 &= ~ADCRES_3;                // Resolution 8-bit

  • Thank you so much for the reply. The program now works and your answer is neat and clean.

**Attention** This is a public forum