cancel
Showing results for 
Search instead for 
Did you mean: 

The internal temperature measured by the ADC is different in debug and not debug mode. When I am debugging, the temperature value measured is correct (about 23°C). Without the j-link debugger, the temperature measured is incorrect (about 18 °C)

dlamb.1
Associate II

I send the temperature value on a serial interface.

In the live watch of the IAR tool, I can see the same correct value than the one sent on the serial interface.

The problem occurs after a power-down/power-up of my board, like if something is not initialised properly.

But when I connect my J-Link and without downloading a new firmware, it works again!!!

-->Are there some timings at the starting-up required before to initialize the ADC?

8 REPLIES 8
Ozone
Lead II

Wait for a few minutes after power-on, to have thermal equilibrium.

Compare those measurements.

For analogue electronics, 15 minutes are recommended.

dlamb.1
Associate II

I have a mechanism for recalibrating the ADC when the temperature has shift of 5 degrees.

After the first measurement, if I force this recalibration, then it works!

It seems that the very first calibration doesn't work in my case. This application runs with a 48MHz crystal.

I have the same firmware running on another board but with a cystal at 25MHz, and it works fine without workaround...

In my experience still the same problem.

After turning power on and code is running, the silicon die still takes some time to warm up, and reach thermal equilibrium.

The Vref source is certainly affected, too.

You are speaking about the internal sensor anyway, don't expect too much benefit.

The value reflects the die temperature, which is only loosely related to the ambient temperature.

Which STM32?

What is the value of calibration register in the correct and in the incorrect case??

JW

dlamb.1
Associate II

STM32L451CC

I did a modification in my firmware in order to let me the possibility to know, without debugger, the value of the register ADC1->CALFACT.

And effectively there is a problem with the calibration:

When the temperature value is correct, CALFACT = 0x44

When the temperature value is not correct, CALFACT = 0

Here are the main steps I am using before the calibration of the ADC:

    /*------- ADC Initialization ------- */

    LL_ADC_Disable( ADC1 );

    LL_ADC_DeInit( ADC1 );

    LL_ADC_CommonDeInit( __LL_ADC_COMMON_INSTANCE( ADC1 ) );

    /* Enable the ADC clock*/

    LL_AHB2_GRP1_EnableClock( (uint32_t)LL_AHB2_GRP1_PERIPH_ADC );

    /* On this STM32 series, setting of these features is conditioned to ADC state:

     * All ADC instances of the ADC common group must be disabled

     * (If multiple ADC are used, the first one sets the common configuration)

     */

    if( __LL_ADC_IS_ENABLED_ALL_COMMON_INSTANCE(ADCxy_COMMON) == 0u )

    {

      /* Common affects all ADCs! */

      PtrOnCommonInitCfg = &CommonInitCfg ;

      (void) LL_ADC_CommonInit( __LL_ADC_COMMON_INSTANCE( ADC1 ), PtrOnCommonInitCfg );

      /* path selection: enable temperature sensor on CH17 */

      LL_ADC_SetCommonPathInternalCh( __LL_ADC_COMMON_INSTANCE( ADC1 ), (uint32_t)( LL_ADC_PATH_INTERNAL_VREFINT + LL_ADC_PATH_INTERNAL_TEMPSENSOR ) );

    }

    PtrOnAdcInitCfg = &AdcInitCfg.tInit ;

    (void) LL_ADC_Init( ADC1, PtrOnAdcInitCfg );

    PtrOnAdcRegInitCfg = &AdcInitCfg.tRegInit ;

    (void) LL_ADC_REG_Init( ADC1, PtrOnAdcRegInitCfg );

    /*

     * Disable the deep power down (enabled by default after reset state), 

     * otherwise the calibration needs to be reset after every time

     * the deep power down state is exited

     */

    LL_ADC_DisableDeepPowerDown( ADC1 );

    /* Enable the internal regulator */

    LL_ADC_EnableInternalRegulator( ADC1 );

    /* Wait for the internal regulator to settle */

    u32Wait = ((LL_ADC_DELAY_INTERNAL_REGUL_STAB_US * ( 48000000 / (100000U * 2U))) / 10U);

    while( u32Wait != 0U )

    {

      u32Wait--;

    }

    /* Run ADC self calibration */

    LL_ADC_StartCalibration( ADC1, (uint32_t) LL_ADC_SINGLE_ENDED );

    /* Wait for calibration to finish */

    while( LL_ADC_IsCalibrationOnGoing( ADC1 ) != 0u )

    { 

      /* wait end of calibration */

    }

I am probably missing a step... but which one?

I don't know, I don't use and don't understand Cube/LL.

Convert the code to registers access and follow the description of calibration process given in RM.

JW

Uwe Bonnes
Principal III

The measured temperature depends also on the buisiness of the CPU. In debug mode, a lot more clocks run uninterrupted, and so more power is needed and chip temperatiure is higher. What is the ambient temperature?

the ambient temperature is 22°C.