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.

CCS/MSP430FR2311: ADC reading only one of channels A3 (P1.3 OA0O) and A0 (P1.0), single conversion mode

Part Number: MSP430FR2311
Other Parts Discussed in Thread: LMT86

Tool/software: Code Composer Studio

Hello all,

I'm trying to read two channels (one after another) in single channel mode (I don't need to convert all of them at once). Problem is, it seems that only one channel is read (the one that starts first), and if I insert 3V3 on it, the reading is  around 2045. Say, if I start conversion on channel A0 first, only A0 will work until the end.

I'm configuring the ADC this way:

void configADC(void)
{
    // Configure ADC A0 pin
    P1SEL0 |= BIT0;
    P1SEL1 |= BIT0;

    // Configure ADC10
    ADCCTL0 &= ~ADCENC;                       // Disable ADC
    ADCCTL0 = ADCSHT_2 | ADCON;               // ADCON, S&H=16 ADC clks
    ADCCTL1 = ADCSHP | ADCCONSEQ_0;           // ADCCLK = MODOSC; sampling timer
    ADCCTL2 = ADCRES;                         // 10-bit conversion results
    ADCIE = ADCIE0;                           // Enable ADC conv complete interrupt
}

And I'm trying to read it this way:

#define A3 true
#define A0 false
uint16_t g_adcResult

uint16_t analogRead(bool channel)
{
    if(channel)
        ADCMCTL0 = ADCINCH_3 | ADCSREF_0;         // A3 ADC input select = OA output Vref = DVCC

    else
        ADCMCTL0 = ADCINCH_0 | ADCSREF_0;         // A0 ADC input select Vref = DVCC

    ADCCTL0 |= ADCENC | ADCSC;          // Sampling and conversion start

    __bis_SR_register(LPM0_bits); // Enter LPM0, ADC_ISR will force exit

    return g_adcResult;
}

void main(void)
{
    uint16_t adcTempTerm = 0;

    //some code...

    adcTempTerm = analogRead(A0) + analogRead(A3);
}

The ADC ISR:

#pragma vector=ADC_VECTOR
__interrupt void ADC_ISR(void)
{
    switch(__even_in_range(ADCIV, ADCIV_ADCIFG))
    {
    case ADCIV_NONE:
        break;

    case ADCIV_ADCOVIFG:
        break;

    case ADCIV_ADCTOVIFG:
        break;

    case ADCIV_ADCHIIFG:
        break;

    case ADCIV_ADCLOIFG:
        break;

    case ADCIV_ADCINIFG:
        break;

    case ADCIV_ADCIFG:

        g_adcResult = ADCMEM0;

        __bic_SR_register_on_exit(LPM0_bits);

        break;

    default:
        break;
    }
}

I'm facing difficulties trying to search information regarding how to properly setup single conversions. Is there a way to achieve what I'm trying to do? Please note that my current program has only 48 bytes of memory left.

  • Per SLAU445G Figure 20-23, ADCINCH can only be changed when ADCENC=0, but ENC is still 1 when you try to switch channels. You need to clear it yourself (a single instruction as it happens).

    Also, I see where you give A0 (P1.0) to the ADC via PSELx, but I don't see that being done for A3 (P1.3). That can be done in the same line/instruction.

    As to your funny reading: Are you using a Launchpad? If so, did you remove the jumpers on J10 (P1.0) and J8 (P1.3)?
  • Hmm, somehow missed that. Reviewing the SLAU445G and the various ADC examples, it seems that the examples sets the bit multiple times without really needing it.

    It now reads properly, after adding ADCCTL0 &= ~ADCENC into my code.

    uint16_t analogRead(bool channel)
    {
        ADCCTL0 &= ~ADCENC;
    
        if(channel)
            ADCMCTL0 = ADCOA;         // A3 ADC input select = OA output Vref = DVCC
    
        else
            ADCMCTL0 = ADCTS;         // A0 ADC input select = OA output Vref = DVCC
    
        ADCCTL0 |= ADCENC | ADCSC;          // Sampling and conversion start
    
        __bis_SR_register(LPM0_bits); // Enter LPM4, ADC_ISR will force exit
    
        return g_adcResult;
    }

    Bruce McKenney47378 said:
    Also, I see where you give A0 (P1.0) to the ADC via PSELx, but I don't see that being done for A3 (P1.3). That can be done in the same line/instruction.

    From the datasheet, the PSELx configures both A3 and the OA0O, so I've channel A3 set when I configured the opamp. Strange for me, but it seems that the pin supports "dual" function.

    Bruce McKenney47378 said:
    As to your funny reading: Are you using a Launchpad? If so, did you remove the jumpers on J10 (P1.0) and J8 (P1.3)?

    I'm using a MSP430FR2311 16-pin PW package, programmed by a 'FR5994 LP. The "standalone" version is so much cheaper. It's kinda sad that TI doesn't make them with PDIP packages...

    I'm trying to implement some electronic circuit into a electric oven. The one I have is drived by rheostat, mechanical timers...so I'm using this MSP, a 2004 LCD module, LMT86 and thermocouple (type K) to improve it.

    Thanks again for your help.

**Attention** This is a public forum