cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F411 - temperature sensor returning 0

Tmizr.1
Associate II

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!

6 REPLIES 6

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
Associate II

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;

}

Try CH16.

JW

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
Associate II

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

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