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

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

Related Modules

HAL Modules | Turkish