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.

read the battery with ADC of CC2530

Other Parts Discussed in Thread: Z-STACK, TIMAC, CC2530

Hello everybody,

I'am trying to use the ADC for reading the voltage of the battery.

But with some cards it's working, and with other cards it's not working.

 

for this I use a function find in a project of TI(but I don't remember its name):

#define HAL_ADC_REF_125V    0x00    /* Internal 1.25V Reference */
#define HAL_ADC_DEC_064     0x00    /* Decimate by 64 : 8-bit resolution */
#define HAL_ADC_DEC_128     0x10    /* Decimate by 128 : 10-bit resolution */
#define HAL_ADC_DEC_512     0x30    /* Decimate by 512 : 14-bit resolution */
#define HAL_ADC_CHN_VDD3    0x0f    /* Input channel: VDD/3 */
#define HAL_ADC_CHN_TEMP    0x0e    /* Temperature sensor */

uint16 Get_Val_Battery(void)
{
uint16 value_bat;
  /* Clear ADC interrupt flag */
  ADCIF = 0;
  ADCCON3 = (HAL_ADC_REF_125V| HAL_ADC_DEC_128 | HAL_ADC_CHN_VDD3);
  /* Wait for the conversion to finish */
  while ( !ADCIF );
  /* Get the result */
  value_bat = ADCL;
  value_bat |= ((uint16) ADCH) << 8;
  i++;
  /*
  * value now contains measurement of Vdd/3
  * 0 indicates 0V and 32767 indicates 1.25V
  * voltage = (value*3*1.25)/32767 volts
  * we will multiply by this by 10 to allow units of 0.1 volts
  */
  value_bat = value_bat >> 6; // divide first by 2^6
  value_bat = (uint16)(value_bat * 37.5);
  value_bat = value_bat >> 9; // ...and later by 2^9...to prevent overflow during multiplication
  return value_bat;
}

 

*The ref is the internal ref, so 1.25V (or 1.15V, I'am not certain)

*the resolution is 9Bits

*I'am measuring the VDD/3

With this function the value_bat is more or less 32170 before the calculation of the voltage. My battery is 3V.

 

Do you have an idea?

 

thank you!

 

 

  • Hi Guitou,

     

    You haven't mentioned if you developing a program from a scratch or may be you are using Z-Stack,

    or TiMAC? For Z-Stack and TIMAC you have an API for ADC, read HAL_API.pdf document, and use

    the API.

    I'm also recommend you to read this document. You'll probably find it useful.

    One more thing, reference voltage of ADC in cc253x SoC is 1.15V (look at the datasheet).

     

    Br,

    Igor

  • I am programming from scratch.

    but the adc it's working for an other inputs, but with the VDD/3 it's doesnt work.

     

    I copy the code of the PDF and its measure and calculate the same value than my code!

    I don't understand why...

  •  

    Hi Guitou,

     

    Try to do the following:

    1. Define these constants:

      #define HAL_ADC_EOC 0x80 // End of Conversion bit
      #define HAL_ADC_START 0x40 // Starts Conversion
      #define HAL_ADC_RESOLUTION_8 0x01
      #define HAL_ADC_RESOLUTION_10 0x02
      #define HAL_ADC_RESOLUTION_12 0x03
      #define HAL_ADC_RESOLUTION_14 0x04
      #define HAL_ADC_CHN_VDD3 0x0f    // VDD/3
      #define HAL_ADC_REF_125V 0x00    // Internal Reference (1.15V for CC2530)

       
    2. call uint16 sampledVoltage = adcRead( HAL_ADC_CHN_VDD3, HAL_ADC_RESOLUTION_12 );
       
    3. Write down the definition of adcRead(). This is actually the halAdcRead function from Z-Stack hal.c module, slightly
      changed 
      and stripped of unnecessary (for you) parts, so a big thanks goes to guys initially who wrote this function:

    uint16 adcRead (uint8 channel, uint8 resolution)

    {

    int16  reading = 0;

    uint8   i, resbits;

    uint8  adcChannel = 1;


    if (channel < 8)

    for (i=0; i < channel; i++)

    adcChannel <<= 1;


    /* Enable channel */

    ADCCFG |= adcChannel;


    /* Convert resolution to decimation rate */

    switch (resolution) {

    case HAL_ADC_RESOLUTION_8:

    resbits = HAL_ADC_DEC_064;

    break;


    case HAL_ADC_RESOLUTION_10:

    resbits = HAL_ADC_DEC_128;

    break;


    case HAL_ADC_RESOLUTION_12:

    resbits = HAL_ADC_DEC_256;

    break;


    case HAL_ADC_RESOLUTION_14:

    default:

    resbits = HAL_ADC_DEC_512;

    break;

    }


    /* writing to this register starts the extra conversion */

    ADCCON3 = channel | resbits | HAL_ADC_REF_125V;


    /* Wait for the conversion to be done */

    while (!(ADCCON1 & HAL_ADC_EOC));


    /* Disable channel after done conversion */

    ADCCFG &= (adcChannel ^ 0xFF);


    /* Read the result */

    reading = (int16) (ADCL);

    reading |= (int16) (ADCH << 8);


    /* Treat small negative as 0 */

    if (reading < 0)

    reading = 0;


    switch (resolution) {

    case HAL_ADC_RESOLUTION_8:

    reading >>= 8;

    break;


    case HAL_ADC_RESOLUTION_10:

    reading >>= 6;

    break;


    case HAL_ADC_RESOLUTION_12:

    reading >>= 4;

    break;


    case HAL_ADC_RESOLUTION_14:

    default:

    reading >>= 2;

    break;

    }

    return ((uint16)reading);

    }

     

    Tell me if it works.

     

    Br,

    Igor

  • hello,

     

     

     

    Thank you for you quick answer.

    In fact, I now try 3 different methods and all of them give me the same result.

    It's the intepretation of these results which was wrong! Sorry for that!

     

    Bye

     

  • Hi Igor.

    I read the codes you provided. I though ADC can only measure the voltage smaller than the reference voltage.

    Generally, the voltage of battery is higher than 1.15V or 1.25V. Therefore, how does your code work?

    BR,

    Jiaying

  • Hi Jiaying Please read the comment about the definition of HAL_ADC_CHN_VDDS, which is #define HAL_ADC_CHN_VDD3 0x0f /* Input channel: VDD/3 */. This makes you can measure voltage up to 1.15x3=3.45.

  • Hi,

    First of all you should set ADC reference Internal Reference (1.15V for CC2530/1, 1.24 for 2540/1)

    HalAdcSetReference(HAL_ADC_REF_125V);

    Then calling the HalAdcRead() function with HAL_ADC_CHN_VDD3 should give you the right result.

    Where HAL_ADC_CHN_VDD3 is the battery voltage divided by 3.

    uint16 tmp_bat_sample = HalAdcRead(HAL_ADC_CHN_VDD3, HAL_ADC_RESOLUTION_12);

  • HI YiKai.

    Thank you very much. I did get the voltage value.

    Best Regards,

    Jiaying

  • Hi Igor.

    Thank you very much.

    BR,

    Jiaying

  • Hi , Jiaying Song !

    Sorry to bother you.

    If you use the following code to get the voltage , how do you see the value of parameter tmp_bat_sample ??

    uint16 tmp_bat_sample = HalAdcRead(HAL_ADC_CHN_VDD3, HAL_ADC_RESOLUTION_12);


    Do you use "Debug without Downloading" in IAR ?? or other method ??


    Thanks ! 

    Martin.


  • Hi,,,I'm beginner at embedded programming and zigbee
    would you please tell me where is the right place for implementing this codes?