hal::clock

Clock Configuration - PLL & System Clock Setup

~410 satır ~22 fonksiyon STM32/GD32

Genel Bakış

Clock modülü, mikrodenetleyicinin kalp atışıdır. HSI/HSE/PLL kaynaklarını yapılandırır, sistem clockunu ayarlar ve peripheral clocklarını dağıtır. Doğru clock yapılandırması sistemin performansını, güç tüketimini ve timing accuracy'sini doğrudan etkiler.

Temel Özellikler

Hızlı Başlangıç

içe_aktar hal::clock

// HSE + PLL -> 72 MHz (STM32F1)
clock.init(yap
    source: clock.SOURCE_PLL,
    hse_freq: 8_000_000,  // 8 MHz crystal
    pll_mul: 9,           // 8 * 9 = 72 MHz
    ahb_div: 1,           // HCLK = 72 MHz
    apb1_div: 2,          // PCLK1 = 36 MHz (max 36 MHz)
    apb2_div: 1           // PCLK2 = 72 MHz
son)

// Verify clock
değişken sysclk = clock.get_sysclk_freq()
io.yazdir_satır("SYSCLK: " + sysclk.metne() + " Hz")

Tipler ve Enum'lar

// Clock Sources
enum ClockSource {
    HSI,        // High-Speed Internal (16 MHz)
    HSE,        // High-Speed External (4-25 MHz crystal)
    PLL,        // Phase-Locked Loop (multiplied clock)
    LSI,        // Low-Speed Internal (32 kHz, RTC)
    LSE         // Low-Speed External (32.768 kHz, RTC)
}

// PLL Source
enum PLLSource {
    PLL_HSI,    // HSI as PLL input
    PLL_HSE     // HSE as PLL input
}

// AHB Prescaler
enum AHBPrescaler {
    DIV_1, DIV_2, DIV_4, DIV_8, DIV_16,
    DIV_64, DIV_128, DIV_256, DIV_512
}

// APB Prescaler
enum APBPrescaler {
    DIV_1, DIV_2, DIV_4, DIV_8, DIV_16
}

yapı ClockConfig yap
    source: ClockSource,
    hse_freq: sayı = 8_000_000,
    pll_source: PLLSource = PLL_HSE,
    pll_mul: sayı = 9,      // STM32F1: 2-16
    pll_m: sayı = 8,        // STM32F4: input divider
    pll_n: sayı = 336,      // STM32F4: multiplier
    pll_p: sayı = 2,        // STM32F4: system clock divider
    pll_q: sayı = 7,        // STM32F4: USB/SDIO divider
    ahb_prescaler: AHBPrescaler = DIV_1,
    apb1_prescaler: APBPrescaler = DIV_2,
    apb2_prescaler: APBPrescaler = DIV_1,
    css_enable: mantık = doğru,  // Clock Security System
    flash_latency: sayı = 2      // Wait states
son

Örnek 1: STM32F1 - 72 MHz Maximum Speed

Problem: STM32F103 için maksimum performans (72 MHz)

içe_aktar hal::clock, hal::flash

fonksiyon clock_72mhz_init() yap
    // Enable HSE (8 MHz external crystal)
    clock.hse_enable()
    
    // Wait for HSE ready
    eğer değil clock.hse_wait_ready(1000) yap
        io.yazdir_satır("HSE failed to start!")
        dön
    son
    
    // Configure Flash latency (2 wait states for 72 MHz)
    flash.set_latency(flash.LATENCY_2)
    
    // Configure PLL: HSE * 9 = 8 MHz * 9 = 72 MHz
    clock.pll_config(yap
        source: clock.PLL_HSE,
        mul: 9
    son)
    
    // Enable PLL
    clock.pll_enable()
    clock.pll_wait_ready(1000)
    
    // Configure bus prescalers
    clock.set_ahb_prescaler(clock.AHB_DIV_1)   // 72 MHz
    clock.set_apb1_prescaler(clock.APB_DIV_2)  // 36 MHz (max!)
    clock.set_apb2_prescaler(clock.APB_DIV_1)  // 72 MHz
    
    // Switch to PLL as system clock
    clock.set_sysclk_source(clock.SOURCE_PLL)
    
    // Wait for switch
    döngü yap
        eğer clock.get_sysclk_source() == clock.SOURCE_PLL yap
            kır
        son
    son
    
    // Update SystemCoreClock variable
    clock.system_core_clock_update()
    
    io.yazdir_satır("Clock configured successfully!")
    io.yazdir_satır("SYSCLK: " + clock.get_sysclk_freq().metne() + " Hz")
    io.yazdir_satır("HCLK: " + clock.get_hclk_freq().metne() + " Hz")
    io.yazdir_satır("PCLK1: " + clock.get_pclk1_freq().metne() + " Hz")
    io.yazdir_satır("PCLK2: " + clock.get_pclk2_freq().metne() + " Hz")
