Reading internal temperature sensor STM32
Like PeterJ pointed out, the first flaw is that you have to set the ADC_CCR_TSVREFE bit and not reset it.

I've no idea how you set the sample and hold time, but I hope it is correct. It has to be at least 10 µs for an accurate measurement (datasheet section about temperature sensor).

Your next big flaw is in your thinking that the reference voltage is 1.21 V. That is the nominal value for the \$V_{refint}\$. This voltage is not the reference voltage for the ADC. The reference voltage is usually \$V_{DDA}\$ or a different externally supplied voltage on the \$V_{REF+}\$-pin. But it can't be higher than \$V_{DDA}\$ nor can it be lower than \$V_{DDA}\$-1.2 V.

With your conversion result of 950, and taking 3.3 V you would end up with 27.2 °C, which seems like a good start. If you have 3 V it'd be -0.6 °C, which also seems okay.

Why do I consider -0.6 °C a good value? Because calculation using the average values is crap.

I don't know why, but STM doesn't promote their calibrated values much. Every device has two ADC raw values taken at 30 °C and 110 °C at 3.3 V stored internally. Using those values, you end up with more reasonable temperature values without performing calibration.



Something along these lines should do:

// see datasheet for position of the calibration values, this is for STM32F429
const uint16_t* const ADC_TEMP_3V3_30C =  reinterpret_cast&lt;uint16_t*&gt;(0x1FFF7A2C);
const uint16_t* const ADC_TEMP_3V3_110C =  reinterpret_cast&lt;uint16_t*&gt;(0x1FFF7A2E);
const float CALIBRATION_REFERENCE_VOLTAGE = 3.3F;

const float REFERENCE_VOLTAGE = 3.0F; // supplied with Vref+ or VDDA

// scale constants to current reference voltage
float adcCalTemp30C = static_cast&lt;float&gt;(*ADC_TEMP_3V3_30C) * (REFERENCE_VOLTAGE/CALIBRATION_REFERENCE_VOLTAGE);
float adcCalTemp110C = static_cast&lt;float&gt;(*ADC_TEMP_3V3_110C) * (REFERENCE_VOLTAGE/CALIBRATION_REFERENCE_VOLTAGE);

uint16_t adcTempValue = SAMPLED VALUE;

float temperature = (static_cast&lt;float&gt;(adcTempValue) - adcCalTemp30C)/(adcCalTemp110C - adcCalTemp30C) * (110.0F - 30.0F) + 30.0F;


I'm used to C++, so maybe not your coding style, but that shouldn't be a big problem.