Skip to main content
Tmizr.1
Associate
March 28, 2023
Question

STM32F411 - temperature sensor returning 0

  • March 28, 2023
  • 6 replies
  • 1974 views

Hi All , Im trying to read the temperature from the internal temperature sensor.

But everytime Im reading i recevied 0

Here is my code:

#define ADC1EN (1U<<8)

void temp_init()

{

// Configure ADC module ADC1_IN18 channel

// Enable Clock access

RCC->APB2ENR |= ADC1EN;

//10010 =18

ADC1->SQR3 |=(1U<<4);

ADC1->SQR3 |=(1U<<1);

//conversion length 1 channels

ADC1->SQR1 = 0x00;

// TEMP sensor enable

  ADC->CCR |=ADC_CCR_TSVREFE;

// Enable ADC module

ADC1->CR2 |=ADC_CR2_ADON;

}

void start_conversion()

{

// Enable continues conversion

ADC1->CR2 |= C2_CONT;

// Start ADC conversion

ADC1->CR2 |= C2_SWSTART;

}

uint32_t adc_read(void)

{

//Wait for conversion to complete

while(!(ADC1->SR & SR_EOC)){};

//Read ADC sampled value

return ADC1->DR;

}

from the main I just call the function every ~1 second

printf("Temp :%f \n\r",adc_read());

BTW i know that the printf value isnt yet the final temp value

Thanks ahead!

This topic has been closed for replies.

6 replies

waclawek.jan
Super User
March 28, 2023

In 'F407, temperature sensor is in ADC channel 16.

 [EDIT] Sorry, I made an error - you are using 'F411 rather than 'F407. I don't have 'F411 at hand at the moment. RM0383 is relatively messy when it comes to the temperature sensor; it appears it can be read from both CH16 and CH18 (with CH18 being shared with VBAT). Try perhaps both. [/EDIT]

I rewrote your code to correct this error, also systematically use symbols from CMSIS-mandated device header, and it works as expected:

volatile uint32_t tt;
 
 int main(void) {
 
 // Configure ADC module ADC1_IN18 channel
 // Enable Clock access
 RCC->APB2ENR |= RCC_APB2ENR_ADC1EN;
 //10010 =18
 ADC1->SQR3 |= 16; // in 'F407, temperature sensor is CH16
 //conversion length 1 channels
 ADC1->SQR1 = 0x00;
 // TEMP sensor enable
 ADC->CCR |=ADC_CCR_TSVREFE;
 // Enable ADC module
 ADC1->CR2 |=ADC_CR2_ADON;
 
 // Enable continues conversion
 ADC1->CR2 |= ADC_CR2_CONT; // C2_CONT;
 // Start ADC conversion
 ADC1->CR2 |= ADC_CR2_SWSTART; // C2_SWSTART;
 
 while(1) {
 //Wait for conversion to complete
 while(!(ADC1->SR & ADC_SR_EOC)){};
 tt = ADC1->DR;
 }
}
(gdb) p tt
$5 = 942
(gdb)
$6 = 856
(gdb)
$7 = 948
(gdb)
$8 = 937
(gdb)

Output is rather noisy (this was run on a board which does not have VDDA/VREF+ well filtered), but note, that among other things like properly setting up clocks, you may need to set the sampling time according to datasheet requirements for the temperature sensor.

JW

Tmizr.1
Tmizr.1Author
Associate
March 28, 2023

Thank you very much for your reply.

From the refrence manual "Temperature sensor, VREFINT and VBAT internal channels • The temperature sensor is internally connected to ADC1_IN18 channel which is shared with VBAT."

To use the sensor:

3. Select ADC1_IN16 or ADC1_IN18 input channel.

4. Select a sampling time greater than the minimum sampling time specified in the datasheet.

5. Set the TSVREFE bit in the ADC_CCR register to wake up the temperature sensor from power down mode

6. Start the ADC conversion by setting the SWSTART bit (or by external trigger)

7. Read the resulting VSENSE data in the ADC data register 

It seems that I did everything according to the guide ,even I changed the selected channel to 18 , but still receving 0...

void temp_init()

{

// Configure ADC module ADC1_IN16 channel

// Enable Clock access

RCC->APB2ENR |= RCC_APB2ENR_ADC1EN;

//10010 =18

ADC1->SQR3 |=18;

//conversion length 1 channels

ADC1->SQR1 = 0x00;

// TEMP sensor enable

  ADC->CCR |=ADC_CCR_TSVREFE;

// Enable ADC module

ADC1->CR2 |=ADC_CR2_ADON;

}

waclawek.jan
Super User
March 28, 2023

Try CH16.

JW

waclawek.jan
Super User
March 28, 2023

Also, if you have non-1 APB prescaler, try inserting some delay between setting clock in RCC and setting the ADC registers.

If you have debugger, read out and check the ADC registers content.

JW

Tmizr.1
Tmizr.1Author
Associate
March 28, 2023

Unfortunately nothing new... I tested another channel (GPIO PA1) and it worked well.

waclawek.jan
Super User
March 29, 2023

I've just tried the code I've posted on a Nucleo-F411 and it works as expected, with both CH16 (as posted) and CH18.

Are you sure you are using a genuine STM32F411, and not a clone?

JW