cancel
Showing results for 
Search instead for 
Did you mean: 

How to check Stop mode current consumption on Nucleo-L073 board

PSaga.1
Associate II

Hello,

I'm working on a low-power application using the STM32L073 microcontroller and aiming to achieve a current consumption of around 3.5 µA in Stop mode. Here are the steps I've followed so far:

  1. Power Connections: I'm powering the microcontroller directly via VDD with a voltage of 3.3V.

  2. Nucleo Board Configuration: I have removed the JP5 connection on my Nucleo-L073 board along with the CN2 jumper connections.

Despite my efforts, the current consumption I'm observing ranges between 260 µA to 280 µA, which is significantly higher than my target.

Here are the crucial parts of the code I've used to measure the current consumption:

 

 

#include "main.h"

// Function prototypes
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
void HW_EnterStopMode(void);
void Error_Handler(void); // Function prototype for Error_Handler

int main(void) {
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();

    // Main loop
    while (1) {
        // Enter Stop mode
        HW_EnterStopMode();
    }
}

void HW_EnterStopMode(void) {
    // Suspend SysTick to prevent waking up from interrupts
    HAL_SuspendTick();

    // Clear the wake-up flag
    __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);

    // Enter Stop mode with low power regulator ON and wait for interrupt
    HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);

    // After waking up, reconfigure the system clock
    SystemClock_Config();

    // Resume SysTick
    HAL_ResumeTick();
}

static void MX_GPIO_Init(void) {
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    // Enable GPIO clock
    __HAL_RCC_GPIOB_CLK_ENABLE();

    // Configure GPIO pin for external interrupt (e.g., button)
    GPIO_InitStruct.Pin = GPIO_PIN_1; // Change as needed for your setup
    GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    // Enable and set EXTI line 0 and 1 Interrupt to the lowest priority
    HAL_NVIC_SetPriority(EXTI0_1_IRQn, 2, 0);
    HAL_NVIC_EnableIRQ(EXTI0_1_IRQn);
}

// Interrupt handler for external interrupt
void EXTI0_1_IRQHandler(void) {
    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_1); // Clear the interrupt flag
}

void SystemClock_Config(void) {
    // Set the system clock to use MSI or HSI at a low frequency (e.g., 100 kHz)
    RCC_OscInitTypeDef RCC_OscInitStruct = {0};

    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
    RCC_OscInitStruct.MSIState = RCC_MSI_ON;
    RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6; // 100 kHz
    RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT;

    if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
        Error_Handler(); // Call Error_Handler on failure
    }

    RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

    RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1;
    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_MSI;
    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;

    if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK) {
        Error_Handler(); // Call Error_Handler on failure
    }
}

// Error handler function definition
void Error_Handler(void) {
    /* USER CODE BEGIN Error_Handler_Debug */

    // User can add their own implementation to report the HAL error return state.

    __disable_irq(); // Disable all interrupts

    while (1) {
        // Stay in this loop if an error occurs.
        // You can add a mechanism to blink an LED or send a message here.
    }

    /* USER CODE END Error_Handler_Debug */
}

 

 

Am I missing something in my setup or code? Any insights on how to achieve single-digit µA consumption for my application would be greatly appreciated. Thank you!

 

Hope that helps! Do you want me to assist further on optimizing your code or setup?

5 REPLIES 5

You need to look very carefully at the schematics to identify all possible paths for current leakage.

eg, CN2 disconnects the SWD lines from the ST-Link - but not the reset line.

There may be a connection to the ST-Link for measuring the target voltage.

Probably the easiest way with this Nucleo board is to break off the ST-Link part completely:

https://community.st.com/t5/stm32-mcus-boards-and-hardware/leakage-current-potentially-via-stlink-pins-on-demo-board/m-p/693585/highlight/true#M20109

 

Adventures in low-power measurement with ST boards:

https://community.st.com/t5/stm32-mcus-wireless/excess-current-consumption-running-b-l072z-lrwan1-from-battery/td-p/322961

 

#SleepCurrentConsumption #CurrentConsumption #LowPower

PSaga.1
Associate II

Hello Andrew,

I have looked into the schematics and observed USART, MCO, NRST, SWO pins connected over solder bridges to the ST Link where CN2 separates out the required programming pins. So I take off the SBs then you think I will be able to achieve the required current consumption? Thanks for the support.

PSaga.1
Associate II

I have taken OFF the SBs going to ST-LINK and now observed that the power consumption is 0.44 u amps. NRST is the culprit is what I see but this current feels very low is it correct? The code I have used is this

 

/**
  ******************************************************************************
  * @file    PWR/PWR_STOP/Src/main.c
  * @author  MCD Application Team
  * @brief   This sample code shows how to use STM32L0xx PWR HAL API to enter
  *          and exit the stop mode with an EXTI.
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2016 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "main.h"

/** @addtogroup STM32L0xx_HAL_Examples
  * @{
  */

/** @addtogroup PWR_STOP
  * @{
  */

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void SystemPower_Config(void);

/* Private functions ---------------------------------------------------------*/

/**
  * @brief  Main program
  *   None
  * @retval None
  */
