8 years ago.

STM32 Underclocking for energy saving

Hi,

I'm looking for ways to minimize the power consumption of the STM32F031K. I'm already putting into sleep() most of the time, but my application doesn't really require the full 48 Mhz capability and would work just as well with 8Mhz or even 1 Mhz. How exactly can I reduce the PLL multiplier to minimize the clock speed?

1 Answer

8 years ago.

There is some information here from the Disco-L476 that may help.

However I find in most cases if the system spends most of its time in deepsleep mode, running the wake up code at its fastest gives a more energy efficient solution. If I remember, this code dropped the run current consumption by half (around 6mA). If your process takes twice as long with a lower clock speed the advantage has been lost. But that does depend on the processes running.

For best efficiency deeplseep is required to drop to around 5uA. Not sure if the STM32F031K will go that low, but the best low power ST MCU's are the L series, L476 proving the clear winner on MBED with good speed and low power in deepsleep mode. Also the LowPowerConfiguration function appears not to be needed here, unlike the F series, the ports do not need to be put into Analog Input mode. At least that's what I'm finding. The Nucleo-L476 also appears to be one of the lowest priced boards

https://developer.mbed.org/teams/ST/code/DISCO_L476VG_Sleep/file/e99d70686026/main.cpp

Accepted Answer

Paul, correct me if I am wrong but deep sleep does not maintain RAM, correct? I need to be able to access values. The equivalent L series is the stm32L031 but I do not think that is yet supported by Mbed nor are the smaller QFPN package version available on digikey which is problematic. That's why I'm trying to reduce the power usage for the time being on the F031K.

posted by Krzysztof Sitko 03 Apr 2016

I believe on one target they currently implemented it wrong, but on all others, including the STMs, deepsleep maintains RAM state. Sleep disables the CPU core and nothing else, deepsleep disables everything that receives a clock, and on the properly implemented one also powers down the flash memory (which does retain its state obviously), but the RAM is retained.

You do need to take into account that you cannot wake up using any interrupt that requires a peripheral to be clocked. So for example Serial interrupt won't work, and on most targets, including STM32s, also Ticker interrupts are disabled. The WakeUp lib can be used to replace this. Again on most targets, including the STMs, the default InterruptIn is capable of waking it from deepsleep. (Note that depending on your clock setup and how screwed up they made the clock setup code on your board it might take stupidly long to wake up, dunno if they already fixed that in latest mbed versions).

Still reducing clock speed can also be a good option imo. The best option is to delete your mbed lib, import mbed-dev. Then go to targets/cmsis/stm/mcu family/your mcu/xxxxx_system.c/.h. Here the startup is defined, which is mainly setting your clock correctly. You can also change the PLL ratios. (Of course you can also do it after boot in your main code, but you might as well put it good from start, and it reduces risk on some possible issues. Do also make sure you set your SystemCoreClock variable correctly). (Insta-edit: If you want to run it at such lower speeds just completely disable the PLL and run directly from the crystal/IRC. I have for example a Teensy 3.1 that runs directly from its crystal to reduce power consumption).

Finally, there is also code there that checks if there is an external clock, a crystal, or none. This code is also run after it wakes from deepsleep, so if needed you can optimize it by only enabling the option you are using.

posted by Erik - 03 Apr 2016

Deepsleep and Erik's WakeUp lib works just fine, the Deepsleep level on MBED, at least the Targets I have tried will only go down to the level that does retain RAM. But the F series are not really good for low power and the wake up time is all over the place. Whereas the L476 does work very well. But if you want 32QFN package and low power, then I would look at the Freescale(NXP) KL25Z. You will get around 3uA in deepsleep, wake's up fast and much easier to configure the Clock setup. I use these with 32KHz clock crystal (no USB mode), this mode is already available in the MBED-DEV library and should run at around 7mA. This will also give you a working RTC in this mode. Thanks to a lot of work by Erik, this platform is probably bug free. I have used 32QFN chips but prefer to use 64LQFP, not too much difference in overall board design size and much easier to work with.

posted by Paul Staron 03 Apr 2016

Erik,

I've chosen only the clock source option and made the following changes which have reduced to clock down to 8Mhz.

title

RCC_OscInitStruct.PLL.PLLState = RCC_PLL_OFF;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;

Just to be sure are there any other changes I would could make to reduce clock power draw?

Also does your wakeup library work on the STM32's without a 32.768kHz crystal?.

posted by Krzysztof Sitko 14 Apr 2016