Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

📊 hal::pwm

Pulse Width Modulation - PWM Sinyal Üretimi

~320 satır ~12 fonksiyon STM32/GD32/ESP32

📖 Genel Bakış

PWM modülü, timer donanımını kullanarak değişken genişlikli dijital sinyaller üretir. Motor hız kontrolü, LED parlaklık ayarı, servo kontrol ve analog çıkış simülasyonu için kullanılır.

🔑 Temel Özellikler

  • Konfigüre edilebilir frekans (1 Hz - 1 MHz+)
  • 0-100% duty cycle kontrolü
  • Çoklu kanal desteği (4 kanala kadar)
  • Complementary output (dead-time ile)
  • Hardware sync ve trigger
  • DMA destekli dalga formu üretimi
  • One-pulse mode
  • Encoder interface mode

🚀 Hızlı Başlangıç

içe_aktar hal::pwm, hal::gpio

// PWM pin setup (TIM3 CH1 -> PA6)
gpio.pin_init(gpio.PORT_A, 6, yap
    mode: gpio.MODE_AF,
    af: gpio.AF2_TIM3
son)

// PWM initialization (1 kHz, 50% duty)
değişken pwm_handle = pwm.init(pwm.TIM3, pwm.CHANNEL_1, yap
    frequency: 1000,      // 1 kHz
    duty_cycle: 50,       // 50%
    polarity: pwm.ACTIVE_HIGH,
    mode: pwm.MODE_PWM1
son)

// Start PWM
pwm.start(pwm_handle)

// Update duty cycle
pwm.set_duty_cycle(pwm_handle, 75)  // 75%

📦 Tipler ve Enum'lar

// Timer Seçimi
enum Timer {
    TIM1, TIM2, TIM3, TIM4, TIM5,
    TIM8, TIM9, TIM10, TIM11, TIM12
}

// PWM Kanalları
enum Channel {
    CHANNEL_1, CHANNEL_2, CHANNEL_3, CHANNEL_4
}

// PWM Modları
enum Mode {
    PWM1,  // Active when CNT < CCR
    PWM2   // Active when CNT > CCR
}

// Polarity
enum Polarity {
    ACTIVE_HIGH,  // High is active
    ACTIVE_LOW    // Low is active
}

// Alignment Mode
enum Alignment {
    EDGE,    // Edge-aligned
    CENTER1, // Center-aligned mode 1
    CENTER2, // Center-aligned mode 2
    CENTER3  // Center-aligned mode 3
}

yapı PWMConfig yap
    frequency: sayı,        // Hz (1-1000000)
    duty_cycle: kesir,      // 0.0-100.0
    polarity: Polarity,
    mode: Mode,
    alignment: Alignment
son

💡 Örnek 1: LED Dimming (Parlaklık Kontrolü)

LED parlaklığını PWM ile kontrol etme

içe_aktar hal::pwm, hal::core

fonksiyon led_dimmer() yap
    // PWM setup (10 kHz)
    değişken led_pwm = pwm.init(pwm.TIM2, pwm.CHANNEL_1, yap
        frequency: 10000,
        duty_cycle: 0,
        polarity: pwm.ACTIVE_HIGH,
        mode: pwm.MODE_PWM1
    son)
    
    pwm.start(led_pwm)
    
    // Fade in/out loop
    döngü yap
        // Fade in (0% -> 100%)
        için brightness içinde 0..100 için yap
            pwm.set_duty_cycle(led_pwm, brightness.kesir())
            core.delay_ms(10)
        son
        
        core.delay_ms(500)
        
        // Fade out (100% -> 0%)
        için brightness içinde (0..100).reverse() için yap
            pwm.set_duty_cycle(led_pwm, brightness.kesir())
            core.delay_ms(10)
        son
        
        core.delay_ms(500)
    son
son

💡 Örnek 2: DC Motor Hız Kontrolü

L298N sürücüsü ile motor kontrolü

içe_aktar hal::pwm, hal::gpio

