Skip to main content
Associate II
May 29, 2025
Solved

Turned off ADC still consumes energy

  • May 29, 2025
  • 3 replies
  • 447 views

I'm using STM32L011F4P6 in CubeIDE. I toggle digital output pin PA2 hi/low every 10ms just to see if it works and it consumes 80uA when it runs. When I set another pin PA0 as analog input, the current consumption rises to 315uA. This is OK as I understand that it needs some energy to do ADC conversion. However I only need to measure analog input once and so I want to turn ADC off. I tried HAL_ADC_Stop(&hadc); HAL_ADC_DeInit(&hadc); however it does not returns consumption to 80uA only to 280uA, so something related to ADC is still on and consuming energy. I really want to go back to 80uA when I don't need ADC anymore. I tried enabling Auto Off it had no effect.

 

 int x = 0;
 while (1)
 {
	 // toggle digital pin every 10ms
	 HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_2);
	 HAL_Delay(10);
	 x++;

	 // at 5s mark (10ms*500 = 5s) turn off adc
	 if (x == 500) {
		 HAL_ADC_Stop(&hadc);
		 HAL_ADC_DeInit(&hadc);
	 }
 }

 

Best answer by dvhx

I repeated all measurements and compared project directories, this time I measured with ST-LINK disconnected during current measurement.


Here is connections of STM32L011F4P6:
- Pin 1 (boot) to ground
- Pin 4 (nrst) 100nF cap to ground.
- Pin 5 (VDDA) to 3.0V (same as pin 16)
- Pin 8 (PA2) set as GPIO_Output in IOC file
- Pin 15 (VSS) to GND
- Pin 16 (VDD) to 3.0V
- Pin 19 and Pin 20 are SWD, connected only during programming, not during current measurement.
- 100nF cap and 10uF cap between VDD and VSS

 

First test:

- in IOC all pins off expcept PA2 which is gpio output
- in main infinite loop:
  HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_2);
  HAL_Delay(10);
- When run this consumes 51uA with 3.0V VDD

Second test:
- in IOC I enabled pin PA0 to be analog input
- no other change in code but MX_ADC_Init appeared
- stm32l0xx_hal_conf.h now have uncommented #define HAL_ADC_MODULE_ENABLED
- I'm not actually measuring anything analog, just enabled pin
- When run this consumes 286uA with 3.0V VDD
- Src/Main.c enabled HSI oscillator, this IMHO explains the current raise:

RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_MSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;

previously it was:

RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;

So it changes the oscillator from MSI to HSI when ADC is used and that causes the raise in current consumption. Now I need to return back to MSI when I'm done measuring ADC and it should return back to 51uA.

Update: following code indeed switches power consumption back to 51uA:

 // Turn off ADC
 HAL_ADC_Stop(&hadc);
 HAL_ADC_DeInit(&hadc);
 // Switch back to MSI
 // Enable MSI oscillator
 __HAL_RCC_MSI_ENABLE();
 // Wait until MSI is ready
 while (__HAL_RCC_GET_FLAG(RCC_FLAG_MSIRDY) == RESET);
 // Select MSI as the system clock source
 __HAL_RCC_SYSCLK_CONFIG(RCC_SYSCLKSOURCE_MSI);
 // Wait until MSI is used as the system clock source
 while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_MSI);
 // (Optional) Disable HSI if no longer needed
 __HAL_RCC_HSI_DISABLE();

 

3 replies

CTapp.1
Senior III
May 29, 2025

I'm not familiar with the HAL, but do you also need to disable the ADC clock?

All posts are made in a personal capacityMISRA C++ ChairMISRA C WG MemberDirector The MISRA Consortium Limited (TMCL)
dvhxAuthor
Associate II
May 29, 2025

What is the correct way to disable ADC clock? I tried __HAL_RCC_ADC1_CLK_DISABLE(); and it had no effect, still 280uA.

AScha.3
Super User
May 29, 2025

>When I set another pin PA0 as analog input, the current consumption rises to 315uA

Really , when pin is analog mode ?  -- It should need no power then !

So at first : find out, when the current is raising : on init, on setting pin..., on starting ADC.

And verify, its not another (unused) pin on same port, thats floating and so consumes power.

If its sure, the ADC is the cause and nothing else on this port:

Then 2 ways to find out , what needs the power (and then know, what to switch off):

- read rm, what is enabled , when using ADC (power to ADC, clock to ADC, battery sensor, int. reference, pin...).

- debug the HAL call, that starts increased power need, see, whats switched ON; 

...then you know, what you have to switch off, for lowest power. And to switch on, to use the ADC again.

"If you feel a post has answered your question, please click ""Accept as Solution""."
dvhxAuthorBest answer
Associate II
May 30, 2025

I repeated all measurements and compared project directories, this time I measured with ST-LINK disconnected during current measurement.


Here is connections of STM32L011F4P6:
- Pin 1 (boot) to ground
- Pin 4 (nrst) 100nF cap to ground.
- Pin 5 (VDDA) to 3.0V (same as pin 16)
- Pin 8 (PA2) set as GPIO_Output in IOC file
- Pin 15 (VSS) to GND
- Pin 16 (VDD) to 3.0V
- Pin 19 and Pin 20 are SWD, connected only during programming, not during current measurement.
- 100nF cap and 10uF cap between VDD and VSS

 

First test:

- in IOC all pins off expcept PA2 which is gpio output
- in main infinite loop:
  HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_2);
  HAL_Delay(10);
- When run this consumes 51uA with 3.0V VDD

Second test:
- in IOC I enabled pin PA0 to be analog input
- no other change in code but MX_ADC_Init appeared
- stm32l0xx_hal_conf.h now have uncommented #define HAL_ADC_MODULE_ENABLED
- I'm not actually measuring anything analog, just enabled pin
- When run this consumes 286uA with 3.0V VDD
- Src/Main.c enabled HSI oscillator, this IMHO explains the current raise:

RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_MSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;

previously it was:

RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;

So it changes the oscillator from MSI to HSI when ADC is used and that causes the raise in current consumption. Now I need to return back to MSI when I'm done measuring ADC and it should return back to 51uA.

Update: following code indeed switches power consumption back to 51uA:

 // Turn off ADC
 HAL_ADC_Stop(&hadc);
 HAL_ADC_DeInit(&hadc);
 // Switch back to MSI
 // Enable MSI oscillator
 __HAL_RCC_MSI_ENABLE();
 // Wait until MSI is ready
 while (__HAL_RCC_GET_FLAG(RCC_FLAG_MSIRDY) == RESET);
 // Select MSI as the system clock source
 __HAL_RCC_SYSCLK_CONFIG(RCC_SYSCLKSOURCE_MSI);
 // Wait until MSI is used as the system clock source
 while (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_MSI);
 // (Optional) Disable HSI if no longer needed
 __HAL_RCC_HSI_DISABLE();