hal::power
Power Management - Ultra Low Power Modes
~420 satır
~20 function
STM32/GD32
Overview
Power modülü, embedded sistemlerde enerji verimliliği for kritik önem taşır. Sleep, Stop ve Standby modları ile güç tüketimini mikroamperlere düşürür. Bataryalı IoT cihazları, wearable'lar ve uzun ömürlü sensör ağları for vazgeçilmezdir.
Key Features
- Sleep Mode: CPU durdurulur, periferaller çalışır (run mode -> sleep ~1-2ms)
- Stop Mode: Tüm clocklar durdurulur, SRAM korunur (<1 μA typical)
- Standby Mode: Backup domain hariç her şey kapalı (~0.3 μA)
- Voltage Scaling: 1.8V - 3.6V arası dinamik voltaj ayarı
- PVD (Programmable Voltage Detector): Düşük voltaj uyarısı
- Backup Domain: RTC + 4KB backup SRAM (Standby'de korunur)
- Wakeup Sources: RTC alarm, EXTI, USART, USB, tamper
- Regulator Modes: Main/Low-power regulator seçimi
Quick Start
import hal::power, hal::rcc
// Sleep Mode (WFI - Wait For Interrupt)
power.enter_sleep_mode(do
mode: power.SLEEP_ON_EXIT
end)
// Stop Mode (ultra low power)
power.enter_stop_mode(do
regulator: power.REGULATOR_LOW_POWER,
wakeup_source: power.WAKEUP_RTC
end)
// Restore clocks after wakeup from Stop
rcc.sysclk_restore()
// Standby Mode (lowest power)
power.enter_standby_mode(do
wakeup_pin: power.WAKEUP_PIN1,
rtc_alarm: true
end)
Types and Enums'lar
// Power Modes
enum PowerMode {
RUN, // Normal operation
SLEEP, // CPU stopped, peripherals active
STOP, // All clocks stopped, SRAM retained
STANDBY // Only backup domain active
}
// Regulator Modes
enum Regulator {
REGULATOR_MAIN, // Main regulator (faster wakeup)
REGULATOR_LOW_POWER // Low-power regulator (lower current)
}
// Wakeup Sources
enum WakeupSource {
WAKEUP_PIN1, // PA0
WAKEUP_PIN2, // PC13
WAKEUP_RTC, // RTC alarm
WAKEUP_TAMPER,
WAKEUP_RESET
}
// Voltage Scaling
enum VoltageScale {
SCALE_1, // 1.8V (high performance, 168 MHz)
SCALE_2, // 1.5V (medium, 144 MHz)
SCALE_3 // 1.2V (low power, 120 MHz)
}
struct PowerConfig do
mode: PowerMode,
regulator: Regulator,
wakeup_source: WakeupSource,
flash_power_down: bool = true,
low_power_deepsleep: bool = true
end
Example 1: Sleep Mode - Periodic Sensor Reading
Problem: 1 saniyede bir sensör okuyup enerji tasarrufu domak
import hal::power, hal::rtc, hal::adc, hal::gpio
function sensor_sistemi_init() do
// RTC wakeup timer (1 Hz)
rtc.init(do
clock_source: rtc.LSI,
async_prescaler: 127,
sync_prescaler: 249 // 32 kHz / 128 / 250 = 1 Hz
end)
rtc.set_wakeup_timer(do
period: 1, // 1 second
callback: sensor_oku_handler
end)
// ADC for temperature sensor
adc.init(adc.ADC1, do
resolution: adc.RES_12BIT,
channel: adc.CH_TEMP
end)
end
let sensor_veri: Array = []
function sensor_oku_handler() do
// Woke up from sleep!
// Read temperature
let temp = adc.read_single(adc.ADC1, adc.CH_TEMP)
let celsius = (temp * 3.3 / 4096.0 - 0.76) / 0.0025 + 25.0
sensor_veri.ekle(celsius)
// Log every 10 readings
if (sensor_veri.uzunluk >= 10) do
let ortalama = sensor_veri.topla() / sensor_veri.uzunluk cast float
io.yazdir_satır("Avg temp: " + ortalama.metne() + " C")
sensor_veri.temizle()
end
end
function ana() do
sensor_sistemi_init()
io.yazdir_satır("Entering sleep mode with RTC wakeup...")
loop do
// Enter sleep mode (CPU stops, RTC continues)
power.enter_sleep_mode(do
mode: power.SLEEP_WFI
end)
// Wakes up here on RTC interrupt
// sensor_oku_handler() already executed
end
end
Güç Tüketimi: Sleep mode ~1-2 mA (peripherals active), Run mode ~20 mA. Ortalama ~2 mA (90% sleep, 10% active).
Example 2: Stop Mode - Button Wakeup (Ultra Low Power)
Problem: Buton basılana kadar minimum güç tüketimi
import hal::power, hal::exti, hal::gpio, hal::rcc
function dusuk_guc_init() do
// PA0 -> Wakeup button (external interrupt)
gpio.pin_init(gpio.PORT_A, 0, do
mode: gpio.MODE_INPUT,
pull: gpio.PULL_DOWN
end)
exti.init(0, do
trigger: exti.TRIGGER_RISING,
mode: exti.MODE_EVENT // Event mode for wakeup
end)
// Disable unnecessary peripherals
rcc.periph_clock_disable(rcc.PERIPH_TIM2)
rcc.periph_clock_disable(rcc.PERIPH_TIM3)
rcc.periph_clock_disable(rcc.PERIPH_USART2)
end
function ana() do
dusuk_guc_init()
io.yazdir_satır("System initialized")
io.yazdir_satır("Entering Stop Mode (press button to wake up)...")
// Flash power down for extra savings
power.flash_power_down_enable()
// Enter Stop Mode
power.enter_stop_mode(do
regulator: power.REGULATOR_LOW_POWER,
entry: power.ENTRY_WFE // Wait For Event
end)
// *** WOKE UP HERE ***
// Restore system clock (Stop mode uses HSI/8)
rcc.sysclk_restore()
// Re-enable flash
power.flash_power_down_disable()
io.yazdir_satır("Woke up from Stop Mode!")
// Do work
led_blink(5)
// Go back to sleep
io.yazdir_satır("Entering Stop Mode again...")
// (loop or jump to stop entry)
end
Güç Tüketimi: Stop mode <1 μA (STM32L4), ~10 μA (STM32F4). Wakeup time ~5-10 μs.
Example 3: Standby Mode - RTC Alarm Wakeup (Deepest Sleep)
Problem: 1 saat uyuyup uyanma, SRAM kaybedilir ama backup domain korunur
import hal::power, hal::rtc, hal::backup
const MAGIC_NUMBER: int = 0xDEADBEEF
function standby_sistemi_init() do
// Enable backup domain access
power.backup_access_enable()
// RTC configuration (LSE for accuracy)
rtc.init(do
clock_source: rtc.LSE, // External 32.768 kHz crystal
hour_format: rtc.FORMAT_24H
end)
// Check if woke up from standby
if power.get_flag(power.FLAG_STANDBY) do
io.yazdir_satır("Woke up from Standby!")
power.clear_flag(power.FLAG_STANDBY)
// Check backup register
let magic = backup.read_register(0)
if (magic == MAGIC_NUMBER) do
let wake_count = backup.read_register(1)
wake_count = wake_count + 1
backup.write_register(1, wake_count)
io.yazdir_satır("Wakeup count: " + wake_count.metne())
end
else do
io.yazdir_satır("Fresh boot, initializing...")
backup.write_register(0, MAGIC_NUMBER)
backup.write_register(1, 0)
end
end
function standby_ile_uyku(saat: int) do
// Set RTC alarm (wake up after N hours)
let simdiki_zaman = rtc.get_time()
let alarm_zaman = rtc.Time do
hour: (simdiki_zaman.hour + saat) % 24,
minute: simdiki_zaman.minute,
second: simdiki_zaman.second
end
rtc.set_alarm(rtc.ALARM_A, alarm_zaman)
// Enable wakeup pin as backup
power.wakeup_pin_enable(power.WAKEUP_PIN1)
io.yazdir_satır("Entering Standby for " + saat.metne() + " hours...")
io.yazdir_satır("(All RAM will be lost, only backup registers preserved)")
// Enter Standby Mode
power.enter_standby_mode()
// *** NEVER RETURNS - FULL SYSTEM RESET ON WAKEUP ***
end
function ana() do
standby_sistemi_init()
// Do some work
io.yazdir_satır("Doing important work...")
led_blink(3)
// Sleep for 1 hour
standby_ile_uyku(1)
end
Güç Tüketimi: Standby mode ~0.3-2 μA. 1 saat uyku = 0.0003 mAh. 1000 mAh batarya ile 380+ yıl!
Example 4: Voltage Scaling for Dynamic Performance
Problem: Yüksek performans gerektiğinde Scale 1, düşük güçte Scale 3 kullanmak
import hal::power, hal::rcc
enum PerformanceMode {
HIGH_PERF, // 168 MHz
NORMAL, // 120 MHz
LOW_POWER // 80 MHz
}
function set_performance_mode(mode: PerformanceMode) do
match mode do
PerformanceMode.HIGH_PERF => do
// Voltage Scale 1 (1.8V)
power.set_voltage_scaling(power.SCALE_1)
// PLL config for 168 MHz (HSE 8 MHz)
rcc.pll_config(do
source: rcc.PLL_HSE,
pllm: 8,
plln: 336,
pllp: 2,
pllq: 7
end)
rcc.sysclk_set(rcc.SYSCLK_PLL, 168_000_000)
io.yazdir_satır("High Performance: 168 MHz, ~100 mA")
end,
PerformanceMode.NORMAL => do
// Voltage Scale 2 (1.5V)
power.set_voltage_scaling(power.SCALE_2)
rcc.pll_config(do
source: rcc.PLL_HSE,
pllm: 8,
plln: 240,
pllp: 2,
pllq: 5
end)
rcc.sysclk_set(rcc.SYSCLK_PLL, 120_000_000)
io.yazdir_satır("Normal: 120 MHz, ~60 mA")
end,
PerformanceMode.LOW_POWER => do
// Voltage Scale 3 (1.2V)
power.set_voltage_scaling(power.SCALE_3)
rcc.sysclk_set(rcc.SYSCLK_HSI, 16_000_000)
io.yazdir_satır("Low Power: 16 MHz, ~10 mA")
end
end
end
function ana() do
// Start in low power
set_performance_mode(PerformanceMode.LOW_POWER)
loop do
// Idle state
power.enter_sleep_mode(do mode: power.SLEEP_WFI end)
// Check if high-performance task needed
if heavy_computation_requested() do
set_performance_mode(PerformanceMode.HIGH_PERF)
perform_fft_analysis()
set_performance_mode(PerformanceMode.LOW_POWER)
end
end
end
Result: Dynamic scaling ile ortalama güç tüketimi %40-60 azalır.
API Reference
Power Modes
// Sleep mode entry
function enter_sleep_mode(mode: SleepMode)
// Stop mode entry
function enter_stop_mode(config: StopConfig)
// Standby mode entry
function enter_standby_mode()
// Wakeup configuration
function wakeup_pin_enable(pin: WakeupPin)
function wakeup_pin_disable(pin: WakeupPin)
// Voltage scaling
function set_voltage_scaling(scale: VoltageScale)
function get_voltage_scaling() -> VoltageScale
// PVD (Programmable Voltage Detector)
function pvd_enable(level: PVDLevel)
function pvd_disable()
// Backup domain
function backup_access_enable()
function backup_access_disable()
// Flags
function get_flag(flag: PowerFlag) -> bool
function clear_flag(flag: PowerFlag)
// Flash power control
function flash_power_down_enable()
function flash_power_down_disable()
Important Notes:
- Stop Mode Wakeup: Clock kaynağı HSI/8'e returner, sysclk_restore() gerekli
- Standby Wakeup: Full system reset, tüm SRAM kaybolur (backup domain hariç)
- Debug Limitations: Stop/Standby modunda debugger bağlantısı kesilir
- Peripheral State: Stop modunda peripheral state korunur, Standby'de kaybolur
Platform Support
| Platform | Sleep Current | Stop Current | Standby Current |
|---|---|---|---|
| STM32F1 | 1.5 mA | 22 μA | 2 μA |
| STM32F4 | 2.1 mA | 11 μA | 1.8 μA |
| STM32L4 | 0.9 mA | 0.6 μA | 0.3 μA |
| STM32H7 | 4 mA | 50 μA | 6 μA |
Best Practices
- Peripheral kapatma: Stop öncesi kullanılmayan peripheral'ları disable et
- GPIO low power: Floating pinleri input+pull structlandır
- Backup domain kullan: Standby'de kalıcı veri for backup register
- RTC calibration: LSI toleransı 5%, LSE kullan (accurate timing)
- Debug etme: Stop/Standby modunda debugger çalışmaz
- SRAM güvenme: Standby'de SRAM kaybolur, kritik veriyi backup domain'e yaz