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;
  • 1
    \$\begingroup\$ So, what is your question? \$\endgroup\$ – 12Lappie Dec 20 '16 at 15:19
  • 1
    \$\begingroup\$ Why are you using names like BIT23?! \$\endgroup\$ – JimmyB Dec 20 '16 at 16:21
  • \$\begingroup\$ Did you "Select an appropriate sampling time specified in the device datasheet" and "Set the TSEN bit in the ADC_CCR register to wake up the temperature sensor [...] and wait for its stabilization time"? \$\endgroup\$ – JimmyB Dec 20 '16 at 16:29

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.

| improve this answer | |

Thank you for your help. In the end it was a timing issue - sampling time in ADC_SMPR was too short and also at power on I did not wait long enough for the temperature sensor to stabilize. It works fine now.

| improve this answer | |
  • 3
    \$\begingroup\$ Please add the value of the correct sampling time and delay after power on into your answer. \$\endgroup\$ – Bence Kaulics Dec 22 '16 at 7:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.