cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L4 ADC Configuration to read internal temperature sensor's data.

Maunik Patel
Associate II

Hello there,

I am working on STM32L4's ADC and wants to measure internal temperature sensor's readings.

But somehow, I am facing some issues here.

1. Calculated Temperature is incorrect:

I used below equation, provided in reference manual RM0393's 16.4.31 section, to calculate actual temperature:

   Temperature (in Celsius) = ((110 - 30) * (TS_DATA - TA_CAL1) / (TS_CAL2 - TS_CAL1)) + 30

where,

   TS_DATA = 886 (640.5 Cycles)

   TS_CAL1 = 1035   (read from address 0x1FFF 75A8-A9)

   TS_CAL2 = 1373   (read from address 0x1FFF 75CA-CB)

   Calculated temperature = -5 (at room temperature, about 26 Celsius)

Clearly, here is some issue. Can you please guide me to resolve it ?

ADC Configuration:

   Resolution : 12-bit

   sampling time : 640.5 Cycles

   End of Conversion Selection : End of Single Conversion

   Scan mode / Continuous mode / Discontinuous Mode : Disabled

If required, I can provide code for above mentioned testings.

.

2. Sampling Time:

What should be proper value of 'Sampling Time', while calculating Temperature ?

I know that 'Sampling time' is relevant with some hardware impedance, but don't know what impedance is set for internal temperature sensor.

.

3. Max impedance for 12-bit resolution:

As mentioned in the datasheet, maximum RAin external impedance is 50K.

But, for 12-bit resolution, we are allowed to use 39K only (for fast channels)

(reference: Table 63, Page 115 of STM32L4's data sheet)

Can we set impedance > 39K for 12-bit resolution?

Please guide me here.

Thank You,

Maunik Patel

4 REPLIES 4
T J
Lead

this is the code I use for the F091

void readProcessorTemperature(void) {
    //Temperature computation code example
    // 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))   // set in factory
#define VDD_APPLI ((uint16_t) (3295))  // set my measuring my voltage on PCB
	
  	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;
    processorTemp *=  110 - 30;
    processorTemp /=  ((double)*TEMP110_CAL_ADDR) - *TEMP30_CAL_ADDR;
    processorTemp +=   30;
    processorTemperature =  (int32_t)(processorTemp * 100);
    //printf("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);
 
    Vdda = (double)16 * 3.3 * *VREFINT_CAL;  // 16x oversampled data requires /16
    Vdda /= ADC_Channel_AVE[VRef_Ad17];
    
    setCursor1(0, 90);  // static debug screen
    printf( "processorTemperature %.1f     ", ((float)processorTemperature) / 100);
    printf( "Vdda as %.3f  \n\r", Vdda);
   
}

Hello @Community member​ 

Your code is almost identical with that of mine.

Except the number '16' you used as divider at line 14th and as multiplier at line 21th.

But still I am facing the issue.

I appreciate your reference code.

Thank You...

michal.matejasko
Associate II

Hi @Community member​ ,

you have probably already solved the problem. Just for others that might be roaming here:

1.Sampling time

The constrains are stated in the datasheet (DS11449, section 6.3.23 Temperature sensor characteristics) . The ADC sampling time when reading the temperature >= 5us.

2.Vdda

Attention must be payed to the conditions on when the TS_CAL1 and TS_CAL2 values were acquired.

In the same datasheet as above, section 3.15.1 Temperature sensor says, that the values were obtained with Vdda = 3.0V. If your Vdda is different, then you need to recalculate the TS_CAL1 and TS_CAL2 values accordingly, in order to get correct values.

It seems to me, that you might have faced the mutual effect of those two reasons.

I hope, this answer will help somebody struggling with the same issue here. 🙂

Best regards,

Michal

S.Ma
Principal

Yep, first you have to read Vref, deduct Vdd and scale the ADC from Vdd down to 3.0V to run the linear interpolation.

The ADC example in Cube is not going to bring you to this point.