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.

ADC12 sequence then single

I'm running a sequence of conversions triggered by TmrA which throws the ADC interrupt.

I want to shut off the sequence and run a single conversion in the interrupt handler and then

re-enable the sequence. The code I have is shown below.  I can't get the single conversion to

work.  It appears to run but ADCMEM0 isn't getting updated.  Suggestions ?

void adcInit(void)

{

    ADC12CTL1 = ADC12SHP + ADC12SHS_1 + ADC12DIV_5 + ADC12SSEL_3 + ADC12CONSEQ_1;
    ADC12CTL2 = ADC12TCOFF + ADC12RES_2 + ADC12REFOUT;    // turn temp sensor off
                                                    // Resolution to 12-bit, refout on

    ADC12MCTL0 = ADC12INCH_3 + ADC12SREF_1;                // ref=2.5V, channel 0 = pressure C
    ADC12MCTL1 = ADC12INCH_2 + ADC12SREF_1;                // ref=2.5V, channel 1 = sigin
    ADC12MCTL2 = ADC12INCH_1 + ADC12SREF_1;                // ref=2.5V, channel 2 = pressure B
    ADC12MCTL3 = ADC12INCH_0 + ADC12SREF_1 + ADC12EOS ;    // ref=2.5V, channel 3 = pressure A
    ADC12IE = 0x08;

    ADC12CTL0 |= ADC12ENC;

}

#pragma vector=ADC12_VECTOR
__interrupt void ADC12ISR ()

{

    tempADC_0 = ADC12MEM0;
    tempADC_3 = ADC12MEM3;  // clear int flag


    P2OUT |= DebugPin;  // switch mux
    _delay_cycles(500);  // delay 32 uS to settle
    ADC12CTL1 &= ~ADC12CONSEQ_1; // + ~ADC12SHS_1;  // turn off sequence of conversions
    ADC12CTL0 &= ~(ADC12MSC + ADC12ENC + ADC12SC);
    ADC12CTL1 |= ADC12CSTARTADD_0;   // Use Mem0, ch2  for signal B
    ADC12CTL0 |= ADC12ENC + ADC12SC;
    while(ADC12CTL1 & ADC12BUSY);
    ADC12CTL0 &= ~(ADC12ENC + ADC12SC);
    ADC12CTL0 |= ADC12MSC;  // re-enable sequence
    ADC12CTL1 |= ADC12CONSEQ_1; // + ADC12SHS_1;

}

  • I fixed it, ADC12ENC has to be low before you change ADC12MSC

    ADC12CTL0 &= ~(ADC12ENC + ADC12SC);

    has to be before the settling delay.

  • When you get into the ISR for a completed sequence, the next sequence has already started. Clearing ADC12ENC interrupts this new sequence, but not instantly. You’ll need to wait until the ADC12 is no longer busy (especially if MCLK>ADCCLK). Then you can make the configuration changes and start a new (single) conversion.
    So yes, clearing ADC12ENC is the first thing to do.

    However, busy-waiting for a conversion to complete (or busy-waiting for anything) inside an ISR is a death sin. You should rather check the current state (doing sequence or single conversion) inside the ISR and exit it after starting the next action. You’ll return here when the next conversion/sequence is done. In the meantime the CPU can sleep or do something useful.

**Attention** This is a public forum