STM32 gotchas
143. VREFINT and temperature calibration values not available in 'F1 and 'F2

The internal voltage reference VREFINT in STM32 provides a stable voltage, using which the absolute voltage of analog reference VREF+ (bonded to VDDA or even VDD in low-pin-count packages) can be determined. While VREFINT is quite stable across VDD and temperature variations, its absolute voltage has a certain spread across individual devices, given manufacturing tolerances. For example, the STM32L476 datasheet gives Internal reference voltage spread over the temperature range as max. 7.5mV, and from Average voltage coefficient of max. 1200ppm the the maximum spread over operating voltage range is around 2.5mV; however, the nominally 1.212V reference has range from min. 1.182V to 1.232V, i.e. 50mV. Other models/families may have different values, but the principle is the same and the ratios are very similar.

To compensate for this, for most STM32, the precise value of VREFINT is determined at manufacturing, in the form of ADC readout at given "standard" supply voltage and temperature; and this readout is stored at a predetermined address (usually called VREFINT_CAL and given in individual datasheets) in the system memory. This value can then be used to determine VREF+ voltage and thus all ADC readouts more precisely.

Similarly, the internal temperature sensor has a manufacturing spread, which is compensated by using two readouts - TS_CAL1 and TS_CAL2 - taken by manufacturer at "standard voltage" and two temperatures, again addresses and particular temperatures given in individual datasheets.

However, two of the oldest STM32 families - the 'F1 and 'F2 family - don't have these calibration values determined. Quite surprisingly, the 'L1 family does have them, even if it is an older family than the 'F2. For 'F2, this is another difference against 'F4 to be taken into account, should 'F2 be used as a "downgrade" for 'F4.

Even in families except 'F1 and 'F2, the lowest-end "value-line" models (principial numbering of which ends with 0) usually don't have all of these coefficients available, often the higher-temperature coefficient is missing.