2025-09-01 5:03 AM
Hello,
I am developing a custom made PCB, for a pico balloon, mounting a STM32F103C8T6. For this project I will need to use low power techniques but before going deep into the Sleep/Standby/Stop mode I was working on understanding and reducing the power consumption of the STM32 during RUN mode.
For these tests, the STM32 has only the decoupling caps in the VDD, VBAT and VDDA pins, and the rest of the PCB are left unpopulated to ensure the current consumption comes only from the STM32.
I reduced the code to the minimum by just setting the Clock configuration for 8 MHz (directly from HSI, PLL and LSI off) , setting all the GPIO to INPUT + PULLDOWN + Set to RESET, configure 1 GPIO as output + set to RESET, and then wait forever in a while(1) loop.
The problem is that, when I compile the project without optimization "-O0" the STM32 consumes 9 mA, however when I set the "-O1" flag the same code runs at 2 mA. In the "-O1" compilation if, instead of an empty while I have a "HAL_Delay(5000);" the consumption goes up to 8mA. And in the "-O0" compilation, if I remove the set to RESET to the GPIO, the power goes to 2mA.
Tests:
The pcb has nothing else conected, I have tried changing the GPIO that I set to RESET and the behaviour is the same. I have tried 2 ICs and the same. I have even exported the GPIO, RCC, PWR register contents and check that in all the compilations the peripherals are configured the same way.
So my main question is: Why is this happening? How the optimization is affecting the code? And how a simple HAL_Delay can add so much current consumption?
Thank you in advance.
The source code can be checked here: https://gist.github.com/LaboratorioGluon/e70cad16cc5aeccde5f150f94bfba9e1
2025-09-01 5:16 AM
> And how a simple HAL_Delay can add so much current consumption?
By busy-waiting in a tight loop for a flag to get set.
The core runs basically at full speed to check a single value each few nanoseconds.
> In the "-O1" compilation ...
I hope you know the semantics of the "volatile" qualifier, or else you might run into "surprises" trying to optimise your code.
Anyway ...
I am developing a custom made PCB, for a pico balloon, mounting a STM32F103C8T6.
The F103 is a relatively old silicon, and most probably not the best choice for a battery-operated low-power application.
ST has some STM32 variants dedicated to low-power, like 'L' and 'U' devices. : https://www.st.com/en/microcontrollers-microprocessors/stm32-ultra-low-power-mcus.html
2025-09-01 5:30 AM
> By busy-waiting in a tight loop for a flag to get set.
The core runs basically at full speed to check a single value each few nanoseconds.
Yes, but comparing to a while(true) loop, the uC is running at full speed in both cases, the main difference would be the read/write accesses to the memory that indeed can cause an increase in power consumption. According to the datasheet the power consumption at 8 MHz processing data from the Flash is 4-5mA while I am getting 8-9mA with all peripheral disabled.
I am not using any optimization in my code, is just plain initialization just to check the STM32 behaviour. And I am selecting the STM32F103 because I have some laying around. Yes, the plan is to update to an STM32L0 for next revision, but I want to understand this chip before.
Also, still dont understand why setting a GPIO to a value would change the current consumption even when the while(1) loop is the same, and the GPIO is not reconfigured in the loop.
2025-09-01 6:33 AM
> According to the datasheet the power consumption at 8 MHz processing data from the Flash is 4-5mA while I am getting 8-9mA with all peripheral disabled.
Which depends on temperature and supply voltage as well.
And the datasheet does specifiy ranges, not exact numbers.
> I am not using any optimization in my code, is just plain initialization just to check the STM32 behaviour.
Just to state it, optimisation will not affect current consumption directly. In other words, the average consumption of "optimised" and "unoptimised" is the same, just the instruction sequence differs.
It will make a difference if you only run at fill speed for specific tasks, and then go back to sleep modes.
Higher optimisation will achieve more throughput per time period.
Which leads to another interesting phenomenon ...
A faster, better core (e.g. a M4F instead of a M3) can save power overall, even if drawing more current during peaks.
You would need to go through your energy budget (battery capacity etc.) in the context of your use case.
2025-09-01 7:10 AM
As @Ozone already said, if you're starting a project where very low power is a key requirement, then an F1 is almost certainly not the best choice.
@LabGluon wrote:Why is this happening? How the optimization is affecting the code?
Try stepping the code in each case - see for yourself what the difference is!
(you might need to step at the machine instruction level, rather than the source line level).
I would strongly suggest that the you get an STLINK-V3PWR or X-NUCLEO-LPM01A (or similar) so you can see exactly what's happening with the current consumption - a simple meter is not going to give useful detail.