yapı Motor yap
    pwm: PWMHandle,
    dir_pin1: GPIOPin,
    dir_pin2: GPIOPin
son

fonksiyon motor_init() -> Motor yap
    // Direction pins
    değişken in1 = gpio.pin_init(gpio.PORT_B, 0, gpio.MODE_OUTPUT)
    değişken in2 = gpio.pin_init(gpio.PORT_B, 1, gpio.MODE_OUTPUT)
    
    // PWM for speed (20 kHz)
    değişken motor_pwm = pwm.init(pwm.TIM1, pwm.CHANNEL_1, yap
        frequency: 20000,
        duty_cycle: 0,
        polarity: pwm.ACTIVE_HIGH,
        mode: pwm.MODE_PWM1
    son)
    
    pwm.start(motor_pwm)
    
    dön Motor yap
        pwm: motor_pwm,
        dir_pin1: in1,
        dir_pin2: in2
    son
son

fonksiyon motor_set_speed(motor: Motor, speed: kesir) yap
    // speed: -100 to +100 (negative = reverse)
    eğer speed > 0 ise yap
        // Forward
        gpio.pin_write(motor.dir_pin1, gpio.HIGH)
        gpio.pin_write(motor.dir_pin2, gpio.LOW)
        pwm.set_duty_cycle(motor.pwm, speed)
    yoksa eğer speed < 0 ise yap
        // Reverse
        gpio.pin_write(motor.dir_pin1, gpio.LOW)
        gpio.pin_write(motor.dir_pin2, gpio.HIGH)
        pwm.set_duty_cycle(motor.pwm, -speed)
    yoksa yap
        // Stop
        gpio.pin_write(motor.dir_pin1, gpio.LOW)
        gpio.pin_write(motor.dir_pin2, gpio.LOW)
        pwm.set_duty_cycle(motor.pwm, 0.0)
    son
son

fonksiyon ana() yap
    değişken motor = motor_init()
    
    // Acceleration test
    için speed içinde 0..100 için yap
        motor_set_speed(motor, speed.kesir())
        core.delay_ms(50)
    son
    
    core.delay_ms(2000)
    
    // Deceleration
    için speed içinde (0..100).reverse() için yap
        motor_set_speed(motor, speed.kesir())
        core.delay_ms(50)
    son
    
    motor_set_speed(motor, 0.0)  // Stop
son

💡 Örnek 3: Servo Motor Kontrolü (SG90)

50Hz PWM ile servo açı kontrolü

içe_aktar hal::pwm

yapı Servo yap
    pwm: PWMHandle,
    min_pulse: kesir,  // ms
    max_pulse: kesir   // ms
son

fonksiyon servo_init(timer: Timer, channel: Channel) -> Servo yap
    // Servo: 50Hz, 1-2ms pulse width
    değişken servo_pwm = pwm.init(timer, channel, yap
        frequency: 50,      // 50 Hz (20ms period)
        duty_cycle: 7.5,    // 1.5ms pulse (90°)
        polarity: pwm.ACTIVE_HIGH,
        mode: pwm.MODE_PWM1
    son)
    
    pwm.start(servo_pwm)
    
    dön Servo yap
        pwm: servo_pwm,
        min_pulse: 1.0,  // 1ms = 0°
        max_pulse: 2.0   // 2ms = 180°
    son
son

fonksiyon servo_set_angle(servo: Servo, angle: kesir) yap
    // angle: 0-180 degrees
    değişken clamped = angle.clamp(0.0, 180.0)
    
    // Map angle to pulse width (1-2ms)
    değişken pulse_ms = servo.min_pulse + 
        (clamped / 180.0) * (servo.max_pulse - servo.min_pulse)
    
    // Convert to duty cycle (20ms period)
    değişken duty = (pulse_ms / 20.0) * 100.0
    
    pwm.set_duty_cycle(servo.pwm, duty)
son

