2020-06-25 04:30 AM
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.
2020-06-25 06:52 AM
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) \
)
2020-06-25 12:00 PM
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