son

Çıktı: SYSCLK: 72000000 Hz, HCLK: 72000000 Hz, PCLK1: 36000000 Hz, PCLK2: 72000000 Hz

Örnek 2: STM32F4 - 168 MHz with USB Support

Problem: STM32F407 için 168 MHz + 48 MHz USB clock

içe_aktar hal::clock, hal::flash, hal::power

fonksiyon clock_168mhz_usb_init() yap
    // Enable power interface clock
    clock.periph_clock_enable(clock.PERIPH_PWR)
    
    // Voltage scaling for max frequency
    power.set_voltage_scaling(power.SCALE_1)
    
    // Enable HSE (8 MHz)
    clock.hse_enable()
    clock.hse_wait_ready(1000)
    
    // Flash latency (5 wait states for 168 MHz @ 3.3V)
    flash.set_latency(flash.LATENCY_5)
    flash.prefetch_enable()
    flash.instruction_cache_enable()
    flash.data_cache_enable()
    
    // PLL configuration:
    // VCO_IN = HSE / PLLM = 8 MHz / 8 = 1 MHz
    // VCO_OUT = VCO_IN * PLLN = 1 MHz * 336 = 336 MHz
    // SYSCLK = VCO_OUT / PLLP = 336 MHz / 2 = 168 MHz
    // USB_CLK = VCO_OUT / PLLQ = 336 MHz / 7 = 48 MHz
    clock.pll_config(yap
        source: clock.PLL_HSE,
        pllm: 8,   // Input divider
        plln: 336, // Multiplier
        pllp: 2,   // System clock divider
        pllq: 7    // USB clock divider
    son)
    
    clock.pll_enable()
    clock.pll_wait_ready(1000)
    
    // Bus prescalers
    clock.set_ahb_prescaler(clock.AHB_DIV_1)   // 168 MHz
    clock.set_apb1_prescaler(clock.APB_DIV_4)  // 42 MHz (max 42 MHz!)
    clock.set_apb2_prescaler(clock.APB_DIV_2)  // 84 MHz (max 84 MHz!)
    
    // Switch to PLL
    clock.set_sysclk_source(clock.SOURCE_PLL)
    döngü yap
        eğer clock.get_sysclk_source() == clock.SOURCE_PLL yap
            kır
        son
    son
    
    clock.system_core_clock_update()
    
    // Verify USB clock
    değişken usb_clk = clock.get_usb_freq()
    io.yazdir_satır("USB Clock: " + usb_clk.metne() + " Hz")
    
    eğer usb_clk != 48_000_000 yap
        io.yazdir_satır("WARNING: USB clock is not 48 MHz!")
    son
son

Sonuç: 168 MHz sistem clocku + 48 MHz USB clock. Maksimum performans.

Örnek 3: Clock Security System (CSS)

Problem: HSE crystal failure durumunda otomatik HSI'ye geçiş

içe_aktar hal::clock, hal::nvic

değişken hse_failed: mantık = yanlış

fonksiyon clock_css_init() yap
    // Normal clock setup with HSE
    clock.hse_enable()
    clock.hse_wait_ready(1000)
    
    clock.pll_config(yap
        source: clock.PLL_HSE,
        mul: 9
    son)
    clock.pll_enable()
    clock.pll_wait_ready(1000)
    
    // Enable Clock Security System
    clock.css_enable()
    
    // Enable NMI interrupt for CSS
    nvic.enable_irq(nvic.RCC_IRQn, yap priority: 0 son)
    
    clock.set_sysclk_source(clock.SOURCE_PLL)
    
    io.yazdir_satır("CSS enabled, monitoring HSE...")
son

// CSS failure interrupt handler
fonksiyon RCC_IRQHandler() yap
    eğer clock.get_flag(clock.FLAG_CSS) yap
        io.yazdir_satır("CSS INTERRUPT: HSE FAILURE DETECTED!")
        
        hse_failed = doğru
        
        // System automatically switched to HSI
        // Reconfigure PLL with HSI
        clock.pll_disable()
        
        clock.pll_config(yap
            source: clock.PLL_HSI,
            mul: 16  // HSI/2 * 16 = 8 MHz * 8 = 64 MHz
        son)
        
        clock.pll_enable()
        clock.pll_wait_ready(1000)
        
        // Clear CSS flag
        clock.clear_flag(clock.FLAG_CSS)
        
        io.yazdir_satır("Switched to HSI-based PLL (64 MHz)")
    son
