2018-06-19 05:13 AM
Hello everyone,
I'm currently trying to get as accurate ADC values as possible from a STM32F072. I'm using the NUCLEO-F072RB and wanted to use the internal stored reference voltage value for calibration. But I'm already off when I use this to calculate my actual VDDA for further ADC measurement. I double checked all my voltages with a calibrated multimeter and oscilloscope directly on the pins and with smalles possible ground loops. There are no spikes/drops in the voltage due to the ADC measurement and the ripple and noise is at around 5 mVpp. I also added 2x 10 nF and 1x 10 uF to C30 (100 nF) on AVDD on the nucleo. I tried all sampling times for the ADC without any change in the results and of course use 12-Bit. I do not want to read the value of the internal Vref-Voltage as it is not accurate (min 1.2V, typ 1.23V, max 1.25V).
So even after taking care of any possible error sources I'm getting a wrong value for my calculated AVDD voltage. I measured this with two multimeters to be 3.310V at 25�C. The calculated value from the STM32 is ~3.296 V, which is 14 mV off. This might be too much for measurements of voltages after a voltage divider, even when considering the 1% tolerance of the resistors. I read about a accuracy of ~1 mV (without voltage divider), so I'm curious how to achieve this when the reference value is not accurate.
This are parts of the code from the used test program:
// ADC self calibration, has to be done before any ADC Start/Enable
while(HAL_ADCEx_Calibration_Start(&hadc) != HAL_OK);// values for calculation of actually VDDA-supply and reference voltagevolatile uint32_t VREFINT_CAL, VREF_3V3 = 330000;const uint16_t *p = (uint16_t *)0x1FFFF7BA; // 2 Byte at this address is VRefInt @3.3V/30�CVREFINT_CAL = *p; // read the value at pointer address// Start ADC with DMA supportvolatile uint16_t adc_value[4] = {0, 0, 0, 0};HAL_ADC_Start_DMA(&hadc, (uint32_t*)adc_value, 4); while (1){ //toggle LED HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin); HAL_Delay(50); // calculate 3.3 V supply voltage with the factory stored VREFINT_CAL value // adc_value[2] contains the raw ADC_IN17 value of the internal voltage reference (~1530) VREF_3V3 = (330000 * VREFINT_CAL) / adc_value[2]; // VREFINT_CAL = 1529 // adc_value[2] = 1530 // VREF_3V3 = ~329568 (~3.29568 V calculated)}#accuracy #nucleo-f072rb #adc #calibration #stm32f0 #internal-voltage-reference2019-02-01 05:14 AM
First you have to de-initialize the ADC, setup a structure to pass to the ADC when initializing it, initialize it and then calibrate it. I don't know why but the de-initialization is important...just make sure you reinitialize it prior to attempting to calibrate it.
2019-02-03 05:34 PM
I have a precision external reference.
4/4096 * 3.3 = 3.2 mV not 14 mV, so my performance is no good.
The stm32f072 doesn't have a Vrefin I believe?
Yeah, I may need to get a better external ADC.