cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L151xB Low Power Modes Current Consumption

andy23
Associate II
Posted on January 26, 2015 at 16:12

Dear folk,

I am not able getting the desired power consumption for STM32L151xB (48 Pins) using the predestined STM32L1xx_StdPeriph_Examples/PWR/CurrentConsumption.

More detailed, I need to use a Low Power mode which allows me to wake the controler over USART, which led me to Low Power sleep (Wakeup on any interrupt). As said, the problem is neither the code, nor the LPM itself, I am just not able to reach the desired current consumption of <10�A. With the attached code it is just possible to reach ~50�A.

FYI, during normal run, my clocks are using HSE on 8MHz (VCO range 2). This posted code is the ''reduced'' code of the Example which gets me 53�A, the least I can get with those examples.

I'm trying this for a while now, changing clocks and so on, but cannot reach my goal. Could you please take a look and give me some advice? Thanks in advance.

Best regards,

Andy

Code:

/* Configure the System Clock to MSI Range 0 (65KHz). ----------------------*/

      GPIO_InitTypeDef GPIO_InitStructure;

      /* RCC system reset */

      RCC_DeInit();

      

      /* Flash 0 wait state */

      FLASH_SetLatency(FLASH_Latency_0);

      

      /* Disable Prefetch Buffer */

      FLASH_PrefetchBufferCmd(DISABLE);    

      

      /* Disable 64-bit access */

      FLASH_ReadAccess64Cmd(DISABLE);

      

      /* Enable the PWR APB1 Clock */

      RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);

      

      /* Select the Voltage Range 2 (1.5V) */

      PWR_VoltageScalingConfig(PWR_VoltageScaling_Range2);

      

      /* Wait Until the Voltage Regulator is ready */

      while(PWR_GetFlagStatus(PWR_FLAG_VOS) != RESET)

      {

      }

      

      /* HCLK = SYSCLK/2 = ~32KHz */

      RCC_HCLKConfig(RCC_SYSCLK_Div2);

      

      /* PCLK2 = HCLK */

      RCC_PCLK2Config(RCC_HCLK_Div1);

      

      /* PCLK1 = HCLK */

      RCC_PCLK1Config(RCC_HCLK_Div1);

      

      /* Set MSI clock range to 65.536KHz */

      RCC_MSIRangeConfig(RCC_MSIRange_0);

      

      /* Select MSI as system clock source */

      RCC_SYSCLKConfig(RCC_SYSCLKSource_MSI);

      

      /* Wait till PLL is used as system clock source */

      while (RCC_GetSYSCLKSource() != 0x00)

      {}

      

      /* Configure all GPIO as analog to reduce current consumption on non used IOs */  

      /* Enable GPIOs clock */

      RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB | RCC_AHBPeriph_GPIOC |

                            RCC_AHBPeriph_GPIOD , ENABLE);

      

      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;

      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;

      GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;

      GPIO_Init(GPIOC, &GPIO_InitStructure);

      GPIO_Init(GPIOD, &GPIO_InitStructure);

      GPIO_Init(GPIOA, &GPIO_InitStructure);

      GPIO_Init(GPIOB, &GPIO_InitStructure);

      

      /* Disable GPIOs clock */

      RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB | RCC_AHBPeriph_GPIOC |

                            RCC_AHBPeriph_GPIOD , DISABLE);

      

      

      /* Enable The ultra Low Power Mode */

      PWR_UltraLowPowerCmd(ENABLE);

      

      /* Enable the power down mode during Sleep mode */

      FLASH_SLEEPPowerDownCmd(ENABLE);

      

      /* Request to enter SLEEP mode with regulator in low power mode */

      PWR_EnterSleepMode(PWR_Regulator_LowPower, PWR_SLEEPEntry_WFI);

      

      /* Infinite loop */

      while (1){}

#low-power #stm32 #lpm #current
11 REPLIES 11
stm322399
Senior
Posted on January 26, 2015 at 16:22

Andy, my easiest guess is that you need to disable input schmidt triggers. Have a look to the following:

RI->HYSCR1 = 0xFFFFFFFF;
RI->HYSCR2 = 0xFFFFFFFF;
RI->HYSCR3 = 0xFFFFFFFF;

Hope this help.
andy23
Associate II
Posted on January 26, 2015 at 16:27

Thank you for your fast answer.

