How to Implement Sleep Mode in ARM Cortex-M Microcontrollers
To implement sleep mode in ARM Cortex-M, use the
WFI (Wait For Interrupt) or WFE (Wait For Event) instructions to put the CPU into low-power state. Before that, configure the SLEEPDEEP bit in the System Control Register (SCR) to select the desired sleep mode depth.Syntax
The main instructions to enter sleep mode are WFI and WFE. These are assembly instructions that halt the CPU until an interrupt or event occurs.
WFI: Wait For Interrupt, CPU sleeps until an interrupt wakes it.WFE: Wait For Event, CPU sleeps until an event wakes it.
To select deep sleep mode, set the SLEEPDEEP bit in the System Control Register (SCR) before executing WFI or WFE.
c
/* Set SLEEPDEEP bit to enter deep sleep mode */ SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; /* Enter sleep mode and wait for interrupt */ __WFI();
Example
This example shows how to put an ARM Cortex-M microcontroller into deep sleep mode using the CMSIS hardware abstraction layer. The CPU will sleep until an interrupt wakes it.
c
#include "stm32f4xx.h" // Replace with your MCU header void enter_sleep_mode(void) { /* Set SLEEPDEEP bit to enable deep sleep mode */ SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; /* Optionally configure power control registers here for lower power */ /* Enter sleep mode and wait for interrupt */ __WFI(); /* CPU wakes here after interrupt */ /* Clear SLEEPDEEP bit if needed */ SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; } int main(void) { // Initialization code here while (1) { // Do some work // Enter sleep mode to save power enter_sleep_mode(); // CPU resumes here after waking up } }
Output
No visible output; CPU enters low-power sleep mode until an interrupt occurs.
Common Pitfalls
- Not setting the
SLEEPDEEPbit when deep sleep is required, causing the CPU to enter only a shallow sleep. - Forgetting to enable interrupts that can wake the CPU, resulting in the CPU never waking up.
- Not clearing the
SLEEPDEEPbit after waking, which may cause unexpected behavior on subsequent sleep calls. - Misconfiguring power control registers, leading to higher power consumption than expected.
c
/* Wrong: Missing SLEEPDEEP bit for deep sleep */ // __WFI(); // CPU enters shallow sleep only /* Correct: Set SLEEPDEEP bit before WFI */ SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; __WFI(); SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
Quick Reference
| Step | Action | Description |
|---|---|---|
| 1 | Set SLEEPDEEP bit | Select deep sleep mode by setting SCB->SCR SLEEPDEEP bit |
| 2 | Configure wake-up sources | Enable interrupts or events that can wake the CPU |
| 3 | Execute WFI or WFE | Put CPU to sleep until interrupt or event occurs |
| 4 | Clear SLEEPDEEP bit | Reset SLEEPDEEP bit after waking if needed |
Key Takeaways
Use the WFI or WFE instruction to put the ARM Cortex-M CPU into sleep mode.
Set the SLEEPDEEP bit in the System Control Register to enter deep sleep mode.
Always enable interrupts or events that can wake the CPU from sleep.
Clear the SLEEPDEEP bit after waking to avoid unintended sleep behavior.
Configure power control registers properly to maximize power savings.