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.

CC2540 ADC conversion sequence

Other Parts Discussed in Thread: CC2540

Hi everyone, I am trying to sample 2 single-ended channel single with CC2540. Then I treated it as a conversion sequence. But there is a question confused me,  that is how to read each channle's result.  

The EOC flag in ADCCON1  means the end of the one channle's conversion or the end of the sequence's ( two channles) conversion.

The part of code as follows. 

while (!(ADCCON1 & 0x80)); 

if (ADCCON2 & 0x0F == 0x01)               //to read AN0 result
{
adc_v0 = (int16) (ADCL);
adc_v0 |= (int16) (ADCH << 8); 
}

while (!(ADCCON1 & 0x80));

if (ADCCON2 & 0x0F == 0x02) // to read AN1 result
{
adc_v2 = (int16) (ADCL);
adc_v2 |= (int16) (ADCH << 8);

}

Is this right ? 

When using sequence conversion, it must  be using DMA way to get result ?

Thanks a lot!

BR,

Key

  • Checking ADCCON2[3:0] will only tell you which channel the conversion is currently at, not which is currently done.

    It seems you will miss the first read-out of channel 1 and might end up with swapped storage of the data.

    Using DMA is the cleanest way to do this, optionally you can skip the if() checking of channels and disable interrupts while doing measurements to ensure you read out the correct channel.

    Regards,
    Svend

  • Hi , Svend, thanks for your answer.

    The EOC flag in ADCCON1  means the end of the one channle's conversion or  the end of the sequence's ( two channles) conversion

    When the ADCCON2.SCH bits are read, they indicate the channel on which conversion is ongoing. The
    results in ADCL and ADCH normally apply to the previous conversion. If the conversion sequence has
    ended, ADCCON2.SCH has a value of one more than the last channel number.

    The result should be read  like this ?

    while (!(ADCCON1 & 0x80));

    if (ADCCON2 & 0x0F == 0x01) //AN0 result
    {
    adc_v0 = (int16) (ADCL);
    adc_v0 |= (int16) (ADCH << 8);
    }
    else if (ADCCON2 & 0x0F == 0x02) //AN1 result
    adc_v1 = (int16) (ADCL);
    adc_v1 |= (int16) (ADCH << 8);
    }

    while (!(ADCCON1 & 0x80));

    if (ADCCON2 & 0x0F == 0x02) //AN1 result
    {
    adc_v2 = (int16) (ADCL);
    adc_v2 |= (int16) (ADCH << 8);

    }
    else if (ADCCON2 & 0x0F == 0x01) //AN0 result
    {
    adc_v3 = (int16) (ADCL);
    adc_v3 |= (int16) (ADCH << 8);
    adc =  (uint32)adc_v1 << 16 | adc_v3;
    }

    adc = (uint32)adc_v2 << 16 | adc_v0;

    }

    return adc;

    Using DMA is  a good way. But i want to using ADC triggered by a timer (timer1 channle compare event), not the full speed conversion.  

    ADCCON1[5:4] need to select 10 as timer 1 channel 0 compare event.

    Then initial timer1, in this step, it should enable timer1 interrupt , if so, and what should be handle in the ISR ?

    The question is some more .

    Thank you for your patient reading.

    BR,

    Key

     

  • You don't need to set up interrupts to the CPU. The timer 1 event goes directly to the ADC.

    Have a look at for example the following thread for an example:

    http://e2e.ti.com/support/low_power_rf/f/538/p/334955/1168769.aspx#1168769

    Regards,
    Svend

  • Thank you so much, Svend ! That's really helpful for me. I am trying to slove it.

    Thanks !

    BR,

    Key