son

fonksiyon ana() yap
    clock_css_init()
    
    döngü yap
        eğer hse_failed yap
            io.yazdir_satır("Running on backup HSI clock")
            // Reduce performance or enter safe mode
        son
        
        // Normal operation
        delay_ms(1000)
    son
son

Güvenlik: HSE arızasında sistem donmaz, otomatik HSI'ye geçer.

Örnek 4: MCO (Master Clock Output) for Debugging

Problem: Oscilloscope ile clock sinyalini gözlemlemek

içe_aktar hal::clock, hal::gpio

fonksiyon mco_debug_init() yap
    // MCO pin: PA8 (STM32F4)
    gpio.pin_init(gpio.PORT_A, 8, yap
        mode: gpio.MODE_AF,
        af: gpio.AF0_MCO,
        speed: gpio.SPEED_VERY_HIGH
    son)
    
    // Output SYSCLK / 4 to MCO
    // (168 MHz / 4 = 42 MHz on PA8)
    clock.mco1_config(yap
        source: clock.MCO_SYSCLK,
        prescaler: clock.MCO_DIV_4
    son)
    
    io.yazdir_satır("MCO output enabled on PA8")
    io.yazdir_satır("Expected frequency: " + 
                    (clock.get_sysclk_freq() / 4).metne() + " Hz")
son

// Alternative: Output PLL clock for verification
fonksiyon mco_pll_check() yap
    gpio.pin_init(gpio.PORT_A, 8, yap
        mode: gpio.MODE_AF, af: gpio.AF0_MCO
    son)
    
    // Output PLL / 2
    clock.mco1_config(yap
        source: clock.MCO_PLL,
        prescaler: clock.MCO_DIV_2
    son)
    
    io.yazdir_satır("PLL clock on PA8 (use oscilloscope)")
son

Debug: Oscilloscope ile gerçek clock frekansını doğrulayın. PLL lock problemlerini tespit edin.

API Referansı

Clock Source Control

// HSE control
fonksiyon hse_enable()
fonksiyon hse_disable()
fonksiyon hse_wait_ready(timeout_ms: sayı) -> mantık

// HSI control
fonksiyon hsi_enable()
fonksiyon hsi_disable()
fonksiyon hsi_calibration_set(value: sayı)

// PLL control
fonksiyon pll_config(config: PLLConfig)
fonksiyon pll_enable()
fonksiyon pll_disable()
fonksiyon pll_wait_ready(timeout_ms: sayı) -> mantık

// System clock
fonksiyon set_sysclk_source(source: ClockSource)
fonksiyon get_sysclk_source() -> ClockSource
fonksiyon get_sysclk_freq() -> sayı

// Bus clocks
fonksiyon set_ahb_prescaler(div: AHBPrescaler)
fonksiyon set_apb1_prescaler(div: APBPrescaler)
fonksiyon set_apb2_prescaler(div: APBPrescaler)
fonksiyon get_hclk_freq() -> sayı
fonksiyon get_pclk1_freq() -> sayı
fonksiyon get_pclk2_freq() -> sayı

// Peripheral clocks
fonksiyon periph_clock_enable(periph: Peripheral)
fonksiyon periph_clock_disable(periph: Peripheral)

// CSS and MCO
fonksiyon css_enable()
fonksiyon css_disable()
fonksiyon mco1_config(source: MCOSource, div: MCODiv)

// Utilities
fonksiyon system_core_clock_update()
fonksiyon get_flag(flag: ClockFlag) -> mantık
fonksiyon clear_flag(flag: ClockFlag)
Önemli Notlar:
  • Flash Latency: High frequency için wait state gerekli (168 MHz -> 5 WS)
  • APB1 Max: STM32F1 36 MHz, F4 42 MHz, F7 54 MHz
  • USB Clock: Tam 48 MHz olmalı (tolerance 0.25%)
  • PLL Lock Time: ~200 μs, timeout kullanın

Platform Desteği

Platform Max SYSCLK HSE Range PLL Multiplier
STM32F1 72 MHz 4-16 MHz 2-16x
STM32F4 168 MHz 4-26 MHz PLLM/N/P/Q
STM32F7 216 MHz 4-26 MHz PLLM/N/P/Q
STM32H7 480 MHz 4-48 MHz PLLM/N/P/Q/R
GD32VF103 108 MHz 4-25 MHz 2-32x

Best Practices

İlgili Modüller

HAL Modülleri | English