Library 36- DAC Signal generator for STM32F4

For FFT project purpose, I needed simple, really simple signal generator. I don’t have separate device at home, so I made one with STM32F4.

DAC Signal library uses timer for output generation and DMA for transferring data from memory to DAC peripheral. So this library does not use processor for controlling. Everything is behind the scenes.

You can use 4 different signal waves:

  1. Square
  2. Sawtooth
  3. Triangle
  4. Sinus

They are simple, predefined signals. You can adjust signal frequency for specific wave. I tested some frequencies, and sinus worked just well at about 100kHz, but square works great to about 50kHz. Square wave has 50% duty cycle. If you need variable square wave duty cycle, then you should look at my PWM library or PWM tutorial.

This library is not a real signal generator, sinus signal is not going to negative. Signals have fake ground at the middle of DAC max value, so 2047 is fake ground, and sinus is going from 0 to 4095. If you want “negative” effect, then you should add a capacitor in series to the output, this will allow only AC component to go through. Capacitor varies between your signal frequency, but about 680nF should be just OK.



  • Supports 4 different simple predefined waves
  • Selectable signal frequency
  • Supports 2 DAC channels
  • Timer driven DMA
    • TIM2, TIM4, TIM5, TIM6, TIM7 and TIM8 can be used


    • STM32F4xx
    • STM32F4xx RCC
    • STM32F4xx GPIO
    • STM32F4xx DAC
    • STM32F4xx TIM
    • STM32F4xx DMA
  • TM
    • TM GPIO
    • defines.h

Pinout is simple. You only need pins for DAC outputs.

DACx STM32F4 Description
DAC1 PA4 DAC Channel 1
DAC2 PA5 DAC Channel 2

STM32F401 series does not have DAC output, so you can’t use this library there. But others should have it. Pins are fixed, analog, can not be changed.

Functions and enumerations


Example below produces:

  • Triangle wave on DAC Channel 1, pin PA4, with signal frequency 5 kHz
  • Square wave on DAC Channel 2, pin PA5, with signal frequency 10kHz
  • Oscilloscope result with cursor measurements
Triangle wave 5kHz

Triangle wave 5kHz

Square wave 10kHz

Square wave 10kHz

Project is available on Github, download library below.

TM STM32F4 DAC Signal Library


Owner of this site. Also electronic enthusiasts, web developer, 3D printer fan, handball player and more. Big fan of STM32F4 devices. In anticipation of the new Discovery board for STM32F7 lines.

You may also like...

Read before commenting!

Before you make a new comment, make sure you agree with things listed below:

  • - Read post to make sure if it is already posted what you are asking for,
  • - Make sure you have the latest version of libraries used in your project,
  • - Make a clean and grammatically correct written message,
  • - Report as many details as possible, including what have you done so far,
  • - Do NOT post any code here. Use Pastebin,
  • - Do NOT post any error codes here. Use Pastebin,
  • - Specify STM32Fxxx family and used Discovery/EVAL/Nucleo or custom made board,
  • - Make sure your clock is set correct for PLL,
  • - If you are using my HAL drivers, please check this post how to start.
