cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L1 internal temperature

MAI THANH.Brice
Associate III
Posted on August 09, 2017 at 14:44

Hello,

I use a STM32L151RCT6 on a custom board and i want to read the internal temperature.

In the cube library I found an exemple using the LL library so I included the ll_adc driver in my code and tried to use it.

When I use the macro __LL_ADC_CALC_TEMPERATURE , i get a temperature of 425�C !! I know it's summer but that's a bit too hot

After some debuging, I read the calibration value at 30�C and 110�C : 668 and 846

I also read my raw adc value and get 1547

So the 425�C is 'correct' regarding the calibration value but I think that the calibrations values are incorrect.

Any idea why ? and how to fix this ?

I don't need an accurate measure (5�C range will be sufficient)

Brice

#stm32l1 #adc #internal-temperature-sensor
9 REPLIES 9
Tilen MAJERLE
ST Employee
Posted on August 09, 2017 at 15:11

Hello

MAI_THANH.Brice

‌,

please provide us concept of your temperature measurements. Please know that temperature may vary up to 40 degrees between devices as it is intended to be used to check temperature difference and not absolute temperature.

Best regards,

Tilen

S.Ma
Principal
Posted on August 09, 2017 at 15:11

Check out Cube example code for the corresponding Nucleo or Discovery / ADC examples. It should be there. ADC DR register value can be shifted left, right with more or less significant bit... hence the too big or too small value... Check the datasheet for the ADC setting for the calibration values. Are they for 10 bit? 12 bit? left aligned? right aligned?

MAI THANH.Brice
Associate III
Posted on August 09, 2017 at 15:38

So this is my ADC initialisation

hadc.Instance = ADC1;

hadc.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;

hadc.Init.Resolution = ADC_RESOLUTION_12B;

hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;

hadc.Init.ScanConvMode = ADC_SCAN_ENABLE;

hadc.Init.EOCSelection = ADC_EOC_SEQ_CONV;

hadc.Init.LowPowerAutoWait = ADC_AUTOWAIT_DISABLE;

hadc.Init.LowPowerAutoPowerOff = ADC_AUTOPOWEROFF_DISABLE;

hadc.Init.ChannelsBank = ADC_CHANNELS_BANK_A;

hadc.Init.ContinuousConvMode = DISABLE;

hadc.Init.NbrOfConversion = 12;

hadc.Init.DiscontinuousConvMode = DISABLE;

hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;

hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;

hadc.Init.DMAContinuousRequests = ENABLE;

And my function to measure

HAL_ADC_Start_DMA(&hadc, (uint32_t *)

adc_meas

, ADC_SEQ_ORDER_NB_CONV )

while (gsv_adc_complete != true);

uint16_t cal1 = *TEMPSENSOR_CAL1_ADDR;

uint16_t cal2 = *TEMPSENSOR_CAL2_ADDR;

int32_t temp_val = __LL_ADC_CALC_TEMPERATURE(3000, adc_meas[TEMPERATURE_SEQ_IDX], LL_ADC_RESOLUTION_12B);

PrintSerial('Cal 1 %d ; Cal 2 %d ; Raw ADC %d; Temp %d', cal1, cal2, adc_meas[TEMPERATURE_SEQ_IDX], temp_val);

And the output result

Cal 1 668 ; Cal 2 846 ; Raw ADC 1548; Temp 425

I understand that the internal temperature isn't precise but I read on the reference manual that a calibration at 30° and 110° is made so I was hoping to get a value close to the real one.

(I have sensor with minor drift at -10° and +60°, so it would have helped me)

My ADC code conversion is working because i use to measure the other channel in the adc sequence without problem

Posted on August 10, 2017 at 16:32

Hello!

The problem is, in given formula in RM , temp sensor value is for 3,0 volts VDDA.

At least the value must converted first to a proportional value to the current voltage we use.

MAI_THANH.Brice

‌ , the AD value you took is too high.

Normaly it must be between the two cal values.. at room temperature.

In your program you take 12 values

>> HAL_ADC_Start_DMA(&hadc, (uint32_t *)

adc_meas

, ADC_SEQ_ORDER_NB_CONV );

is ADC_SEQ_ORDER_NB_CONV equal to 12?

is gsv_adc_complete flag , inside the

ADC_DMAConvCplt(..)

callback?

In adc_meas[TEMPERATURE_SEQ_IDX], the TEMPERATURE_SEQ_IDX index is consistent with the rank and channel also? (0x10).

Posted on August 10, 2017 at 16:05

Hello,

Chapter 12.12 of the Reference Manual

http://www.st.com/content/ccc/resource/technical/document/reference_manual/cc/f9/93/b2/f0/82/42/57/CD00240193.pdf/files/CD00240193.pdf/jcr:content/translations/en.CD00240193.pdf

gives many information regarding how to use the temperature sensor. Make sure:
  • to enable the TSVREFE bit in the ADC_CCR register to wake up the temperature sensor with LL_ADC_SetCommonPathInternalCh()
  • to wait for sensor stabilization time (tSTART) using LL_ADC_DELAY_TEMPSENSOR_STAB_US macro
  • use the correct sampling time tSTEMP with  LL_ADC_SetChannelSamplingTime()

STM32Cube_FW_L1_V1.7.0 provides an example for STM32L152RE:

STM32Cube_FW_L1_V1.7.0\Projects\STM32L152RE-Nucleo\Examples_LL\ADC\ADC_TemperatureSensor

Rgds

Bruno

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
Posted on August 10, 2017 at 17:11

I saw this exemple to understand how to read the temperature.

I use the cube generated code with standard driver. The TSVREFE bit and delay seems to be implemented

But I think I misconfigured the sampling time on my sequence conversion. I used a 48 cycles and I think it might be too short.

I just tried to use 384 cycles and now I read 31°C for an ambiant of 27°C,it seems more correct.

Tomorrow I will perform some tests to see if the temperature is correct from -20° to 85°

Posted on August 10, 2017 at 17:17

Hello 

My power supply is 3V so the formula is good

And I use 12 adc input on this project and 

ADC_SEQ_ORDER_NB_CONV equal to 12

I use an enum to acces the differnet convesion result in the buffer

 the 

gsv_adc_complete  is a volatile bool set in the 

ADC_DMAConvCplt

the TEMPERATURE_SEQ_IDX  is also equal to the rank in the conversion sequence.

I have no problem reading all the other ADC input so I think my code is correct. 

But like I write to Bruno, I think my problem was about the sampling time. 

Posted on August 10, 2017 at 17:24

I've tried on a STM32L152 Nucleo: the temperature is  30 °C. Beware that this is the junction temperature.

In the Nucleo example,  LL_ADC_SAMPLINGTIME_192CYCLES is being used.

Cheers,

Bruno

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
Posted on August 11, 2017 at 11:37

Hi

So I've performed some tests at -25°c, 25°c and 50°C (85°c is currently running) and so far I've read the good temperature (with a 3-4°C offset)

So my problem was the sampling time: it was too short ! 

Thanks again