cancel
Showing results for 
Search instead for 
Did you mean: 

Internal temperatur sensor

pa
Associate II
Posted on May 16, 2013 at 16:10

Hi all

I've some troubles with the internal temperatur sensor from my stm32f051: If I read the adc_channel16 I get ~1920 as value.

Then I calculate the result in this way

�C = ((V25 - VSENSE) / Avg_Slope) + 25 = ((1.43V - 1.54V) / 4.3mV/�C) + 25 = -0.58�C

But this should be ~22�C.

Then I thought, that I could use the factory callibration data. But HOW?

If I read the stored value like this ''(*((uint32_t*)0x1FFFF7B8))'' I get 100206271 as ''

TS ADC raw data acquired at temperature of 30 �C, V

DDA

= 3.3 V

''.

So can anyone help me? Or should I use an external SPI temperature sensor for only measuring with an accuracy of ~1�C?

Thank you very mutch and best regards

#adc-bandgap #stm32f205-temperature
10 REPLIES 10
Posted on May 16, 2013 at 16:49

The 30 C and 110 C calibration values are 16-bit, not 32-bit

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
pa
Associate II
Posted on May 16, 2013 at 17:33

But why are they using 2 32Bit registers for each value?

Calibration value name  Description 

Memory address 

 TS_CAL1  TS ADC raw data acquired at

temperature of 30 °C,

VDDA= 3.3 V  0x1FFF F7B8 - 0x1FFF F7B9

 TS_CAL2  TS ADC raw data acquired at

temperature of 110 °C

VDDA= 3.3 V  0x1FFF F7C2 - 0x1FFF F7C3 .ExternalClassB03E595537E44B59A949E22D56147C6B .telerik-reTable-2 {border-collapse:collapse;border:solid 0px;font-family:Tahoma;} .ExternalClassB03E595537E44B59A949E22D56147C6B .telerik-reTable-2 tr.telerik-reTableHeaderRow-2 {border-width:1.0pt 1.0pt 3.0pt 1.0pt;margin-top:0in;margin-right:0in;margin-bottom:10.0pt;margin-left:0in;line-height:115%;font-size:11.0pt;font-family:'Calibri' , 'sans-serif';width:119.7pt;border:solid white 1.0pt;border-bottom:solid white 3.0pt;background:#4F81BD;padding:0in 5.4pt 0in 5.4pt;color:#FFFFFF;} .ExternalClassB03E595537E44B59A949E22D56147C6B .telerik-reTable-2 td.telerik-reTableHeaderFirstCol-2 {border-width:1.0pt 1.0pt 3.0pt 1.0pt;border:solid white 1.0pt;border-bottom:solid white 3.0pt;padding:0in 5.4pt 0in 5.4pt;} .ExternalClassB03E595537E44B59A949E22D56147C6B .telerik-reTable-2 td.telerik-reTableHeaderLastCol-2 {border-width:1.0pt 1.0pt 3.0pt 1.0pt;border:solid white 1.0pt;border-bottom:solid white 3.0pt;padding:0in 5.4pt 0in 5.4pt;} .ExternalClassB03E595537E44B59A949E22D56147C6B .telerik-reTable-2 td.telerik-reTableHeaderOddCol-2 {border-width:1.0pt 1.0pt 3.0pt 1.0pt;border:solid white 1.0pt;border-bottom:solid white 3.0pt;padding:0in 5.4pt 0in 5.4pt;} .ExternalClassB03E595537E44B59A949E22D56147C6B .telerik-reTable-2 td.telerik-reTableHeaderEvenCol-2 {border-width:1.0pt 1.0pt 3.0pt 1.0pt;border:solid white 1.0pt;border-bottom:solid white 3.0pt;padding:0in 5.4pt 0in 5.4pt;} .ExternalClassB03E595537E44B59A949E22D56147C6B .telerik-reTable-2 tr.telerik-reTableOddRow-2 {color:#666666;background-color:#F2F3F4;font-size:10pt;vertical-align:top;} .ExternalClassB03E595537E44B59A949E22D56147C6B .telerik-reTable-2 tr.telerik-reTableEvenRow-2 {color:#666666;background-color:#E7EBF7;font-size:10pt;vertical-align:top;} .ExternalClassB03E595537E44B59A949E22D56147C6B .telerik-reTable-2 td.telerik-reTableFirstCol-2 {margin-top:0in;margin-right:0in;margin-bottom:10.0pt;margin-left:0in;line-height:115%;font-size:11.0pt;font-family:'Calibri' , 'sans-serif';width:119.7pt;border-top:none;border-left:solid white 1.0pt;border-bottom:none;border-right:solid white 3.0pt;background:#4F81BD;padding:0in 5.4pt 0in 5.4pt;color:#FFFFFF;} .ExternalClassB03E595537E44B59A949E22D56147C6B .telerik-reTable-2 td.telerik-reTableLastCol-2 {padding:0in 5.4pt 0in 5.4pt;} .ExternalClassB03E595537E44B59A949E22D56147C6B .telerik-reTable-2 td.telerik-reTableOddCol-2 {padding:0in 5.4pt 0in 5.4pt;} .ExternalClassB03E595537E44B59A949E22D56147C6B .telerik-reTable-2 td.telerik-reTableEvenCol-2 {padding:0in 5.4pt 0in 5.4pt;} .ExternalClassB03E595537E44B59A949E22D56147C6B .telerik-reTable-2 tr.telerik-reTableFooterRow-2 {color:#666666;background-color:#FFFFFF;font-size:10pt;vertical-align:top;padding:0in 5.4pt 0in 5.4pt;} .ExternalClassB03E595537E44B59A949E22D56147C6B .telerik-reTable-2 td.telerik-reTableFooterFirstCol-2 {margin-top:0in;margin-right:0in;margin-bottom:10.0pt;margin-left:0in;line-height:115%;font-size:11.0pt;font-family:'Calibri' , 'sans-serif';width:119.7pt;border-top:none;border-left:solid white 1.0pt;border-bottom:none;border-right:solid white 3.0pt;background:#4F81BD;padding:0in 5.4pt 0in 5.4pt;color:#FFFFFF;} .ExternalClassB03E595537E44B59A949E22D56147C6B .telerik-reTable-2 td.telerik-reTableFooterLastCol-2 {padding:0in 5.4pt 0in 5.4pt;} .ExternalClassB03E595537E44B59A949E22D56147C6B .telerik-reTable-2 td.telerik-reTableFooterOddCol-2 {padding:0in 5.4pt 0in 5.4pt;} .ExternalClassB03E595537E44B59A949E22D56147C6B .telerik-reTable-2 td.telerik-reTableFooterEvenCol-2 {padding:0in 5.4pt 0in 5.4pt;}

Best regards

Posted on May 16, 2013 at 18:13

But why are they using 2 32Bit registers for each value?

You are confused, they do not, it describes two addresses for 8-bit bytes, which when combined represent a 16-bit value. The range no doubt fitting in 12-bit given the performance of the ADC.

uint16_t ts_cal1, ts_cal2;

ts_cal1 = *((uint16_t*)0x1FFFF7B8);

ts_cal2 = *((uint16_t*)0x1FFFF7C2);

from these you should be able to create a basis, and per degree scale from which to utilize the reading.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on May 16, 2013 at 18:19

0690X00000604ynQAA.png

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
jpeacock2399
Associate II
Posted on May 16, 2013 at 19:34

Make sure your sample time for channel 16-19 is at least 10usec, otherwise you get invalid data.  Buried in the datasheet electrical specs for the part is a conversion time parameter for the internal channels.  On an F4 I get a converted sample in the 985 range.

I had the same problem when I had a fast conversion time.

  Jack Peacock

pa
Associate II
Posted on May 17, 2013 at 08:41

Ok, I've now changed my calculation but the values isn't still correct (SMT32F0Discovery).

The ADC1 runs with the internal oscillarot (14MHz)


#define Ts_Cal1 (*((sf_uint16*)0x1FFFF7B8)) 

#define Ts_Cal2 (*((sf_uint16*)0x1FFFF7C2)) 

float
Avg_Slope = ((
float
)(Ts_Cal1 - Ts_Cal2)) / (110 - 30); 


void
vADCConfigurationTemperature (
void
) 

{ 

ADC_InitTypeDef ADC_InitStructure; 

ADC_StructInit(&ADC_InitStructure); 
/// Load defaults 


ADC_DeInit(ADC1); 

ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; 

ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; 

ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; 

ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Upward; 

ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; 

ADC_Init(ADC1, &ADC_InitStructure); 

ADC_ChannelConfig(ADC1, ADC_Channel_16, ADC_SampleTime_239_5Cycles); 

ADC_TempSensorCmd(ENABLE); 

ADC_GetCalibrationFactor(ADC1); 


ADC_Cmd(ADC1, ENABLE); 

while
(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADEN)); 

ADC_StartOfConversion(ADC1); 

} 


