cancel
Showing results for 
Search instead for 
Did you mean: 

Turned off ADC still consumes energy

dvhx
Associate II

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);
	  }
  }

 

1 ACCEPTED SOLUTION

Accepted Solutions
dvhx
Associate II

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();

 

View solution in original post

4 REPLIES 4
CTapp.1
Senior II

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

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

>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".
dvhx
Associate II

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();