2013-05-16 07:10 AM
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-temperature2013-05-16 07:49 AM
The 30 C and 110 C calibration values are 16-bit, not 32-bit
2013-05-16 08:33 AM
But why are they using 2 32Bit registers for each value?
Calibration value name Description
Memory addressTS_CAL1 TS ADC raw data acquired at
temperature of 30 °C, VDDA= 3.3 V 0x1FFF F7B8 - 0x1FFF F7B9TS_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 regards2013-05-16 09:13 AM
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.2013-05-16 09:19 AM
2013-05-16 10:34 AM
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 Peacock2013-05-16 11:41 PM
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?
2013-05-17 02:38 AM
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°C2013-05-17 03:52 AM
Thank you. The discovery board use realy 3V instead of 3V3.
Problem solved.2013-05-17 07:01 AM