3

I am trying to generate a triangular wave of frequency 8kHz using DAC and DMA. DAC is triggered using a timer so that the DAC speed will be 1 MSPS. I am working on stm32L476 discovery board. I am using stm32CUBEMX for code initialization. My configurations are as follows:

In stm32CUBEMX :

 Clock configuration : system clock = 80MHz 
                                     APB1 and APB2 peripheral clocks = 20 MHz
                                     APB1 and APB2 timer clocks = 40 MHz
                                     PLL source mux : HSI
                                     PLLM = /1
                                     *N = x10
                                      /R = /8
                                     PLLCLK selected
    Timer : Prescalar = 39
                UP counter
                Period = 1
                So that output frequency is 1 MHz to trigger the DAC.
    DAC :
              Output buffer : Enable
              Trigger : TIM7 Event out
              DMA(option inside DAC configuration in cubeMX): DAC channel 2(PA5), Half word, circular mode, priority = very             high, memory(ticked) in cubeMX

I am using ac6SW4stm32(system workbench) for writing code. I created an array like this for triangular wave.

const uint16_t val[]={130,260,390,520,650,780,910,1040,
1170,1300,1430,1560,1690,1820,1950,2080,
2210,2340,2470,2600,2730,2860,2990,3120,
3250,3380,3510,3640,3770,3900,4030,4095,
4030,3900,3770,3640,3510,3380,3250,3120,
2990,2860,2730,2600,2470,2340,2210,2080,
1950,1820,1690,1560,1430,1300,1170,1040,
910,780,650,520,390,260,130,0};

In main, I added the following three statements. These statements start timer, DAC and DMA respectively.

HAL_TIM_Base_Start(&htim7);
HAL_DAC_Start(&hdac1,DAC_CHANNEL_2);
HAL_DAC_Start_DMA(&hdac1, DAC_CHANNEL_2, (uint32_t*)val, 64, DAC_ALIGN_12B_R);

At the output, I am not getting proper triangular wave. Frequency of the wave is correct but the wave is not perfectly triangular. It has different rising and falling slopes(unequal edges).

Mel
  • 5,837
  • 10
  • 37
  • 42
user8398475
  • 61
  • 2
  • 7

1 Answers1

4

You have not enough samples to have the triangular wave. 64 samples is far not enough. (single step is >100mV). If you want to keep 1MSPS the maximum is 125 samples which is not good enough in my opinion.

Your DAC can be driven with much more samples per second than 1MSPS. My record (using external fast opamp) is 5.5MSPS. With the internal buffer on you can try up to 2-3MSPS.

Waveform was generated using STM32F446 and the oscillogram was taken by my prototype STM32F303 10MSPS oscilloscope.

This is the oscillogram of the saw 8kHz with 32 samples: enter image description here

This is the oscillogram of the saw 8kHz with 256 samples: enter image description here

TIM6 -> DIER |= TIM_DIER_UDE;
TIM6 -> PSC = PSC_Value;
TIM6 -> ARR = ARR_Value;
TIM6 -> CR2 |= TIM_CR2_MMS_1;

DAC -> CR = DAC_CR_DMAEN1 | DAC_SR_DMAUDR1 | DAC_CR_TEN1 | DAC_CR_BOFF1;
DAC -> CR |= DAC_CR_EN1;

DMA1_Stream5 -> NDTR = Nsamples;
DMA1_Stream5 -> PAR = (uint32_t)&(DAC -> DHR12R1);
DMA1_Stream5 -> M0AR = (uint32_t)Buff;
DMA1_Stream5 -> CR = (DMA_SxCR_TEIE | DMA_SxCR_CHSEL | DMA_SxCR_CIRC | DMA_SxCR_DIR_0 | DMA_SxCR_EN | DMA_SxCR_PSIZE_0 | DMA_SxCR_MSIZE_0 | DMA_SxCR_MINC | DMA_SxCR_PL_0);

TIM6 -> CR1 |= TIM_CR1_CEN;

PS the code is for 446RE

0___________
  • 60,014
  • 4
  • 34
  • 74
  • PS I would recommend the bare register approach. HAL for the very simple hardware like DAC and timer is useless – 0___________ Aug 01 '17 at 15:00
  • I tried increasing the number of samples and decreased the timer prescalar value to increase the dac speed so that I'll get 8kHz wave. But the wave still is uneven. If I try for triangular wave of less frequency like 2kHz, I'm able to get it correctly. Following are some of the observations: 1) 512 samples, 2MSPS dac speed, output frequency 1.86kHz(seems right), correct waveform 2) 256 samples, 2MSPS dac speed, o/p freq = 3.7kHz(freq correct), uneven waveform. Also dac speed cannot be increased beyond this. It gives the same problem with waveform. – user8398475 Aug 03 '17 at 06:29
  • And also is it not possible to get 8kHz output frequency using DAC at 1MSPS? Because if I increase the number of samples, I have to increase the DAC speed,too to get 8kHz as output. – user8398475 Aug 03 '17 at 06:54
  • have you switched on the output buffer? O course you have to increase the speed of the |DAC. – 0___________ Aug 03 '17 at 07:03
  • But it not the issue as your DAC is capable of 10MSPS http://www.st.com/content/ccc/resource/technical/document/application_note/6f/35/61/e9/8a/28/48/8c/DM00129215.pdf/files/DM00129215.pdf/jcr:content/translations/en.DM00129215.pdf For the speed < 2.5MSPS you just need to enable DACs internal buffer – 0___________ Aug 03 '17 at 07:11
  • I have already enabled the internal output buffer. But still can't get the right waveform. I had switched it on right from the start. – user8398475 Aug 03 '17 at 12:10
  • Can you please write me the key steps I'll have to follow while coding for my application? I might be missing something. It'll be easy for me to check if I have missed something. I have been working on this for almost a week now and still can't find the reason. – user8398475 Aug 03 '17 at 12:13
  • See my code. It works. Nothing else has to be done. Check the underrun flag as well. Here is "live" generation captured https://youtu.be/3BGzKDf0k1U by this hardware: https://i.stack.imgur.com/gXhUr.jpg – 0___________ Aug 03 '17 at 12:27
  • Can you please share the whole code? I really want to see what other initializations like system clock configuration you have done. – user8398475 Aug 04 '17 at 04:54