cancel
Showing results for 
Search instead for 
Did you mean: 

How to find a Temperature on STM32F303K8

Walter Enzo Re
Associate II

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!

10 REPLIES 10
T J
Lead

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

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
Lead

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

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
Lead

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

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
Lead
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

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
Lead

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