fonksiyon ana() yap
    değişken servo = servo_init(pwm.TIM2, pwm.CHANNEL_1)
    
    // Sweep 0° to 180°
    döngü yap
        için angle içinde 0..180 için yap
            servo_set_angle(servo, angle.kesir())
            core.delay_ms(15)
        son
        
        için angle içinde (0..180).reverse() için yap
            servo_set_angle(servo, angle.kesir())
            core.delay_ms(15)
        son
    son
son

💡 Örnek 4: Buzzer Melodi Çalma

PWM frekans değiştirerek nota üretme

içe_aktar hal::pwm, hal::core

// Note frequencies (Hz)
sabit DO = 262
sabit RE = 294
sabit MI = 330
sabit FA = 349
sabit SOL = 392
sabit LA = 440
sabit SI = 494
sabit DO_HIGH = 523

fonksiyon buzzer_init() -> PWMHandle yap
    değişken buzzer = pwm.init(pwm.TIM3, pwm.CHANNEL_2, yap
        frequency: 440,  // Default: LA (440 Hz)
        duty_cycle: 50,
        polarity: pwm.ACTIVE_HIGH,
        mode: pwm.MODE_PWM1
    son)
    
    dön buzzer
son

fonksiyon play_tone(buzzer: PWMHandle, freq: sayı, duration_ms: sayı) yap
    pwm.set_frequency(buzzer, freq)
    pwm.start(buzzer)
    core.delay_ms(duration_ms)
    pwm.stop(buzzer)
son

fonksiyon play_melody(buzzer: PWMHandle) yap
    // "Twinkle Twinkle Little Star"
    değişken melody = [
        (DO, 500), (DO, 500), (SOL, 500), (SOL, 500),
        (LA, 500), (LA, 500), (SOL, 1000),
        (FA, 500), (FA, 500), (MI, 500), (MI, 500),
        (RE, 500), (RE, 500), (DO, 1000)
    ]
    
    her (note, duration) içinde melody için yap
        play_tone(buzzer, note, duration)
        core.delay_ms(50)  // Short pause between notes
    son
son

fonksiyon ana() yap
    değişken buzzer = buzzer_init()
    
    döngü yap
        play_melody(buzzer)
        core.delay_ms(2000)
    son
son

📊 API Referansı

Initialization

fonksiyon init(timer: Timer, channel: Channel, config: PWMConfig) -> PWMHandle
fonksiyon deinit(handle: PWMHandle)
fonksiyon start(handle: PWMHandle)
fonksiyon stop(handle: PWMHandle)

Configuration

fonksiyon set_duty_cycle(handle: PWMHandle, duty: kesir)  // 0.0-100.0
fonksiyon get_duty_cycle(handle: PWMHandle) -> kesir
fonksiyon set_frequency(handle: PWMHandle, freq: sayı)  // Hz
fonksiyon get_frequency(handle: PWMHandle) -> sayı
fonksiyon set_polarity(handle: PWMHandle, pol: Polarity)

Advanced

fonksiyon set_pulse_width(handle: PWMHandle, width_us: sayı)  // Microseconds
fonksiyon enable_complementary(handle: PWMHandle, deadtime_ns: sayı)
fonksiyon set_phase_shift(handle: PWMHandle, phase_degrees: kesir)
fonksiyon configure_dma(handle: PWMHandle, buffer: Dizi[sayı])

⚙️ Platform Desteği

PlatformTimersMax FreqResolution
STM32F4TIM1-1484 MHz16-bit
STM32F1TIM1-472 MHz16-bit
ESP32LEDC 0-740 MHz20-bit
GD32VF103TIM0-6108 MHz16-bit

💡 Best Practices

  • Frekans seçimi: Motor kontrolü için 20-25 kHz (insan işitme aralığı dışı)
  • Servo kontrol: 50 Hz sabit frekans, 1-2ms pulse genişliği
  • LED dimming: 100+ Hz (göz yanıp sönmeyi algılamaz)
  • Timer çakışması: Aynı timer'ın farklı kanallarını kullanın
  • Dead-time: H-bridge kontrolünde shoot-through önlemek için gerekli

🔗 İlgili Modüller

← HAL Modülleri | 🇬🇧 English