STM32L0 incorrect reading from the internal temperature sensor
I'm having trouble reading the temperature, its values are incorrect. The temperature in the room is 22C and the temperature of the sensor shows 55C (selfheating and the measurement error cannot be that big). I have many times checked the correctness of the code, and I use the functions recommended by the manufacturer (Code examples from reference manual). I have no idea why it doesn't work.
Data:
STM32L0x1 family MCU
3.3V supply voltage
Clock frequency: 2.097MHz (MSI)
Problems I ruled out:
1) ADC sampling time too short (it should be longer than 10us and it is).
2) I tested the code on different MCUs of the same model, and also on other models of STM32L0x1 family.
3) VDD of the chip is 3.3V, not e.g. 3.0V, there is no mistake here.
4) The temperature is certainly not about 55C because I checked it with two independent methods (thermal camera and thermocouple) and certainly the housing temperature does not exceed 22C.
5) The board on which I test this circuit is well proven in other ADC applications and behaves flawlessly.
Below I paste the program code:
#include "stm32l0xx.h"
#define TEMP130_CAL_ADDR ((uint16_t*) ((uint32_t) 0x1FF8007E))
#define TEMP30_CAL_ADDR ((uint16_t*) ((uint32_t) 0x1FF8007A))
#define VDD_CALIB ((uint16_t) (300))
#define VDD_APPLI ((uint16_t) (330))
int32_t temperature_in_C;
uint16_t temperature_ADC_value;
int32_t temp130_cal_value;
int32_t temp30_cal_value;
int32_t ComputeTemperature(uint32_t measure)
{
int32_t temperature;
temperature = ((measure * VDD_APPLI / VDD_CALIB) - (int32_t) *TEMP30_CAL_ADDR );
temperature = temperature * (int32_t)(130 - 30);
temperature = temperature / (int32_t)(*TEMP130_CAL_ADDR - *TEMP30_CAL_ADDR);
temperature = temperature + 30;
return(temperature);
}
void ADC_Init()
{
RCC->APB2ENR |= RCC_APB2ENR_ADCEN; /* Enable ADC clock */
ADC1->CFGR2 |= ADC_CFGR2_CKMODE_0
| ADC_CFGR2_CKMODE_1; /* ADC Clock = PCLK (2.097MHz) */
ADC->CCR |= ADC_CCR_LFMEN; /* Enable if ADC Clock Freq < 3.5MHz */
ADC1->CFGR1 |= ADC_CFGR1_CONT; /* Continous conversions */
ADC1->CHSELR = ADC_CHSELR_CHSEL18; /* Channel 18 - Temperature sensor */
ADC1->SMPR |= ADC_SMPR_SMP; /* Sampling time - 160.5 ADC cycles */
ADC->CCR |= ADC_CCR_TSEN; /* Enable temperature sensor */
ADC1->ISR |= ADC_ISR_ADRDY; /* Clearing bit ADRDY (ADC ready) */
ADC1->CR |= ADC_CR_ADEN; /* Enable ADC */
while((ADC1->ISR & ADC_ISR_ADRDY) == 0) /* Wait for turn on */
;
ADC1->CR |= ADC_CR_ADSTART; /* Start */
}
int main(void)
{
ADC_Init();
while (1)
{
for(int i = 0; i < 10000; i++) /* Delay */
;
temperature_ADC_value = ADC1->DR; /* Debug */
temp130_cal_value = (int32_t)(*TEMP130_CAL_ADDR); /* Debug */
temp30_cal_value = (int32_t)(*TEMP30_CAL_ADDR); /* Debug */
temperature_in_C = ComputeTemperature(temperature_ADC_value);
}
return 0;
}Example from debugging in STM Studio:

