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::dac

Digital-to-Analog Converter - Analog Sinyal Üretimi

391 satır ~10 fonksiyon 12-bit

📖 Genel Bakış

DAC modülü, dijital değerleri analog voltaja dönüştürür. Dalga üretimi, audio, sensör simülasyonu için kullanılır.

🔑 Temel Özellikler

  • 12-bit resolution (0-4095)
  • 2 output channels
  • DMA support
  • Triangle/Noise wave generation
  • Timer trigger
  • Output buffer

🚀 Hızlı Başlangıç

içe_aktar hal::dac, hal::gpio

// DAC pin (PA4 = DAC_OUT1)
gpio.clock_enable(gpio.PORT_A)
gpio.pin_init(gpio.PORT_A, 4, yap mode: gpio.MODE_ANALOG son)

// Initialize DAC
değişken dac1 = dac.init(dac.DAC1, dac.CHANNEL_1)

// Output voltage (0-3.3V)
dac.write(dac1, 2048)  // ~1.65V (mid-scale)

💡 Örnek: Sine Wave Generator

içe_aktar hal::dac, hal::timer, math

sabit SAMPLES = 100

fonksiyon generate_sine_wave() yap
    // Generate sine wave lookup table
    değişken sine_table = [0u16; SAMPLES]
    her i içinde 0..SAMPLES için yap
        değişken angle = 2.0 * math.PI * i.kesir() / SAMPLES.kesir()
        değişken value = (math.sin(angle) + 1.0) * 2047.5
        sine_table[i] = value.sayı()
    son
    
    // Setup DAC with DMA
    değişken dac1 = dac.init(dac.DAC1, dac.CHANNEL_1)
    dac.enable_dma(dac1)
    
    // Timer trigger (1kHz = 1kHz sine with 100 samples)
    değişken tim6 = timer.init_basic(timer.TIM6, yap
        frequency: 100_000  // 100kHz update rate
    son)
    
    dac.set_trigger(dac1, dac.TRIGGER_TIM6)
    
    // Start DMA circular mode
    dma.circular_transfer(dac.get_dma_channel(), 
        sine_table.as_ptr(),
        dac.get_data_register(dac1),
        SAMPLES
    )
    
    timer.start(tim6)
son

💡 Örnek: Audio Tone Generator

içe_aktar hal::dac, math

fonksiyon play_tone(freq: kesir, duration_ms: sayı) yap
    değişken dac1 = dac.init(dac.DAC1, dac.CHANNEL_1)
    
    değişken sample_rate = 8000.0  // 8kHz
    değişken samples = (sample_rate * duration_ms.kesir() / 1000.0).sayı()
    
    her i içinde 0..samples için yap
        değişken t = i.kesir() / sample_rate
        değişken value = (math.sin(2.0 * math.PI * freq * t) + 1.0) * 2047.5
        dac.write(dac1, value.sayı())
        core.delay_us(125)  // 8kHz = 125us per sample
    son
son

fonksiyon ana() yap
    // Play musical scale (C4 to C5)
    değişken freqs = [261.63, 293.66, 329.63, 349.23, 392.00, 440.00, 493.88, 523.25]
    
    her freq içinde freqs için yap
        play_tone(freq, 500)  // 500ms each note
        core.delay_ms(100)    // 100ms gap
    son
son

💡 Örnek: Function Generator (Triangle, Sawtooth, Square)

içe_aktar hal::dac, hal::timer, hal::dma

enum Waveform {
    SINE,
    TRIANGLE,
    SAWTOOTH,
    SQUARE
}

sabit SAMPLES = 256

fonksiyon generate_waveform(waveform: Waveform, freq: kesir) yap
    değişken wave_table = [0u16; SAMPLES]
    
    // Generate waveform lookup table
    her i içinde 0..SAMPLES için yap
        değişken phase = i.kesir() / SAMPLES.kesir()
        
        değişken value = eşle waveform yap
            Waveform::SINE => yap
                değişken angle = 2.0 * math.PI * phase
                (math.sin(angle) + 1.0) * 2047.5
            son,
            
            Waveform::TRIANGLE => yap
                eğer phase < 0.5 ise yap
                    phase * 4.0 * 4095.0
                son yoksa yap
                    (1.0 - (phase - 0.5) * 2.0) * 4095.0
                son
            son,
            
            Waveform::SAWTOOTH => yap
                phase * 4095.0
            son,
            
            Waveform::SQUARE => yap
                eğer phase < 0.5 ise 4095.0 yoksa 0.0
            son
        son
        
        wave_table[i] = value.sayı()
    son
    
    // Setup DAC with DMA + Timer trigger
    değişken dac1 = dac.init(dac.DAC1, dac.CHANNEL_1, yap
        trigger: dac.TRIGGER_TIM6,
        dma_enable: doğru
    son)
    
    // Timer frequency = desired_freq * SAMPLES
    değişken tim6 = timer.init_basic(timer.TIM6, yap
        frequency: (freq * SAMPLES.kesir()).sayı()
    son)
    
    // DMA circular mode
    değişken dma_ch = dma.init(dma.DMA1, dma.STREAM5, yap
        direction: dma.M2P,
        src_address: wave_table.as_ptr(),
        dst_address: dac.get_data_register(dac1),
        data_count: SAMPLES,
        src_increment: doğru,
        dst_increment: yanlış,
        circular: doğru,
        data_size: dma.SIZE_16BIT
    son)
    
    dma.start(dma_ch)
    timer.start(tim6)
    
    io.println("Generating {} waveform at {}Hz", waveform, freq)
son

fonksiyon ana() yap
    // Generate 1kHz triangle wave
    generate_waveform(Waveform::TRIANGLE, 1000.0)
    
    döngü yap
        core.delay_ms(1000)
    son
son

💡 Örnek: Dual Channel DAC (Stereo Output)

içe_aktar hal::dac, hal::gpio

fonksiyon dac_dual_init() -> (dac.Handle, dac.Handle) yap
    // PA4 = DAC_OUT1 (left channel)
    gpio.clock_enable(gpio.PORT_A)
    gpio.pin_init(gpio.PORT_A, 4, yap mode: gpio.MODE_ANALOG son)
    
    // PA5 = DAC_OUT2 (right channel)
    gpio.pin_init(gpio.PORT_A, 5, yap mode: gpio.MODE_ANALOG son)
    
    // Initialize both channels
    değişken dac1 = dac.init(dac.DAC1, dac.CHANNEL_1)
    değişken dac2 = dac.init(dac.DAC1, dac.CHANNEL_2)
    
    dön (dac1, dac2)
son

fonksiyon stereo_tone(left_freq: kesir, right_freq: kesir) yap
    değişken (dac_left, dac_right) = dac_dual_init()
    
    değişken sample_rate = 8000.0
    
    her i içinde 0..8000 için yap  // 1 second
        değişken t = i.kesir() / sample_rate
        
        // Left channel
        değişken left_val = (math.sin(2.0 * math.PI * left_freq * t) + 1.0) * 2047.5
        dac.write(dac_left, left_val.sayı())
        
        // Right channel
        değişken right_val = (math.sin(2.0 * math.PI * right_freq * t) + 1.0) * 2047.5
        dac.write(dac_right, right_val.sayı())
        
        core.delay_us(125)
    son
son

fonksiyon ana() yap
    // Stereo test: 440Hz left, 880Hz right
    stereo_tone(440.0, 880.0)
son

💡 Örnek: Voltage Reference / Sensor Simulation

içe_aktar hal::dac

fonksiyon voltage_to_dac(voltage: kesir) -> u16 yap
    // DAC: 0-3.3V = 0-4095
    değişken dac_val = (voltage / 3.3) * 4095.0
    dön dac_val.clamp(0.0, 4095.0).sayı()
son

fonksiyon simulate_temperature_sensor() yap
    // Simulate LM35 temperature sensor (10mV/°C)
    değişken dac1 = dac.init(dac.DAC1, dac.CHANNEL_1)
    
    // Simulate 25°C room temperature
    değişken temp_c = 25.0
    
    döngü yap
        // LM35: 10mV per degree Celsius
        değişken voltage = temp_c * 0.01  // 25°C = 0.25V
        
        dac.write(dac1, voltage_to_dac(voltage))
        
        io.println("Simulating {}°C ({}V)", temp_c, voltage)
        
        // Slowly vary temperature
        temp_c += 0.5
        eğer temp_c > 40.0 ise temp_c = 20.0
        
        core.delay_ms(1000)
    son
son

fonksiyon calibration_voltages() yap
    // Generate precise reference voltages for ADC calibration
    değişken dac1 = dac.init(dac.DAC1, dac.CHANNEL_1)
    
    değişken test_voltages = [0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.3]
    
    her voltage içinde test_voltages için yap
        dac.write(dac1, voltage_to_dac(voltage))
        io.println("Output: {}V (measure with ADC)", voltage)
        core.delay_ms(5000)  // Hold for 5 seconds
    son
son

fonksiyon ana() yap
    simulate_temperature_sensor()
son

💡 Örnek: PWM-like DC Motor Control via DAC

içe_aktar hal::dac

fonksiyon motor_speed_control() yap
    // DAC output -> Motor driver analog input
    değişken dac1 = dac.init(dac.DAC1, dac.CHANNEL_1)
    
    // Speed ramp up
    io.println("Motor ramping up...")
    her speed içinde 0..=100 için yap
        değişken voltage = (speed.kesir() / 100.0) * 3.3
        dac.write(dac1, voltage_to_dac(voltage))
        core.delay_ms(50)
    son
    
    // Hold max speed
    io.println("Motor at max speed")
    core.delay_ms(2000)
    
    // Speed ramp down
    io.println("Motor ramping down...")
    her speed içinde (0..=100).rev() için yap
        değişken voltage = (speed.kesir() / 100.0) * 3.3
        dac.write(dac1, voltage_to_dac(voltage))
        core.delay_ms(50)
    son
    
    io.println("Motor stopped")
son

fonksiyon voltage_to_dac(voltage: kesir) -> u16 yap
    dön ((voltage / 3.3) * 4095.0).clamp(0.0, 4095.0).sayı()
son

fonksiyon ana() yap
    döngü yap
        motor_speed_control()
        core.delay_ms(1000)
    son
son

⚙️ DAC Yapılandırma

// DAC Configuration
yapı DACConfig yap
    channel: Channel,           // CHANNEL_1 or CHANNEL_2
    trigger: Trigger,           // Software, Timer, EXTI
    output_buffer: bool,        // Enable for external loads
    dma_enable: bool,           // DMA for waveform generation
    noise_wave: bool,           // Noise generation
    triangle_wave: bool,        // Triangle generation
    amplitude: sayı             // Wave amplitude (0-12)
son

// Trigger Sources
enum Trigger {
    SOFTWARE,    // Manual trigger
    TIM2_TRGO,   // Timer 2
    TIM4_TRGO,   // Timer 4
    TIM6_TRGO,   // Timer 6
    TIM7_TRGO,   // Timer 7
    EXTI9        // External line 9
}

// Channels
enum Channel {
    CHANNEL_1,  // PA4
    CHANNEL_2   // PA5
}

📚 DAC Fonksiyonları

// Initialization
fonksiyon init(dac: DACInstance, channel: Channel) -> Handle
fonksiyon init_with_config(dac: DACInstance, config: DACConfig) -> Handle

// Basic output
fonksiyon write(handle: Handle, value: u16)  // 0-4095
fonksiyon write_voltage(handle: Handle, voltage: kesir)  // 0.0-3.3V

// Advanced features
fonksiyon enable_dma(handle: Handle)
fonksiyon set_trigger(handle: Handle, trigger: Trigger)
fonksiyon software_trigger(handle: Handle)

// Waveform generation
fonksiyon enable_noise_wave(handle: Handle, amplitude: sayı)
fonksiyon enable_triangle_wave(handle: Handle, amplitude: sayı)

// Utility
fonksiyon get_data_register(handle: Handle) -> *değişken u16
fonksiyon clock_enable()
fonksiyon clock_disable()

📊 DAC Kullanım Senaryoları

Uygulama Frekans Yöntem Açıklama
DC Voltage Reference Static Manual write Calibration, sensor simulation
Audio Tone (8kHz) 100Hz-4kHz Software loop Simple beeper, alarms
Waveform Generator 1Hz-10kHz DMA + Timer Function generator, test equipment
Audio Playback (44kHz) 20Hz-20kHz DMA + I2S/Timer Music, voice synthesis
Motor Speed Control DC-100Hz Slow updates Analog motor driver input

⚡ Performans İpuçları

  • DMA + Timer: Kullanın waveform generation için (CPU-free)
  • Lookup Tables: Pre-calculate sine/triangle değerleri
  • Output Buffer: Enable edin external load (>5kΩ) için
  • Dual Channel: Stereo veya differential output için kullanın
  • Trigger Source: Timer trigger precise timing için ideal

🖥️ Platform Desteği

  • STM32F1: 2-channel 12-bit DAC
  • STM32F4: 2-channel 12-bit DAC, up to 1 MSPS
  • STM32L4: 2-channel 12-bit DAC, ultra-low-power
  • STM32H7: 2-channel 12-bit DAC, up to 1 MSPS
  • GD32: Compatible DAC

⚠️ Önemli Notlar

  • Voltage Range: 0V - 3.3V (VDDA reference)
  • Output Current: Maximum ~5mA without buffer, 10-20mA with buffer
  • Output Buffer: Enable for loads < 5kΩ impedance
  • Pin Mapping: PA4 = DAC_OUT1, PA5 = DAC_OUT2 (fixed, no alternate)
  • Resolution: 12-bit (0-4095), right-aligned or left-aligned
  • Sample Rate: Up to 1 MSPS with DMA + Timer trigger
  • Noise/Triangle: Hardware waveform generation modu (test için ideal)
  • Dual Mode: Her iki channel simultane güncelleme (synchronized output)

🔗 İlgili Modüller

  • hal::timer - DAC trigger source
  • hal::dma - Waveform generation
  • hal::adc - ADC-DAC loopback test
  • hal::gpio - Pin configuration

📖 Referanslar

← HAL Modülleri