int32_t GetTemperature(
void
) 

{ 

int32_t Temperature = 0; 


while
(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET); 

int32_t Temperature = ADC_GetConversionValue(ADC1); 

float
Calc = ((((
float
)(Ts_Cal1 - Temperature)) / Avg_Slope) + 30); 

Temperature = (int32_t)Calc; 


return
Temperature; 

}

I've changed the formula from (((V25 - VSense) / Avg_Slope) + 25) to (((ADC30 - ADC) / Avg_ADC_Slope) + 30). With this values: ADC30 (TS_Cal1) = 1727 ADC (room temp) = ~1940 Avg_ADC_Slope = 5.3125 This gives a Temperature of -10°C instead of ~22°C. What I'm doing worng?
damh
Associate II
Posted on May 17, 2013 at 11:38

Check Vcc and Vcc_ref. If they are not equal to accurate 3.3V, you have to calculate this difference away! Vcc_ref should be stable, too!

Your value of 1940 at 22°C seems to be measured at Vcc_ref=3.0V ;)

1940 / 3300mV * 3000mV = 1763 (corrected ADC_Value) => 23°C
pa
Associate II
Posted on May 17, 2013 at 12:52

Thank you. The discovery board use realy 3V instead of 3V3.

Problem solved.
jpeacock2399
Associate II
Posted on May 17, 2013 at 16:01

This is where the on chip bandgap voltage reference is useful.  Since it returns a known voltage (around 1.2V) you can calculate backwards to determine the ADC Vref voltage. 

I use this to ensure the ADC voltage is stable before starting ADC conversions.  Since the CPU can start while the Vcc is still rising, and the ADC is unstable, making sure the bandgap converts back to the expected ADC voltage ensures the CPU has reached the expected operating voltage.

  Jack Peacock