In this tutorial, we’ll discuss The STM32 Sleep Mode, how to enter sleep mode, how to exit from sleep, Wakeup Pin in STM32 microcontrollers, and other wakeup sources with some code examples and a full test project. Without further ado, let’s get right into it!
Table of Contents
- STM32 Sleep Mode
- STM32 Enter Sleep Mode
- STM32 Wakeup (Exit) Sleep Mode
- STM32 Sleep On Exit
- STM32 Sleep Mode Example Code Project
- Wrap Up
STM32 Sleep Mode
In Sleep mode, the STM32 microcontroller’s CPU clock is turned OFF but all the other clock sources are active. All peripherals will continue to operate normally and can wake up the CPU when an interrupt/event occurs.
For the STM32L432KC target microcontroller, in Sleep Mode, the current consumption is:
- At voltage scaling Range 1 & SysCLK=80MHz, the current draw is 2.23mA
- At voltage scaling Range 2 & SysCLK=100kHz, the current draw is 0.11mA
As you might have noticed, reducing the SysClk frequency will significantly reduce the current consumption in sleep mode. However, it might not meet the timing requirements of certain applications, so you need to reach a compromise.
To put things into perspective, this same target microcontroller (STM32L432KC) draws 8.5mA of current while operating in the Run Mode at full speed (80MHz). Therefore, going into Sleep Mode at the same clock of 80MHz feeding all buses/peripherals except for the CPU, will already set you at a quarter of the current consumption of the normal Run mode.
While debugging a target MCU in sleep mode, make sure you’re working in Range 1 by checking the voltage regulator scale configuration in CubeMX.
STM32 Enter Sleep Mode
By entering sleep mode, the STM32 microcontroller is placed in a low-power state while retaining the contents of SRAM and registers. In this mode, the CPU stops executing instructions, but peripherals, interrupts, and the system clock can remain active depending on the configuration.
To enter Sleep Mode in STM32 microcontrollers, we should first stop the Systick timer. Because if we leave it ON, it’ll wake up the CPU with its interrupt signals every 1ms. So we need to call the HAL_SuspendTick() function first.
Then we can use the HAL_PWR_EnterSLEEPMode() function to enter the sleep mode. You can configure whether the system wakes up via WFI (Wait For Interrupt) or WFE (Wait For Event) instructions.
Here is a code example for entering the STM32 Sleep Mode:
1 2 | HAL_SuspendTick(); HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI); |
You need to Stop The SysTick Timer as it will wake up the CPU every 1ms through its interrupt signal. And don’t forget to resume its operation upon waking up to make sure any systick-dependent software components will continue to operate normally.
STM32 Wakeup (Exit) Sleep Mode
Any interrupt signal will cause the CPU to exit from the sleep mode and go back to normal operation. Therefore, we can use something like EXTI or a specific timer to wake up the CPU on purpose and resume the Systick timer operation by calling the HAL_ResumeTick() function.
This is an example code for exiting the sleep mode upon receiving an EXTI interrupt on the GPIO1 line.
1 2 3 4 5 6 7 8 | void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { if(GPIO_Pin == GPIO_PIN_1) // If The INT Source Is EXTI Line1 (A1 Pin) { // CPU Has Exited From Sleep Mode, Resume The SysTick! HAL_ResumeTick(); } } |
STM32 Sleep On Exit
The Sleep On Exit feature in STM32 microcontrollers is a low-power mechanism that allows the device to automatically enter Sleep mode after exiting an interrupt service routine (ISR).
This means the CPU will run only in interrupt mode and anything in the main while(1) loop will not be executed at all.
This is how to enable the STM32 Sleep on Exit:
1 | HAL_PWR_EnableSleepOnExit(); |
Call this function below to disable the Sleep On Exit feature:
1 | HAL_PWR_DisableSleepOnExit(); |
STM32 Sleep Mode Example Code Project
In this example project, we’ll configure our STM32L432KC microcontroller to run at full speed (80MHz) for 1 second. Then it’ll automatically switch to sleep mode.
Upon receiving an EXTI interrupt on the GPIO1 pin from a push button, the system will switch back to the Run Mode. And it’ll keep toggling between both modes each time the interrupt button is pressed.
The behavior of the system can be easily observed in a debug session by observing a counter variable and a single breakpoint.
Step #1
Open STM32CubeMX, create a new project, and select the target microcontroller. For me, it’s (STM32L432KC)
Step #2
Configure a GPIO pin in EXTI input pull-down mode (button). I’ll use A1 pin (EXTI1), you can choose any EXTI-capable pin.
Enable The EXTI interrupt from the NVIC configuration tab.
Step #3
Go to the Clock configuration page and select the internal HSI+PLL as a clock source to give you the maximum SysClk of 80MHz (in my case). This is the base full-speed run mode.
You can however, select the internal MSI which can give you a low-frequency clock source (2MHz down to 100kHz), if needed.
Step #4
Name & Generate The Project Initialization Code For CubeIDE or The IDE You’re Using.
STM32 Sleep Mode Example Code
Here is The Application Code For This LAB (main.c)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | /* * LAB Name: STM32 Sleep Mode Test Project * Author: Khaled Magdy * For More Info Visit: www.DeepBlueMbedded.com */ #include "main.h" volatile uint8_t SleepMode_Activated = 0; volatile uint8_t EnterSleepFlag = 0; uint8_t Counter = 0; void SystemClock_Config(void); static void MX_GPIO_Init(void); int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); HAL_Delay(1000); SleepMode_Activated = 1; HAL_SuspendTick(); HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI); while (1) { if(EnterSleepFlag) { // Re-Enter Sleep Mode! EnterSleepFlag = 0; SleepMode_Activated = 1; HAL_SuspendTick(); HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI); } Counter++; } } void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { if(GPIO_Pin == GPIO_PIN_1) // If The INT Source Is EXTI Line1 (A1 Pin) { if(SleepMode_Activated == 1) { // CPU Has Exited From Sleep Mode, Resume The SysTick! HAL_ResumeTick(); SleepMode_Activated = 0; } else { // Re-Enter Sleep Mode! EnterSleepFlag = 1; } } } |
STM32 Sleep Mode Example Testing
To test this project, you can place one break point in the location indicated below and keep clicking on the run button in the debug menu while monitoring the counter variable’s value in the live expressions window.
You can see that the system starts in run mode, then after 1s, it goes into sleep mode, therefore, the counter variable stops counting and the breakpoint will not be reached again.
By pressing the A0 (EXTI1) push button, your system will get out of sleep mode and back to run mode. Now, any click on the debug continue button will increment the counter variable by 1 and it’ll keep counting each time will click on the “continue” debug button.
One more click on the push button will bring the system back to sleep, the counter will stop counting, and the breakpoint won’t be reached again. Further clicks on the push button will keep toggling the system between run & sleep modes.
Sleep Mode can’t be entered from the interrupt handler context. Therefore, the flag variable EnterSleepFlag was used to handle the sleep mode entry operation within the main function context.
We could’ve used the STM32 Sleep-On-Exit feature to achieve similar behavior, but it would have been much harder to observe since we’re depending on a counter variable’s change in the main while(1) that won’t be executed if we were to use the sleep-on-exit feature.
Required Parts For STM32 Examples
All the example Code/LABs/Projects in this STM32 Series of Tutorials are done using the Dev boards & Electronic Parts Below:
QTY. | Component Name | Amazon.com | AliExpress | eBay |
1 | STM32-F103 BluePill Board (ARM Cortex-M3 @ 72MHz) | Amazon | AliExpress | eBay |
1 | Nucleo-L432KC (ARM Cortex-M4 @ 80MHz) | Amazon | AliExpress | eBay |
1 | ST-Link V2 Debugger | Amazon | AliExpress | eBay |
2 | BreadBoard | Amazon | AliExpress | eBay |
1 | LEDs Kit | Amazon & Amazon | AliExpress | eBay |
1 | Resistors Kit | Amazon & Amazon | AliExpress | eBay |
1 | Capacitors Kit | Amazon & Amazon | AliExpress & AliExpress | eBay & eBay |
1 | Jumper Wires Pack | Amazon & Amazon | AliExpress & AliExpress | eBay & eBay |
1 | Push Buttons | Amazon & Amazon | AliExpress | eBay |
1 | Potentiometers | Amazon | AliExpress | eBay |
1 | Micro USB Cable | Amazon | AliExpress | eBay |
★ Check The Links Below For The Full Course Kit List & LAB Test Equipment Required For Debugging ★
Download Attachments
You can download all attachment files for this Article/Tutorial (project files, schematics, code, etc..) using the link below. Please consider supporting our work through the various support options listed in the link down below. Every small donation helps to keep this website up and running and ultimately supports the whole community.
Wrap Up
In conclusion, we’ve explored the STM32 Sleep Mode, what it does to reduce the current consumption, and what are the current consumption numbers expected from this mode using the (STM32L432KC) target microcontroller.
We’ve also explored how to enter and exit (wake-up) from sleep mode in STM32 microcontrollers. And how to use the STM32 Sleep-On-Exit feature to run an interrupt-based system with minimal power consumption automatically without worrying about entering and exiting sleep mode manually.
You can build on top of the provided example code project and integrate it into your system. You can also check the rest of the tutorials in this series to learn more about other low-power modes in STM32 microcontrollers.