I am using the ADC on an STM32F030F4P6 to read a battery voltage, usually between 4.2 and 3.5 V. The resistor divider is designed to reduce the voltage so that 4.2 V input becomes ~3.1 V at the ADC and 3.5 V becomes ~2.6 V. The analog reference voltage is 3.3 V.
I'm getting a strange, stable, reproducible result as shown in this graph:
I've verified that the voltage at the ADC pin is as expected (i.e. the resistor divider is working as intended).
The ADC calibration process is being run at boot as per the datasheet:
LL_ADC_Disable(ADC1);
while (LL_ADC_IsEnabled(ADC1)) {
}
LL_ADC_REG_SetDMATransfer(ADC1, LL_ADC_REG_DMA_TRANSFER_NONE);
LL_ADC_StartCalibration(ADC1);
while (LL_ADC_IsCalibrationOnGoing(ADC1)) {
}
LL_ADC_REG_StopConversion(ADC1);
WRITE_REG(ADC1->ISR, LL_ADC_FLAG_EOC | LL_ADC_FLAG_EOS | LL_ADC_FLAG_OVR | LL_ADC_FLAG_ADRDY | LL_ADC_FLAG_AWD1);
LL_ADC_EnableIT_EOS(ADC1);
LL_ADC_Enable(ADC1);
// wait for VREF to stabilize
for (volatile uint32 i = LL_ADC_DELAY_VREFINT_STAB_US * (SystemCoreClock / 1000000U); i != 0; i--) {
}
// wait for adc ready
while (!LL_ADC_IsActiveFlag_ADRDY(ADC1)) {
}
I've taken multiple readings and the results are always the same. I'm using 12 bit resolution and sampling for 13.5 cycles. The results are the same if I sample for longer (e.g. 239.5 cycles).
Is this expected? I understand that the ADC is non-linear to some extent and that the error is dependent on where in the capacitor ladder the voltage is. Is this what I'm seeing here?
Or is the 1 nF capacitor interfering in some way? I added it to reduce the induced noise on the power rail when the ADC was active.
[Edit]
So, the datasheet says N/A for the impedance when using 239.5 cycles but... I suspect 3 MΩ is still too much. One thing I'm considering is using a really large capacitor, 1 uF, and just sampling the voltage very occasionally