In the reference manual, you can find that schmitt triggers are automatically deactivated when the I/O port ist programmed as analog configuration. (RM0038, rev. 10, p177).

But many thanks for your effort 🙂

stm322399
Senior
Posted on January 26, 2015 at 17:01

My second guess: configuration of port H pins (when HSE is off).

Does the power consumption vary if you touch I/O your finger ?

andy23
Associate II
Posted on January 26, 2015 at 20:17

There is no Port H.. this is the one with 48 pins (4 ports).

No, the consumption varys not.

stm322399
Senior
Posted on January 26, 2015 at 20:46

My datasheet (rev.5 Figure 7) says that 48-pin devices have PH0-OSC_IN and PH1-OSC_OUT respectively on pin 3 and 4.

Those are real Port H pins, and I bet it is worth to configure them when HSE is disabled.

andy23
Associate II
Posted on January 27, 2015 at 08:19

Laurent,

the code crashes when trying to configure port H (Hardware_Error) which states that you cannot be right. The crystal is connected to this pins, and as I found out later yesterday, I should use downclocked MSI when in LPM. Keeping you in touch.

I would appreciate more ideas and proposals.

Many thanks

stm322399
Senior
Posted on January 27, 2015 at 09:11

These line has been of some help in my experiments (64-pin STM32L152 with LCD on consuming 6µA):

RCC->AHBLPENR = 0x00010000; // Keep SRAM running !!!
RCC->APB1LPENR = 0;
RCC->APB2LPENR = 0;

andy23
Associate II
Posted on January 27, 2015 at 09:26

This sounds logical. I already tried something like this before but couldnt get any difference. Do you mind giving me your whole code of your STM32L152 project so maybe I can compare? I really guess it is just a clock problem here.

stm322399
Senior
Posted on January 27, 2015 at 10:02

Note that my GPIO configuration may differs from your one because of the board (STM32L disco).

Note that COMP peripheral must be enabled to write HYSCRx registers. Note that main is called from startup_stm32l1xx_md.s, and that SystemInit has no modification.

int main(void)
{
RCC->AHBENR =
RCC_AHBPeriph_GPIOA|
RCC_AHBPeriph_GPIOB|
RCC_AHBPeriph_GPIOC|
RCC_AHBPeriph_GPIOD|
RCC_AHBPeriph_GPIOH|
RCC_AHBPeriph_SRAM;
RCC->APB1ENR =
RCC_APB1Periph_PWR|
RCC_APB1Periph_COMP;
RCC->APB2ENR = 0;
GPIOA->ODR = 0;
GPIOB->ODR = 0;
GPIOC->ODR = 0<<
13
; // Set to 1 to halt idd counter, or do not supply vdd
GPIOD->ODR = 0;
GPIOH->ODR = 0;
GPIOA->PUPDR = 0;
GPIOB->PUPDR = 0;
GPIOC->PUPDR = 0;
GPIOD->PUPDR = 0;
GPIOH->PUPDR = 0;
GPIOA->AFR[0]= 0x0000bbb0;
GPIOA->AFR[1]= 0xb0000bbb;
GPIOB->AFR[0]= 0x00bbb000;
GPIOB->AFR[1]= 0xbbbbbbbb;
GPIOC->AFR[0]= 0xbb00bbbb;
GPIOC->AFR[1]= 0x0000bbbb;
GPIOA->MODER = 0xbd6af4a8;
GPIOB->MODER = 0xaaaa5a8f;
GPIOC->MODER = 0xf5aaafaa;
GPIOD->MODER = 0x55555555;
GPIOH->MODER = 0x55555555;
// Shut GPIO
RCC->AHBENR = RCC_AHBPeriph_SRAM;
// Turn low power
RI->HYSCR1 = 0xFFFFFFFF;
RI->HYSCR2 = 0xFFFFFFFF;
RI->HYSCR3 = 0xFFFFFFFF;
RCC->AHBLPENR = 0x00010000; // Keep SRAM running !!!
RCC->APB1LPENR = 0;
RCC->APB2LPENR = 0;
PWR->CR = ( PWR->CR & ~PWR_CR_PDDS ) | PWR_CR_LPSDSR | PWR_CR_ULP;
SCB->SCR = SCB->SCR | SCB_SCR_SLEEPDEEP;
__WFE();
while(1);
return 0;
}