Skip to main content
ECost
Associate III
June 25, 2020
Question

ADC reading correction per VREF_INT

  • June 25, 2020
  • 2 replies
  • 2235 views

Using STM32F030 Discovery board.

I read the ADC channels including the internal temperature sensor and vrefint.

#define TEMP30_CAL_ADDR ((uint16_t*) ((uint32_t) 0x1FFFF7B8))
#define VREF_INT_ADDR ((uint16_t*) ((uint32_t) 0x1FFFF7BA))

The calibration value of the sensor I get from VREF_INT_ADDR is 0x05F4 or 1524. Calculating the value for a 3.30V value on VDDA I get 1.228V, which is consistent with internal reference voltage per data sheet.

When I read the vrefint channel I get a 0x06A2 or 1698. Calculating the VDDA considering 1.228V I get 2.96V, which is consistent with the VDD voltage I am reading on my Discovery board.

So, to correct the ADC readings taking VDDA into account I have to do the following calculation:

adc_val_corr = (*VREF_INT_ADDR * adc_val)/vrefint;

Is that correct? Am I missing something?

Thanks in advance.

This topic has been closed for replies.

2 replies

TDK
June 25, 2020

HAL provides some routines to help with this. It sounds like you're doing the same as the routines:

#define __LL_ADC_CALC_DATA_TO_VOLTAGE(__VREFANALOG_VOLTAGE__,\
 __ADC_DATA__,\
 __ADC_RESOLUTION__) \
 ((__ADC_DATA__) * (__VREFANALOG_VOLTAGE__) \
 / __LL_ADC_DIGITAL_SCALE(__ADC_RESOLUTION__) \
 )
 
#define __LL_ADC_CALC_VREFANALOG_VOLTAGE(__VREFINT_ADC_DATA__,\
 __ADC_RESOLUTION__) \
 (((uint32_t)(*VREFINT_CAL_ADDR) * VREFINT_CAL_VREF) \
 / __LL_ADC_CONVERT_DATA_RESOLUTION((__VREFINT_ADC_DATA__), \
 (__ADC_RESOLUTION__), \
 LL_ADC_RESOLUTION_12B) \
 )

"If you feel a post has answered your question, please click ""Accept as Solution""."
waclawek.jan
Super User
June 25, 2020

As TDK said, the formula is correct, but the devil may be in details, e.g. rounding at division or overflow at multiplication.

[shameless self-advertisement] my take on the topic [/shameless self-advertisement]

JW