STM32 Tutorial #15 - Sine wave on DAC with DMA

3 min read 2 hours ago
Published on Apr 27, 2026 This response is partially generated with the help of AI. It may contain inaccuracies.

Table of Contents

Introduction

In this tutorial, we will explore how to generate a sine wave using the DAC (Digital-to-Analog Converter) on an STM32 microcontroller with the help of DMA (Direct Memory Access). This approach minimizes CPU load and allows for high-speed output, achieving rates up to 1 Msps (mega samples per second). We will also utilize the CMSIS DSP library for efficient mathematical calculations.

Step 1: Understand the DAC Peripheral

  • Familiarize yourself with the DAC functionality on the STM32 microcontroller.
  • The DAC converts digital signals to analog voltages, which can be used to drive speakers, sensors, or other analog devices.

Step 2: Configure the Timer

  • Set up a timer to generate a consistent clock signal for the DAC.
  • Steps to configure the timer:
    1. Open STM32CubeMX.
    2. Select the appropriate timer (e.g., TIM2).
    3. Set the timer mode to "PWM Generation" or "Update Event".
    4. Define the timer frequency as needed for your application.
    5. Generate the initialization code.

Step 3: Test the Timer Configuration

  • Verify that the timer is functioning correctly:
    1. Upload the code to the STM32.
    2. Use an oscilloscope or logic analyzer to check the timer output.
    3. Make adjustments if necessary to ensure the timer operates at the desired frequency.

Step 4: Configure the DAC

  • Set up the DAC to output the desired waveform:
    1. Open STM32CubeMX and enable the DAC peripheral.
    2. Configure the DAC channel (e.g., DAC1).
    3. Set the output buffer and trigger settings according to your requirements.
    4. Generate the initialization code.

Step 5: Add DAC Code

  • Implement the necessary code to initialize and start the DAC:
    HAL_DAC_Start(&hdac, DAC_CHANNEL_1);
    
  • Ensure the DAC is properly set up to receive data from the DMA.

Step 6: Generate a Simple Sawtooth Wave

  • Create a basic sawtooth wave function:
    void generate_sawtooth_wave(void) {
        for (uint32_t i = 0; i < 4096; i++) {
            HAL_DAC_SetValue(&hdac, DAC_CHANNEL_1, DAC_ALIGN_12B_R, i);
            HAL_Delay(1);  // Adjust delay for desired frequency
        }
    }
    

Step 7: Add Sine Wave Calculation

  • Introduce sine wave generation using the CMSIS DSP library:
    1. Include the CMSIS library in your project.
    2. Use the following code to calculate sine values:
    float32_t sine_value;
    arm_sin_f32(angle, &sine_value);
    HAL_DAC_SetValue(&hdac, DAC_CHANNEL_1, DAC_ALIGN_12B_R, (uint16_t)(sine_value * 2048 + 2048)); // Scale to 12-bit range
    

Step 8: Increase Sample Rate

  • Optimize the sample rate by configuring DMA:
    1. Set up DMA to transfer data to the DAC without CPU intervention.
    2. Adjust the DMA settings in STM32CubeMX:
      • Select the DAC as a DMA request source.
      • Define buffer sizes and transfer modes.

Step 9: Avoid Clipping

  • Ensure the output signal stays within the DAC's voltage range:
    • Use scaling factors to adjust the amplitude of the sine wave.
    • Monitor the output with an oscilloscope to prevent distortion.

Step 10: Profile Performance

  • Use a debugger to profile the application:
    • Check CPU usage and verify that DMA is effectively reducing load.
    • Make adjustments to buffer sizes or timer configurations as necessary.

Conclusion

In this tutorial, we have covered the essential steps to generate a sine wave using the STM32 DAC with DMA. By understanding the DAC configuration, timer setup, and utilizing the CMSIS DSP library, you can create efficient and high-performance analog output. For further exploration, consider implementing additional waveforms or integrating this setup into more complex projects.