cancel
Showing results for 
Search instead for 
Did you mean: 

How to convert calibration values for temperature sensor from 3.3V to 2.5V?

DFuchs
Associate III

Hi,

i have a STM32H743 with an external voltage reference with 2.5V and want to use the internal temperature sensor.

When i use the calibration values from flash i converted them by ((TS_CALx *33.0)/25.0).

The measured value at room temperature seems to be good. I put our prototype in a conditioning cabinet at 70°C and the measured temperaure was 70°C too. I expected something like 85°C.

Do i need measure new calibration values or is the there a formula to transfer the calibration values from 3.3V to 2.5V?

Kind regards

Daniel

8 REPLIES 8
TDK
Guru

Look at the code in __LL_ADC_CALC_TEMPERATURE and use that calculation:

/**
  * @brief  Helper macro to calculate the temperature (unit: degree Celsius)
  *         from ADC conversion data of internal temperature sensor.
  * @note   Computation is using temperature sensor calibration values
  *         stored in system memory for each device during production.
  * @note   Calculation formula:
  *           Temperature = ((TS_ADC_DATA - TS_CAL1)
  *                           * (TS_CAL2_TEMP - TS_CAL1_TEMP))
  *                         / (TS_CAL2 - TS_CAL1) + TS_CAL1_TEMP
  *           with TS_ADC_DATA = temperature sensor raw data measured by ADC
  *                Avg_Slope = (TS_CAL2 - TS_CAL1)
  *                            / (TS_CAL2_TEMP - TS_CAL1_TEMP)
  *                TS_CAL1   = equivalent TS_ADC_DATA at temperature
  *                            TEMP_DEGC_CAL1 (calibrated in factory)
  *                TS_CAL2   = equivalent TS_ADC_DATA at temperature
  *                            TEMP_DEGC_CAL2 (calibrated in factory)
  *         Caution: Calculation relevancy under reserve that calibration
  *                  parameters are correct (address and data).
  *                  To calculate temperature using temperature sensor
  *                  datasheet typical values (generic values less, therefore
  *                  less accurate than calibrated values),
  *                  use helper macro @ref __LL_ADC_CALC_TEMPERATURE_TYP_PARAMS().
  * @note   As calculation input, the analog reference voltage (Vref+) must be
  *         defined as it impacts the ADC LSB equivalent voltage.
  * @note   Analog reference voltage (Vref+) must be either known from
  *         user board environment or can be calculated using ADC measurement
  *         and ADC helper macro @ref __LL_ADC_CALC_VREFANALOG_VOLTAGE().
  * @note   On this STM32 serie, calibration data of temperature sensor
  *         corresponds to a resolution of 16 bits,
  *         this is the recommended ADC resolution to convert voltage of
  *         temperature sensor.
  *         Otherwise, this macro performs the processing to scale
  *         ADC conversion data to 16 bits.
  * @param  __VREFANALOG_VOLTAGE__  Analog reference voltage (unit: mV)
  * @param  __TEMPSENSOR_ADC_DATA__ ADC conversion data of internal
  *                                 temperature sensor (unit: digital value).
  * @param  __ADC_RESOLUTION__      ADC resolution at which internal temperature
  *                                 sensor voltage has been measured.
  *         This parameter can be one of the following values:
  *         @arg @ref LL_ADC_RESOLUTION_16B
  *         @arg @ref LL_ADC_RESOLUTION_14B
  *         @arg @ref LL_ADC_RESOLUTION_12B
  *         @arg @ref LL_ADC_RESOLUTION_10B
  *         @arg @ref LL_ADC_RESOLUTION_8B
  * @retval Temperature (unit: degree Celsius)
  */
