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, VDDA= 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

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, VDDA= 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

temperature of 30 °C,

VDDA= 3.3 V

temperature of 110 °C

VDDA= 3.3 V

Best regards

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.

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

Jack Peacock

The ADC1 runs with the internal oscillarot (14MHz)

`01.`

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

`02.`

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

`03.`

`float`

`Avg_Slope = ((`

`float`

`)(Ts_Cal1 - Ts_Cal2)) / (110 - 30);`

`04.`

`05.`

`void`

`vADCConfigurationTemperature (`

`void`

`)`

`06.`

`{`

`07.`

`ADC_InitTypeDef ADC_InitStructure;`

`08.`

`ADC_StructInit(&ADC_InitStructure);`

`/// Load defaults`

`09.`

`10.`

`ADC_DeInit(ADC1);`

`11.`

`ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;`

`12.`

`ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;`

`13.`

`ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;`

`14.`

`ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Upward;`

`15.`

`ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;`

`16.`

`ADC_Init(ADC1, &ADC_InitStructure);`

`17.`

`ADC_ChannelConfig(ADC1, ADC_Channel_16, ADC_SampleTime_239_5Cycles);`

`18.`

`ADC_TempSensorCmd(ENABLE);`

`19.`

`ADC_GetCalibrationFactor(ADC1);`

`20.`

`21.`

`ADC_Cmd(ADC1, ENABLE);`

`22.`

`while`

`(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADEN));`

`23.`

`ADC_StartOfConversion(ADC1);`

`24.`

`}`

`25.`

`26.`

`int32_t GetTemperature(`

`void`

`)`

`27.`

`{`

`28.`

`int32_t Temperature = 0;`

`29.`

`30.`

`while`

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

`31.`

`int32_t Temperature = ADC_GetConversionValue(ADC1);`

`32.`

`float`

`Calc = ((((`

`float`

`)(Ts_Cal1 - Temperature)) / Avg_Slope) + 30);`

`33.`

`Temperature = (int32_t)Calc;`

`34.`

`35.`

`return`

`Temperature;`

`36.`

`}`

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?

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

Problem solved.

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

Regarding these TS_CAL1 and 2 values, are they applicable for the STM32F103 device?

Cannot find any references in the manuals or guides. I get the feeling that these values are not available with this device. But maybe there is another solution to get more accurate values of the temperature.

Regards Peter