In this tutorial, we’ll discuss The STM32 Stop Mode, how to enter (Stop0, Stop1, Stop2) modes in STM32 microcontrollers, and how to exit from Stop modes (Wakeup) with some code examples and a full test project. Without further ado, let’s get right into it!
Table of Contents
- STM32 Stop Mode
- STM32 Enter Stop Mode
- STM32 Wakeup (Exit) Stop Mode
- STM32 Stop Mode Example Code Project
- Wrap Up
STM32 Stop Mode
Stop mode achieves the lowest power consumption while retaining the content of SRAM and registers. All clocks in the VCORE domain are stopped, and the PLL, the MSI RC, the HSI16 RC, and the HSE crystal oscillators are disabled. The LSE or LSI can be kept running.
Stop 1 offers the largest number of active peripherals and wake-up sources, a shorter wake-up time but a higher consumption than Stop 2.
In Stop 2 mode, most of the VCORE domain is put in a lower leakage mode.
For the STM32L432KC target microcontroller, in Stop Modes, the current consumption is:
- Stop0 mode at 25°C and VDD = 3.6V, the current consumption should be 114μA
- Stop1 mode at 25°C and VDD = 3.6V, the current consumption should be 4.56μA
- Stop2 mode at 25°C and VDD = 3.6V, the current consumption should be 1.23μA
To put things into perspective, this same target microcontroller (STM32L432KC) draws 72μA of current while operating in the DeepSleep (Low-Power Sleep) Mode. Therefore, going into Stop1 or Stop2 modes will significantly reduce the current consumption.
In Stop Modes (Stop0, Stop1, or Stop2), the CPU core is essentially stopped. Therefore, starting a debugging session is not an option while the CPU is operating in any of these modes.
STM32 Enter Stop Mode
By entering Stop 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 and the stop mode you’re going to use (Stop0, Stop1, or Stop2).
To enter Stop 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_PWREx_EnterSTOP0Mode() 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 Stop0 Mode:
1 2 |
HAL_SuspendTick(); HAL_PWREx_EnterSTOP0Mode(PWR_SLEEPENTRY_WFI); |
To Enter Stop1 Mode, only change the function call line of code by the following:
1 |
HAL_PWREx_EnterSTOP1Mode(PWR_SLEEPENTRY_WFI); |
To Enter Stop2 Mode, only change the function call line of code by the following:
1 |
HAL_PWREx_EnterSTOP2Mode(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) Stop Mode
An interrupt signal will cause the CPU to exit from the Stop Mode and go back to normal operation. Therefore, we can use something like EXTI, IWDG, or RTC 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 Stop Mode (0, 1, or 2) 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 Stop Mode, Resume The SysTick! HAL_ResumeTick(); } } |
Unlike Sleep mode, Stop mode disables all clock sources except for the (LSE/LSI). Which by definition puts every peripheral in an OFF state, except for the (RTC backup domain, GPIOs, and IWDG). Any of which can be used as a source of wakeup signal (WFI) to get the CPU out of the stop mode.
STM32 Stop 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 Stop0 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 Stop 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 |
/* * LAB Name: STM32 Stop Mode Test Project * Author: Khaled Magdy * For More Info Visit: www.DeepBlueMbedded.com */ #include "main.h" volatile uint8_t StopMode_Activated = 0; volatile uint8_t EnterStopFlag = 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); StopMode_Activated = 1; HAL_SuspendTick(); HAL_PWREx_EnterSTOP0Mode(PWR_SLEEPENTRY_WFI); while (1) { if(EnterStopFlag) { // Re-Enter Stop Mode! EnterStopFlag = 0; StopMode_Activated = 1; HAL_SuspendTick(); HAL_PWREx_EnterSTOP0Mode(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(StopMode_Activated == 1) { // CPU Has Exited From Stop Mode, Resume The SysTick! HAL_ResumeTick(); StopMode_Activated = 0; } else { // Re-Enter Stop Mode! EnterStopFlag = 1; } } } |
STM32 Stop 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 Stop0 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 Stop0 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 Stop0 mode, 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 & Stop0 modes.
Stop Mode can’t be entered from the interrupt handler context. Therefore, the flag variable EnterStopFlag was used to handle the stop mode entry operation within the main function context.
For other stop modes, you can change only one line of code. Just replace HAL_PWREx_EnterSTOP0Mode(PWR_SLEEPENTRY_WFI); with:
- HAL_PWREx_EnterSTOP1Mode(PWR_SLEEPENTRY_WFI); // Stop1 Mode
- or
- HAL_PWREx_EnterSTOP2Mode(PWR_SLEEPENTRY_WFI); // Stop2 Mode
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 Stop Mode (Stop0, Stop1, and Stop2), what stop mode 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 stop mode in STM32 microcontrollers. 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.