Skip to main content
Piotr1
Associate II
January 20, 2020
Solved

STM32L0 incorrect reading from the internal temperature sensor

  • January 20, 2020
  • 4 replies
  • 2476 views

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:

0690X00000BwBxnQAF.png

This topic has been closed for replies.
Best answer by waclawek.jan

You are supposed to run ADC calibration (see Calibration (ADCAL) subchapter in ADC chapter) before using the ADC.

How does VREFINT_CAL compare to measured value of VREFINT on the same chip?

  

JW

4 replies

waclawek.jan
waclawek.janBest answer
Super User
January 20, 2020

You are supposed to run ADC calibration (see Calibration (ADCAL) subchapter in ADC chapter) before using the ADC.

How does VREFINT_CAL compare to measured value of VREFINT on the same chip?

  

JW

Piotr1
Piotr1Author
Associate II
January 20, 2020

As far as I understand, the manufacturer checked the ADC reading at VREF = 3V (VDD_CALIB) at 30C and 130C and stored it in FLASH memory. This allows me to calibrate the temperature sensor. If I use VREF = 3.3V (VDD_APPLI) the ADC reading should be smaller at the same temperature (for 3.0V and 30C the manufacturer wrote the value 657, so for 3.3V I should have for this temperature proportionally about 597).

Besides, the code that calculates the temperature is taken from Reference Manual from "Code examples" section, so I don't expect that there would be such a big error.

waclawek.jan
Super User
January 20, 2020

No, sorry, my original post was a mistake (I've just worked with an externally connected thermistor and confused things, my bad), I corrected it.

JW

Piotr1
Piotr1Author
Associate II
January 20, 2020

Thank you very much. I didn't expected it to be enough to just calibrate the ADC. Now the result is as expected (T = 30C).