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.

Configuring cc2540 for battery reading

Other Parts Discussed in Thread: CC2540

I am programming the cc2540 in IAR with the latest BLE stack from TI.

I am trying to read the battery voltage using one of the analog pins and an internal reference.  I am interested in the raw adc value.  My attempt is summarized below and is based roughly on the example from http://e2e.ti.com/support/wireless_connectivity/f/538/t/72681.aspx?pi310978=3

1. Add 'HalAdcInit();' to the initialization function

2. Configure analog port for input

APCFG = 0x80; // Set HAL_ADC_CHANNEL_7 to input

3. Set internal reference and read analog value during periodic function

HalAdcSetReference( HAL_ADC_REF_125V );

uint8 adc = HalAdcRead ( HAL_ADC_CHANNEL_7, HAL_ADC_RESOLUTION_10); 

Using these four lines I get a value of approximately 0x50 for adc.  When the battery is read on a multimeter it reads 2.86V.  Furthermore, these readings do not align with the battservice.c description.

What do I need to modify to get better results or are my results just a different correct answer?

  • Hi,

    HalAdcRead returns 16 bit output but you are taking adc as 8 bit only. It may truncate most significant 8 bits.

    Try follow: 

    uint16 adc = HalAdcRead ( HAL_ADC_CHANNEL_7, HAL_ADC_RESOLUTION_10); 

    Now check the results if they are coming fine. 

  • Maulik, thank you for pointing out the the type difference in my code.  Using a uint16 consistently returns a value of 32778 which does not appear to have any relation to the 0x50 that shoving the uint8 into the message returned.

    A little more background, I am trying to fit the uint16 value into the AdvertData array for the BLE stack.  AdvertData is an array of uint8.  I have attempted to simply use adc (which should typecast to first byte) and (adc >> 8) to get me to the second byte.  Doing this has given me the 0x50 value still but only gives 0x00 for the second byte.  If adc is 32778, I would at least expect a non-zero response from the bitshift if the code was working.  Any recommendations for parsing the usint16 into two bytes for advertisement would be much appreciated.

    Along the same lines, which of these code lines actually tells the CC2540 to read the VDD on channel 7 referenced against 1.25V?  Do I need an external trace to connect it?

  • Hi,

    1. Regarding parsing of data. You can do as follow: 

        Use high and low variable inside an array. 

     uint8 high = (uint8) (adc >> 8);
     uint8 low  = (uint8) (adc & 0x00FF);

    2. uint8 adc = HalAdcRead ( HAL_ADC_CHANNEL_7, HAL_ADC_RESOLUTION_10); 

     This line reads data from ADC channel 7. Reference voltage should be 1.25V only. To understand you can take a look at battery service given in Profiles. 

      Check file at path : "Projects\ble\Profiles\Batt\battservice.c" In this file take a look at "battMeasure" function. You'll get more idea on how to measure battery. 

     

     

  • Maulik, thank you for pointing out the Channel_7 Problem.

    In Summary, to read the battery voltage on a CC2540 without using the full battservice functionality there are two sections of code to be added.

    1. In the init function : HalAdcInit();

    2. In a periodic event of some sort :

    HalAdcSetReference( HAL_ADC_REF_125V );//HAL_ADC_CHANNEL_7 125
    uint16 adc = HalAdcRead ( HAL_ADC_CHN_VDD3, HAL_ADC_RESOLUTION_10 );

    uint8 high = (uint8) (adc >> 8);
    uint8 low = (uint8) (adc & 0x00FF);

    Manipulating the result is explained well in the battservice.c source file in the battMeasure function..