int main(void)
{
  /* STM32L0xx HAL library initialization:
       - Configure the Flash prefetch, Flash preread and Buffer caches
       - Systick timer is configured by default as source of time base, but user 
             can eventually implement his proper time base source (a general purpose 
             timer for example or other time source), keeping in mind that Time base 
             duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and 
             handled in milliseconds basis.
       - Low Level Initialization
     */
  HAL_Init();

  /* Configure the system clock to 2 MHz */
  SystemClock_Config();

  /* Configure the system Power */
  SystemPower_Config();

  while (1)
  {
    /* Insert 5 second delay */
    HAL_Delay(5000);

    /* User push-button (lines 4 to 15) will be used to wakeup the system from STOP mode */
    BSP_PB_Init(BUTTON_KEY, BUTTON_MODE_EXTI);

    /* Enable Power Control clock */
    __HAL_RCC_PWR_CLK_ENABLE();
    
      /* Enter Stop Mode */
    HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);

    /* Configures system clock after wake-up from STOP */
    SystemClock_Config();
  }
}

/**
  * @brief  System Clock Configuration
  *         The system Clock is configured as follow : 
  *            System Clock source            = MSI
  *            SYSCLK(Hz)                     = 2000000
  *            HCLK(Hz)                       = 2000000
  *            AHB Prescaler                  = 1
  *            APB1 Prescaler                 = 1
  *            APB2 Prescaler                 = 1
  *            Flash Latency(WS)              = 0
  *            Main regulator output voltage  = Scale3 mode
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  
  /* Enable MSI Oscillator */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
  RCC_OscInitStruct.MSIState = RCC_MSI_ON;
  RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_5;
  RCC_OscInitStruct.MSICalibrationValue=0x00;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct)!= HAL_OK)
  {
    /* Initialization Error */
    while(1); 
  }
  
  /* Select MSI as system clock source and configure the HCLK, PCLK1 and PCLK2 
     clocks dividers */
  RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_MSI;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;  
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;  
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0)!= HAL_OK)
  {
    /* Initialization Error */
    while(1); 
  }
  /* Enable Power Control clock */
  __HAL_RCC_PWR_CLK_ENABLE();
  
  /* The voltage scaling allows optimizing the power consumption when the device is 
     clocked below the maximum system frequency, to update the voltage scaling value 
     regarding system frequency refer to product datasheet.  */
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3);
  
}

/**
  * @brief  System Power Configuration
  *         The system Power is configured as follow : 
  *            + Regulator in LP mode
  *            + VREFINT OFF, with fast wakeup enabled
  *            + MSI as SysClk after Wake Up
  *            + No IWDG
  *            + Wakeup using EXTI Line (User push-button PC.13)
  *   None
  * @retval None
  */
static void SystemPower_Config(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;

  /* Enable Power Control clock */
  __HAL_RCC_PWR_CLK_ENABLE();

  /* Enable Ultra low power mode */
  HAL_PWREx_EnableUltraLowPower();
  
  /* Enable the fast wake up from Ultra low power mode */
  HAL_PWREx_EnableFastWakeUp();

  /* Select MSI as system clock source after Wake Up from Stop mode */
  __HAL_RCC_WAKEUPSTOP_CLK_CONFIG(RCC_STOP_WAKEUPCLOCK_MSI);
  
  /* Enable GPIOs clock */
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOD_CLK_ENABLE();
  __HAL_RCC_GPIOH_CLK_ENABLE();
  __HAL_RCC_GPIOE_CLK_ENABLE();

  /* Configure all GPIO port pins in Analog Input mode (floating input trigger OFF) */
  /* Note: Debug using ST-Link is not possible during the execution of this   */
  /*       example because communication between ST-link and the device       */
  /*       under test is done through UART. All GPIO pins are disabled (set   */
  /*       to analog input mode) including  UART I/O pins.           */
  GPIO_InitStructure.Pin = GPIO_PIN_All;
  GPIO_InitStructure.Mode = GPIO_MODE_ANALOG;
  GPIO_InitStructure.Pull = GPIO_NOPULL;

  HAL_GPIO_Init(GPIOA, &GPIO_InitStructure); 
  HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);
  HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
  HAL_GPIO_Init(GPIOD, &GPIO_InitStructure);
  HAL_GPIO_Init(GPIOH, &GPIO_InitStructure);
  HAL_GPIO_Init(GPIOE, &GPIO_InitStructure);

  /* Disable GPIOs clock */
  __HAL_RCC_GPIOA_CLK_DISABLE();
  __HAL_RCC_GPIOB_CLK_DISABLE();
  __HAL_RCC_GPIOC_CLK_DISABLE();
  __HAL_RCC_GPIOD_CLK_DISABLE();
  __HAL_RCC_GPIOH_CLK_DISABLE();
  __HAL_RCC_GPIOE_CLK_DISABLE();
}

/**
  * @brief GPIO EXTI callback
  *  None
  * @retval None
  */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
  /* Clear Wake Up Flag */
  __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
}

/**
  * @brief SYSTICK callback
  *  None
  * @retval None
  */
void HAL_SYSTICK_Callback(void)
{
  HAL_IncTick();
}

#ifdef  USE_FULL_ASSERT

/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  *   file: pointer to the source file name
  *   line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  /* Infinite loop */
  while (1)
  {
  }
}
#endif

/**
  * @}
  */

/**
  * @}
  */

 

 which was an example code from CubeMX for STOP mode for EWARM. I am worried if everything is correct. Thanks and regards. 


@PSaga.1 wrote:

now observed that the power consumption is 0.44 u amps ... but this current feels very low is it correct? . 


LOL - don't often get people complaining that their sleep current is too low !

Anyhow, what does the Datasheet say?

Sarra.S
ST Employee

Hello @PSaga.1

Normally, using an STM32L073, the typical power consumption is 0.43µA as per the datasheet: 

SarraS_0-1737713778303.png

 

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.