#define __LL_ADC_CALC_TEMPERATURE(__VREFANALOG_VOLTAGE__,\
                                  __TEMPSENSOR_ADC_DATA__,\
                                  __ADC_RESOLUTION__)                              \
  (((( ((int32_t)((__LL_ADC_CONVERT_DATA_RESOLUTION((__TEMPSENSOR_ADC_DATA__),     \
                                                    (__ADC_RESOLUTION__),          \
                                                    LL_ADC_RESOLUTION_16B)         \
                   * (__VREFANALOG_VOLTAGE__))                                     \
                  / TEMPSENSOR_CAL_VREFANALOG)                                     \
        - (int32_t) *TEMPSENSOR_CAL1_ADDR)                                         \
     ) * (int32_t)(TEMPSENSOR_CAL2_TEMP - TEMPSENSOR_CAL1_TEMP)                    \
    ) / (int32_t)((int32_t)*TEMPSENSOR_CAL2_ADDR - (int32_t)*TEMPSENSOR_CAL1_ADDR) \
   ) + TEMPSENSOR_CAL1_TEMP                                                        \
  )

If you feel a post has answered your question, please click "Accept as Solution".
DFuchs
Associate III

Thank you for your help,

but my formula seems to be mathematically equivalent.

I'm using double values for the computation. Perhaps there is a problem or TS_CAL2 isn't measured at 110°C.

Kind regards

Daniel

auto const TS_CAL1 = *reinterpret_cast<uint16_t*>(0x1FF1E820);
auto const TS_CAL2 = *reinterpret_cast<uint16_t*>(0x1FF1E840);
auto const ts_cal1_25v = (static_cast<double>(TS_CAL1) * 33.0) / 25.0;
auto const ts_cal2_25v = (static_cast<double>(TS_CAL2) * 33.0) / 25.0;
 
auto const ts_data = Adc::GetAdc3Data();
auto const temperature = (80.0 / (ts_cal2_25v - ts_cal1_25v))*(static_cast<double>(ts_data) - ts_cal1_25v) + 30.0;

There’s also a sample time requirement. See the datasheet.
If you feel a post has answered your question, please click "Accept as Solution".

Formulae look good to me.

Besides sample time requirement, there is also a required startup time.

What were the values of ts_data for room temperature and for the 70deg.C, and what are the values of TS_CAL1 and TS_CAL2?

JW

I've tested different values fo sample time -> same behaviour.

I've initialised the ADC3 and activated the temperature sensor. Initialised some other stuff and started the ADC3 conversion with channel 18 only.

Now i added 10ms busy waiting between activation of sensor and conversion start. But testing in the cabinet takes some time.

TS_CAL1 = 12309 (30°C, 3.3V reference) -> ts_cal1_25v = 16247.88

TS_CAL2 = 16476 (110°C, 3.3V reference) -> ts_cal2_25v = 21748.32

ts_data = 15937 @ start and 24°C room temperature, so internal junction temperature could be 25.5°C

ts_data = about 19000 @ 70°C ambient temperature, so internal junction temperature cannot be 70°C

Edit:

No changed with 10ms waiting.

The prototype was deactivated and the conditioning cabinet heat up all to about 70°C.

I started the prototype and after about 4 seconds i got the temperature values.

ts_data = 18348 @ start and 70°C ambient temperature. 18348 -> 60,5°C ?!

Kind regards

Daniel

Nikita91
Lead II

4 seconds is very short.

For me there is not enough time for a self warm up, so it seems normal to measure the ambient temperature.

How long does it stabilize at 70 ° C before starting the MCU?

DFuchs
Associate III

I waited about 30 minutes till a sensor inside the cabinet reached and holds the 70°C. So every metal and plastic part inside the cabinet should have 70°C.

When i wait more than an hour with the running prototype the internal temperture sensor measures about 19000 = 70°C. The thermocouple on the heat sink measures 78°C already. The cabinet has an fan inside so 78°C on heat sink and 70°C ambient temperature seems to fit.

Kind regards

Daniel

DFuchs
Associate III

Hmm,

if i don't use the calibration values the result seems to me more realistic. Instead i use the 2mV/°C from the datasheet.

30°C -> 0,620V at temperature sensor -> 16253 at adc3 with 2.5V reference

70°C -> 30°C + 40°C -> 0,620V + (40°C *2mV/°C) -> 0,700V at temperature sensor -> 18350 at adc3 with 2.5V reference.

I would have a junction temperature of 82.5°C with 78°C at heat sink and 70°C ambient.