Skip to main content
Walter Enzo Re
Associate II
September 6, 2018
Question

How to find a Temperature on STM32F303K8

  • September 6, 2018
  • 10 replies
  • 3062 views

Hi, Everyone.

I'm tring to make adc sensor works, to find a temperature.

I found AVG_Slope and V_25 in the datasheet:

AVG_Slope = 0.0046

V_25 = 1.46

And I used V_Ref = 3.0f and N_Bit = 4096f

This is My code (Only for adc_complete conversion)

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)

{

   if (hadc->Instance == ADC1 ){

      float value;

      value = ((float)adc1_buff[3]/N_BIT)*V_REF;

      oil_temp = (float)(((V_25 - value)/Avg_Slope)+25);

      //oil_temp = value;

      //printf("Dato 1 %d, Dato 2 %d, Dato 3 %d, Dato 4 %d", adc1_buff[0], adc1_buff[1], adc1_buff[2], oil_temp);

   }

   else if (hadc->Instance == ADC2 ){

      float val;

      float result;

      HAL_GPIO_TogglePin(GPIOB, LD3_Pin);

      result = HAL_ADC_GetValue(&hadc2);

      val = ((float)result/N_BIT)*V_REF;

      ntc = (float)(((V_25-val)/Avg_Slope)+25);

   }

The problem is that resoult is crazy!

I found about 300° for 3.3 V in, so, surely, I'm doing some mistakes, but I can't find it.

Someone could me help to find them?

Many thanks!

    This topic has been closed for replies.

    10 replies

    T J
    Senior III
    September 6, 2018

    I use this code:

    void readProcessorTemperature(void) {
    /*
     
    Temperature sensor calibration value address
    #define TEMP110_CAL_ADDR ((uint16_t*) ((uint32_t) 0x1FFFF7C2))
    #define TEMP30_CAL_ADDR ((uint16_t*) ((uint32_t) 0x1FFFF7B8))
    #define VDD_CALIB ((uint16_t) (330))
    #define VDD_APPLI ((uint16_t) (300))
    */
    // Temperature sensor calibration value address 
    #define TEMP110_CAL_ADDR ((uint16_t*) ((uint32_t) 0x1FFFF7C2)) // calibrated at 3.3V +-10mV @110C +/- 5C 
    #define TEMP30_CAL_ADDR ((uint16_t*) ((uint32_t) 0x1FFFF7B8)) // calibrated at 3.3V +-10mV @ 30C +/- 5C 
    #define VREFINT_CAL ((uint16_t*) ((uint32_t) 0x1FFFF7BA)) // calibrated at 3.3V +-10mV @ 30C +/- 5C 
    #define VDD_CALIB ((uint16_t) (3300))
    #define VDD_APPLI ((uint16_t) (3295))
    	
     	int32_t AveTemperatureADC = ADC_Channel_AVE[VTemp_Ad16]; // 16x over sampled, needs /16
     
     double processorTemp; // the temperature in degree Celsius
     	
     processorTemp = (double) AveTemperatureADC / 16 - *TEMP30_CAL_ADDR; // /16 to remove the over sampling
     processorTemp *= 110 - 30;
     processorTemp /= ((double)*TEMP110_CAL_ADDR) - *TEMP30_CAL_ADDR;
     processorTemp += 30;
     processorTemperature = (int32_t)(processorTemp * 100);
     //		sprintf(string,"AveTemperatureADC %04X, ADC_CalibrationFactor %04X, *TEMP30_CAL_ADDR %04X, processorTemperature %.2f, processorTemp %.3f \n\r",AveTemperatureADC,ADC_CalibrationFactor,(int32_t) *TEMP30_CAL_ADDR,((float)processorTemperature/100),processorTemp);
     //		puts (string);
     
     Vdda = (double)16 * 3.3 * *VREFINT_CAL; // remove the 16x over sampling without losing resolution
     Vdda /= ADC_Channel_AVE[VRef_Ad17];
     
     
     //char string[64];
     setCursor1(0, 90);
     
     sprintf(string, "processor Temperature %.1f ", ((float)processorTemperature) / 100);
     puts1(string);
     sprintf(string, "Vdda as %.3f \n\r", Vdda);
     puts1(string);
     
    }

    Walter Enzo Re
    Associate II
    September 7, 2018

    Hi Tj, many thanks for your reply.

    I've read your code, but I can't understand it properly.

    For example: ADC_Channel_AVE function where is defined?

    T J
    Senior III
    September 7, 2018

    the Average is only 16 samples added up, hence /16 is required.

    otherwise you can use the direct ADC result... without /16

    Walter Enzo Re
    Associate II
    September 8, 2018

    Hi Tj, many thanks for your reply.

    I generated the code using CubeMX, and I've modify it.

    I've tried to use your code as follows:

    void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)

    {

       if (hadc->Instance == ADC1 ){

          oil_temp = (double)adc1_buff[3] - *TEMP30_CAL_ADDR;

          oil_temp *= 110 - 30;

          oil_temp /= ((double)*TEMP110_CAL_ADDR) - *TEMP30_CAL_ADDR;

          oil_temp +=  30;

          oil_temp = (double)(oil_temp * 100);

       }

    where oil_temp is a double variabile that should contains a temperature in Celsius degree, and adc1_buff[3] is the input voltage that should be transformed in the temperature.

    The problem is the temperature result is not right, I found about -7045..

    Any suggestion?

    Many thanks.

    T J
    Senior III
    September 8, 2018

    this calculation is for processor temperature. I never checked it on a stm32F303

    I do not understand what you mean by Oil Temperature.

    Do you have an Oil Temp sensor connected to an analog input ?

    which temperature sensor is it ?

    Walter Enzo Re
    Associate II
    September 8, 2018

    Hi Tj, many thanks for your reply.

    At the moment there isn't a sensor connected to the pin, but there will be.

    The exact sensor I don't know what will be, but probabily an NTC.

    I've seen this formula on the user manual:

    0690X000006C00hQAC.png

    And I tried it (first post), but temperature out is very strange, so, I need only this formula works.

    I will adapte the V_Ref in function the sensor that I will connected, without changing the code, o, at least, that's what I'd like to do.

    T J
    Senior III
    September 8, 2018
    I get these values from the DMA:

    ADC_ChannelCount 000C
    0909, 081c, 0000, 0502, 074d, 0861, 0024, 0519, 075c, 06ae, 05f1, 07fc,
    Processor Temp is an onboard sensor, it’s the 3rd last reading 0x06AE
    How are you reading the Oil Temperature?
    Walter Enzo Re
    Associate II
    September 8, 2018

    Hi Tj, many thanks for your reply.

    So, I use ADC conversion with DMA, so, I have adc1 with 4 channel, and one of these are the channel where I need to reed the oil temperature.

    So, this is the code:

    /*! Buffer created to storage ADC data by DMA N.B Every cycle, this buffer is overwritten*/
    uint16_t adc1_buff[4];
    double oil_temp;
     
    HAL_TIM_Base_Start_IT(&htim2);
    HAL_ADC_Start_DMA(&hadc1, (uint32_t*)adc1_buff, 4 );
     
    void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
    {
    	if (hadc->Instance == ADC1 ){
    	 oil_temp = (double)adc1_buff[3] - *TEMP30_CAL_ADDR;
    	 oil_temp *= 110 - 30;
    	 oil_temp /= ((double)*TEMP110_CAL_ADDR) - *TEMP30_CAL_ADDR;
    	 oil_temp += 30;
    	 oil_temp = (double)(oil_temp * 100);
    	}

    I leave the part where I make start the timer, and where I include the adc file, to make code easly to read.

    ADC start conversion is triggered by Tim2.

    I only use ADC, the temperature I'd like read by the formula post above, but the result is very strange..

    T J
    Senior III
    September 8, 2018

    If you use an NTC temp sensor then the formula I gave you for processor temp is incorrect.

    you will have to calculate your NTC ADC to Temperature Algorithm

    Walter Enzo Re
    Associate II
    September 8, 2018

    Hi Tj, many thanks for your reply.

    So I can't use the formula on reference manual, and, later remap the scale changing the V_Ref?