cancel
Showing results for 
Search instead for 
Did you mean: 

Incorrect readings from STM32F407's internal temperature sensor when rank is changed.

AdityaUbarhande
Associate

Hi All,
I was experimenting with the inbuilt temperature sensor on STM32F4 DISCOVERY board. The sensor is connected to ADC1_IN16 (16th channel of ADC1).

I wrote a basic C program (attached below) and was able to get the sensor working perfectly fine.

(I have configured 3 of the 4 on-board LEDs to change color as the temperature varies, this is why you would see the GPIO config part as well)

 

 

    #include<stdint.h>
    #include<stdio.h>
    int main(void)
    {	
        //Variable Definitions
        uint32_t* GPIO_MODER = (uint32_t*)0x40020C00;
        uint32_t* GPIO_ODR = (uint32_t*)0x40020C14;
     
        uint32_t* RCC_CLK_AHB1 = (uint32_t*)0x40023830;
        uint32_t* RCC_CLK_APB2 = (uint32_t*)0x40023844;
     
        uint32_t* ADC_CR2 = (uint32_t*)0x40012008;
        uint32_t* ADC_SQR3 = (uint32_t*)0x40012034;
        uint32_t* ADC_SQR1 = (uint32_t*)0x4001202C;
        uint32_t* ADC_CCR = (uint32_t*)0x40012304;
        uint32_t* ADC_DR = (uint32_t*)0x4001204C;
        uint32_t* ADC_STAT = (uint32_t*)0x40012000;
        uint32_t* ADC_SMPR = (uint32_t*)0x4001200C;
     
        
        //Clock enable for GPIOD and ADC
        *RCC_CLK_AHB1 |= (1 << 3);	//Enable GPIOD clock
        *RCC_CLK_APB2 |= (1 << 8);	//Enable ADC clock
     
        //GPIO mode set (LEDs set to OUTPUT)
        *GPIO_MODER |= (1 << 30);
        *GPIO_MODER |= (1 << 28);
        *GPIO_MODER |= (1 << 26);
        *GPIO_MODER |= (1 << 24);
     
         //ADC Configuration
     
        *ADC_SQR1 |= (16 << 15);	//Set 16th sequence for Channel 16
        *ADC_SQR1 |= (15 << 20);	//Configure the 'L' section 
        *ADC_SMPR |= (7 << 18);	//Set Sample Rate to Maximum. (480)
        *ADC_CR2 |= (1 << 0);	//Set ADON bit
        *ADC_CCR |= (1 << 23);	//Enable Temperature Sensor
        	
        while(1)
        {
            *ADC_CR2 |= (1 << 30);		//Start Conversion
    	    while(!(*ADC_STAT & (1 << 4)));	//Wait for conversion to start
    	    while (!(*ADC_STAT & (1 << 1)));     // Wait for EOC flag
     
            uint16_t Vsense =  (uint16_t)*ADC_DR; //Read ADC output data
    	    double voltage, celsius;
     
            voltage = (double)Vsense/4095*3.3;
    	    celsius = (double)(((voltage - 0.76) / 0.0025) + 25);
     
            printf("\nTemperature is: %.2f", celsius);  //Print the temperature 
     
            if(celsius < 57.5) //For low temperature, turn blue LED on
    	    {
    		*GPIO_ODR &= ~(1 << 13);
    		*GPIO_ODR &= ~(1 << 14);
    		*GPIO_ODR |= (1 << 15);
    	    }
    	    else if(celsius < 68 && celsius > 58)//For medium temp, turn orange LED on
    	    {
    		*GPIO_ODR &= ~(1 << 15);
    		*GPIO_ODR &= ~(1 << 14);
    		*GPIO_ODR |= (1 << 13);
    	    }
    	    else if(celsius > 65)  //For high temperature, turn red LED on
    	    {
    		*GPIO_ODR &= ~(1 << 15);
    		*GPIO_ODR &= ~(1 << 13);
    		*GPIO_ODR |= (1 << 14);
    	    } 
        }
    }

 

 

Here is what I found!

In my first code (not the one shared above), I set the rank/priority/sequence of Channel 16 to '1' using the ADC_SQR3 Register. And the temperature sensor worked perfectly fine!

But when I change the rank/priority/sequence to something that is NOT '1' (so 2, 3 or even 16), the temperature sensor does not work properly and I get garbage data in the ADC_DR (ADC Data Register). So the code shared above won't work because it sets the sequence of channel 16 to 16th sequence/rank/priority using ADC_SQR1 (see line number 33)

Why is this happening? Why does changing the rank/priority/sequence of channel 16 disturb the functioning of the code?

P.S. In the ADC_SQR1 there is a "bit-space" named "L[3:0]" (screenshot attached). I believe this bit-space stands for the "number of conversions you wish to make". This bit-space was set to 2 when I selected the rank/priority/sequence to be 2 and 16 when I made the priority 16. So I don't think the configuration of 'L' might be the issue. But please do let me know if my understanding is wrong.

1.png

 

 
 

 

P.P.S: Please let me know what is the correct technical term for rank/priority/sequence? I see different words used at different places. Some articles refer to it as rank, so as priorities and the reference manual refers to it as sequence.

 

Regards,

Aditya Ubarhande

0 REPLIES 0