2017-08-09 05:44 AM
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 1547So 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-sensor2017-08-09 06:11 AM
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
2017-08-09 06:11 AM
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?
2017-08-09 06:38 AM
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
2017-08-10 07:32 AM
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).
2017-08-10 09:05 AM
Hello,
Chapter 12.12 of the Reference Manual
gives many information regarding how to use the temperature sensor. Make sure: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
2017-08-10 10:11 AM
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 implementedBut 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°
2017-08-10 10:17 AM
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.
2017-08-10 10:24 AM
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
2017-08-11 04:37 AM
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