Comment will be deleted on breaking these rules without notification!
  • Victor

    I am testing exactly this same example on Keil uVision 5.14 using Tilen Majerle’s template (the one …CMSIS_USB_…).
    I found an error on lines 76 and 78 of tm_stm32f4_dac_signal.c, there are two pins typed in uppercase (GPIO_PIN_4 and GPIO_PIN_5), so, the compiler was rising an error, I had success on compiling with the changes seen in the second picture I’ve attached.

    I am running an example using peripherals such RTC, USART1 and USART6 and I couldn’t achieve the same results shown in your post. I don’t have a signal on TM_DAC2 output using TIM5 (As seen in the first picture I’ve attached on this post). After changing the timer interface I got it run (TIM6). Could you explain why this is happening? I’ve read some stuff but I haven’t found a solution.


    • Using my GPIO library, those 2 pins are just fine if they are uppercase!
      Huh, from my head, I have no idea right now.

      Should test this first.

      • Victor Santos

        Hi buddy, I solved the problem, don’t worry.
        I just updated my cloned repository with you libraries and it worked like a charm!


  • Bublo

    Hi Tilen, how to correctly stop generation of signal? I just stop the timer, but I am not shure, that it is correct way. Im missing function for stopping signal generation, and also function for change only the frequency would be great (without all those initializations of DMA.)


    • Just disable DMA and TIM and you are done.

      For changing frequency, you have to select new prescaler and period for timer.
      Basically, I can add these methods too.

      • Bublo

        Ok, I made it just like that. Thanks

      • Bart

        I’ve been trying to make a program that changes the frequency but i realy cant make it work. Please add the method to change the fequency.

  • Simão Ferreira

    I used your codes to generate sine and square and to the output of the DAC the signs come out perfect, but after I connect the signals to a AmpOp LM358 (24V/ 0V) to amplify the signals up to 24V, but after the amplify, from 5kHz/ 10kHz signal becomes a triangle.
    You know how to help me in this case?

  • Shawn

    In my project I need to vary the amplitude of the sine-wave…somehow. I know there is a way to do this by modifying the 32 numbers and include a variable but I am finding it a bit hard to do it. Can you help me? Thanks


    • .c file of DAC SIGNAL library: uint16_t DAC_SIGNAL_Sinus[DAC_SIGNAL_SINUS_LENGTH]

      If you don’t want to modify library directly, add this:

      extern uint16_t DAC_SIGNAL_Sinus[DAC_SIGNAL_SINUS_LENGTH]; in your main as global variable and do operations like normal.

  • linkinrcs


    Thank you for all your work which is very helpful for my project.
    I want to synthesize a triangle wave with my STM32F429. But, the minimum frequency needed is 250kHz (I have to flutter a PLL and I want to add this signal at the input of the VCO).
    I seams that this frequency is too high for the STM32’s DAC.
    I thought to generate a square signal (with a timer) and add a small circuit to integrate the signal. But do you have another idea ?
    Thanks in advance.

  • Mia

    hi TM,
    I use the above program to generate the triangle signal of 1000Hz, but the amplitude is about 1,6v, can i get the signal a little lager like 2,5v? how should i change ?

    • Hi, tell me please, how you measure voltage? Using voltmeter or oscilloscope? I’m sure you use voltmeter which averages voltages in time.

      Use oscilloscope for testing if you did not already.

      • Mia

        oh, yes, i used the voltmeter, i think i should try again with the oscilloscope!!! Thank you very much for your reply.

      • Mia

        Hi TM,

        may i change the output voltage from 0-3.3V to 0.5-3.3V?


  • kuds

    Hi, since your libraries are some of the best sources for trustworthy working and well documented STM source code, I’m often looking up basic structures and approaches to different applications, mostly covered by one of your libraries. So my question is more about how the your library works under the hood than it’s pure application.
    My application is something like the signal generator covered by this library but with an EXTERNAL DAC instead of the internal ones your library uses; board is STM32F4.
    I searched your tm_stm32f4_dac_signal.c file for the point, where you connect the timer that is configured to generate a TRGO trigger in a defined frequency with the DAC. I found out, the internal DAC init structure already provides a possibility to connect the internal DAC to a timer. This is not possible for external DACs I am addressing with SPI+DMA. Can I somehow connect a timer with a single DMA request (not a full transfer!)? So that I just load my waveform into the DMA SPI TX buffer once an then the data are sent to the external DAC just automatically whenever the timer triggers? I don’t have any clue where to look this up in the reference manual. Sorry for being a bit offtopic :-/ and thank’s a million for your help 🙂

    • This is not posible. But you can slow down spi frequency if possible to a value for your samplong and then each sample will have send time the same as time base for triggering dma.

      • kuds

        Thanks for your answer 🙂


          Hi kuds
          Did u manage to connect external DACs with STM32F4. Is there any libraries available for that?

  • FPSUsername

    @majerletilen:disqus How can I change the pins of the channels? Currently my lcd display works on pins: 0,3,4,5,6,11,13 and this can not be changed (I have a shield under it).

    • Those pins dont exists. It is mentioned, only 2 pins can be used.

      • FPSUsername

        Is there a workaround for this?

        • No.

          • FPSUsername

            PS: I wanted to change the amount of samples, but when I try for example 255 samples, the sine looks like a saw tooth shape because it only “renders” the first 1/8th part and then starts over. I modified the buffer size as well of course. What else do I need to change for it to work? 32 samples make the sine look too blocky

          • Set DAC_SIGNAL_SINUS_LENGTH to your value and set array for sinus.
            In your case, set it to 255 and fill array for DMA

  • Boldmaa

    Hi. I want to do signal generation. I want to use your example. I download all 4 .rar files but where is the
    #include “tm_stm32f4_delay.h”
    #include “tm_stm32f4_disco.h”
    libraries. There are not in here. Can you help me?

  • issa93

    Hi bro!!
    if i want to generate three different sinus signal what should i do ? can i add an external DAC ?

  • Kashi

    Hi! TM
    I just added your Dac_Signal_Generator library and I build my code successfully.But after loading code I didn’t get any output on the pins(PA4 & PA5).
    So what I should do to get output..
    I am using STM32f407(Evaluation Kit)..