Electronic – ADC Calibration – Vdd calculation

adcstm32

In documents and lots of online sources there is a formula as follows,

$$ Vdd = 3.3V * \frac{VREFINT_{CAL}}{VREFINT_{DATA}}$$

But I cannot get why CAL value is in the numerator and RAW data is in the denominator. I have this logic in my mind,

In the factory, producers used a preknown/fixed 3.3 V as Vdd and then they get this reference CAL value from ADC. But in reality, my Vdd may be different because of non-idealities. So I read Vref_int channel via my ADC and it gives me RAW. I get the CAL value by reading the device memory address provided by manufacturer. ADC reading and voltage level has a direct relationship. So, I conclude that;

3.3 V ------> CAL(from device memory)

x V ------> RAW(read from Vref_int)

Then, x * CAL = 3.3 * RAW

So, x = 3.3 * RAW/CAL should be my formula to get my current Vdd value so that then I know that a maximum ADC reading (4095 for 12 bits reading for ex.) corresponds to x volts.

However, in the above formula it states that x = 3.3 * CAL/RAW.

Please help me with that, thanks.

My board is STM32F4-DISC.

——————– edit ————————————

With all my thanks to the ones who answered, I now understood(I hope) what is going on and want to explain here in detail.

First, what is what :

VREFINT_{CAL} or CAL : The ADC reading of the manufacturer from Vref_int when an exact 3.3V Vdda is used (unitless, 12 bits integer)

VREFINT_{DATA} or RAW : The ADC reading of the user from Vref_int when the Vdda is unknown (unitless, 12 bits integer)

V_{DDA} : Kind of the voltage base for our MCU, when you give a digital high output then it should be exactly equal to Vdda (unit = volts)

Now,

1- In the factory, the manifacturer gets the ADC conversion data from
the Vref_int channel and stores it into a memory location as a
12-bit integer. $$ \frac{{VREFINT_{voltage}}}{3.3(V_{DDA})}= \frac{{VREFINT_{CAL}(stored\,value\,,CAL)}}{4095} \quad (1)$$
The logic is simple here, 4095 for 3.3V and CAL for Vref_int.

2- When you want to calibrate your voltage level, since you don't know
your exact voltage base level, you read the Vref_int yourself and
get another ADC conversion value(RAW), let's call it $$VREFINT_{DATA}$$
Then $$ \frac{VREFINT_{voltage}}{V_{DDA}(unknown)}= \frac{{VREFINT_{DATA}(measurement\,of\,user\,,RAW)}}{4095} $$

Since $$VREFINT_{voltage}$$ is fixed, replace it with its equivalent from eqn. (1).

Then you can see that the equation yields to $$V_{DDA}(unknown) = \frac{3.3*CAL}{RAW}$$

Finally, you can use this Vdda value as your voltage reference(base) on your calculations.

This edit may include some mistakes, please let me know.

Best Answer

ADC reading and voltage level has a direct relationship.

The ADC reading on the VREFINT channel and VDDA have inverse relationship.

An ADC reading is the ratio of the measured voltage to VDDA, scaled up to 4095 (the maximum value that can be expressed on 12 bits). E.g. if you applied VDDA/3 to an ADC input, the result would be 4095/3=1365.

So, the conversion result, ADCx = 4095*VADCINx/VDDA

You cant't measure VDDA directly, because if you apply a voltage equal to VDDA to an ADC channel, the conversion result is always 4095.

VREFINT is a fixed voltage generated inside the MCU, around 1.2 volts. When you convert the VREFINT channel of the ADC, you get the ratio of this voltage to VDDA, i.e. 4095*VREFINT/VDDA. Note that VDDA is now in the denominator. If the supply voltage goes down, the conversion result goes up, and vice versa.

Because VREFINT is not an exact voltage source, they measure it in the manufacturing process, using a good stabilized 3.3V supply, and write the conversion result (VREFINTCAL) in the system memory area.

Now if you'd read the VREFINT channel, and got the exact same value that's stored in the system memory, it would mean that VDDA=3.3V, like in the factory calibration process. This is also what the formula in the question gives you when VREFINTCAL = VREFINTDATA.