cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F070 ADC Reference voltage problem

ASz
Associate II

Hi Everyone!

I have read a lot of topics, articles about the F070 ADC settings, calibration, etc., but I couldn't solve my issue. I'm using ADC with DMA right now, but the problem is the same with the interrupt and the polling method. In my code I'm using 3 channels (2 simple ADCs and the Vref). The result of the Vref channel is about 3.4V but I measure 3.31V with voltmeter (the other channels have this kind of problem too). Calibration is used by every 4th cycle and I have a 100nF capacitor between the Vcc and the GND and input filter as well.

I hope You can help.

Thanks in advance.

Andras

26 REPLIES 26
T J
Lead

I had the same problem and calibration fixed it with 'F072 and 'F091

are you driving any heavy loads from another pin ? this can affect the internal rail voltage.

ASz
Associate II

No.

Right now I'm using just the ADC pins, but my final project will use 2 PWMs and UART.

The calibration helped me a little bit, but I get a 50-70mV difference between the voltmeter's and ADC's value on the ADC pins too (not just Vref).

T J
Lead

50-70mV you have a problem.

when did you change the battery in the meter last ? <- this may be your issue, do you have another meter ?

every bit helps improve the figure...

a few years ago, I paid a little extra to get a really good Volt Meter. ita an AMProbe 37XR-A

nothing special, 4 digit and works very well.

anyhow I am reading 1-2mV difference on the analog input pins and 2-3-4mV on the Vdda calculation.

it moves around after the re-calibration takes place, cal factor 41-42...

what sampling speed are you running ?

the highest few are not good... I use the slowest speed.

I beef up the Caps all round.. so on Vdda 1u and 0.1u

lots of 0.1u on the board, if I have a switcher, I use some ferrites and inductors too..

do you have a switcher power supply ?, this can induce some DC offsets when the noise is rectified in the pin "input stage protection diodes", inside the processor..

just guessing of course...

ASz
Associate II

In my final setup the MCU is working from a battery with a voltage regulator but now I'm using a DC-DC regulator to get 3.3V.

Now I replaced that regulator with the battery (It is on 3.6V now) and the ADC says its 3.67V. I've made a value correction with a 70mV substraction and it's seems to be right (according to the other values).

I've tested with another multimeter but it says it's 3.57V so I'm going to get a better multimeter and after that I will check it again.

T J
Lead

after a power up, you can see the Calibration is off, then after the first cal, all the values seem to settle quite nicely.

(a 4 digit meter is much better than a 3 1/2 digit... )

ASz
Associate II

I have measured with another multimeter but the result is the same :\

My VCC and VCCA are common (without any cap), could it cause any problem?

I have included my main.c

ASz
Associate II

And this is my ADC settings in the CubeMX

ASz
Associate II
 
T J
Lead

this is not quite the same ...

your code is tiny,

I cant understand why my code is 2000 +lines for a short project,

yours is under 20...

void process_ADCcalibration(void) {
	
    //sprintf(string,"ADC Recal is Progressing\n\r");
    //puts (string);
 
	
// check DMA and ADC have stopped;
/*
		Calibration software procedure
		1. Ensure that ADEN=0
		2. Set ADCAL=1
		3. Wait until ADCAL=0
		4. The calibration factor can be read from bits 6:0 of ADC_DR.
				ADC Calibration code example
				// (1) Ensure that ADEN = 0 
				// (2) Clear ADEN 
				// (3) Launch the calibration by setting ADCAL
				// (4) Wait until ADCAL=0
*/
	if((ADC1->CR & ADC_CR_ADEN) != 0)				  // (1) 
    {
        ADC1->CR &= (uint32_t)(~ADC_CR_ADEN);    // (2)
    }
    ADC1->CR |= ADC_CR_ADCAL;    							// (3)
    while((ADC1->CR & ADC_CR_ADCAL) != 0)            // (4)
    {
        checkBackgroundServices();
        // For robust implementation, add here time-out management 
    }
    ADC_CalibrationFactor = (ADC1->DR);   	//& 0x7F);
    ADChasBeenRecalibrated = true;
    
    HAL_ADC_Start_DMA(&hadc, (uint32_t *)ADC_DMABuffer, ADC_ChannelCount);     //from main, adc-start
		
}