Electrical – STM32L011 temperature sensor – almost constant output

adcstm32temperature

I am trying to use the internal temperature sensor of STM32L011 (Nucleo-32 board), but I get almost a constant reading (ADC code) in the 100-120 (decimal) range that changes little to none with temperature (I've tried pressing a soldering iron against the chip and freezer spray). On the other hand – measurement of internal Vcc works fine.

My TS_CAL2 is 928 (decimal), though I am not using it yet for anything.

My code:

void adc_init(void){
RCC_APB2ENR |= BIT9; // Turn on ADC
ADC_CFGR2 = BIT31/*CKMODE1*/ | BIT30/*CKMODE0*/; //ADC clock is PCLK/1

ADC_CCR = BIT25/*LFMEN*/; //low frequency mode (ADC is clocked from APB 2MHz)
ADC_CCR |= BIT22/*VREFEN*/; //enable reference voltage

ADC_IER |= BIT11 /*EOCALIE*/ | BIT2 /*EOCIE*/; //enable interrupts for end of calibration and end of conversion
ISER = BIT12; //enable ADC interrupt vector in NVIC

ADC_CR = BIT31; //start ADC calibration
cpu_sleep(); //ISR should wake up the CPU when calibration is done
while ((ADC_CR & BIT31)); //wait for calibration complete (in case something else woke up the CPU)

ADC_CR |= BIT0; //enable ADC
}

uint32_t adc_get_temperature(void){
ADC_CCR |= BIT23/*TSEN*/; //enable internal temperature sensor
ADC_CCR |= BIT22/*VREFEN*/; //enable internal voltage reference
ADC_CHSELR = BIT18; //select channel 18 (internal voltage sensor)
ADC_CR |=  BIT2/*ADSTART*/; //trigger a conversion

cpu_sleep(); //ISR should wake up the CPU

while ( (ADC_CR & BIT2) ); //wait for end of conversion (in case something else woke up the CPU)
uint32_t conversion_result = ADC_DR;

return conversion_result;
}

Best Answer

I would recommend you to take a look at stm32 examples (STM32CubeL0):

They have example for how to read the internal temperature sensor. They are using HAL library but you can easily backtrace the code so that you undestand what registers that are being set and in what order.