cancel
Showing results for 
Search instead for 
Did you mean: 

DMA, timer6 and DAC problem

nps
Associate II
Posted on July 06, 2016 at 14:48

Hi,

I am trying to generate analogue output using DMA. I have a taken

http://vk.com/id62355309

's cample code for testing. The output frequency is defined by

#define OUT_FREQ 5000

// Output waveform frequency

Above value is used in calculating the timer6 trigger of DAC. With the above value I was able to see sine wave on an oscilloscope. If I change this value to either 4000 or 6000 there is no DAC output at all. I changed the value to see how the sine wave frequency changes, but there is no wave output at all. If I change the timer Prescaler, I can see the output and there is a change in the output frequency. Any explanation why the output is not coming when 5000 is changed will be highly appreciated. Thank you.

5 REPLIES 5
Posted on July 06, 2016 at 17:26

The link doesn't point to any code.

Perhaps you can provide details of the code, and the chip you are using.

The DAC is limited to 1 MSps on most STM32, the timers also have integer dividers, so why don't you print out or analyze the Period and Prescaler settings with respect to the clock going into the timer from the APB. Work back the math and understand what is going on, and this might provide some insight into why it is not working.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
nps
Associate II
Posted on July 06, 2016 at 22:01

Hi clive1,

Below are the code snippets from  Sergey Ostrikov VK's site. I am using STM32F407.

The value OUT_FREQ, if I change, I get output only for some values and for other values there is no output. After many trials I found that if TIM_PERIOD is a multiple of 64, I get the output. For other values output is unpredictable. I believe DAC must work for any reload value as long as there is no over run. I await your reply. Thank you.

#define OUT_FREQ 5000

// Output waveform frequency

#define SINE_RES 128

// Waveform resolution

#define DAC_DHR12R1_ADDR 0x40007408

// DMA writes into this reg on every request

#define CNT_FREQ 42000000

// TIM6 counter clock (prescaled APB1)

#define TIM_PERIOD ((CNT_FREQ)/((SINE_RES)*(OUT_FREQ)))

// Autoreload reg value

static

void

TIM6_Config(

void

) { TIM_TimeBaseInitTypeDef TIM6_TimeBase; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE); TIM_TimeBaseStructInit(&TIM6_TimeBase); TIM6_TimeBase.TIM_Period = (

uint16_t

)TIM_PERIOD; TIM6_TimeBase.TIM_Prescaler = 0; TIM6_TimeBase.TIM_ClockDivision = 0; TIM6_TimeBase.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM6, &TIM6_TimeBase); TIM_SelectOutputTrigger(TIM6, TIM_TRGOSource_Update); TIM_Cmd(TIM6, ENABLE); }

static

void

DAC1_Config(

void

) { DAC_InitTypeDef DAC_INIT; DMA_InitTypeDef DMA_INIT; DAC_INIT.DAC_Trigger = DAC_Trigger_T6_TRGO; DAC_INIT.DAC_WaveGeneration = DAC_WaveGeneration_None; DAC_INIT.DAC_OutputBuffer = DAC_OutputBuffer_Enable; DAC_Init(DAC_Channel_1, &DAC_INIT); DMA_DeInit(DMA1_Stream5); DMA_INIT.DMA_Channel = DMA_Channel_7; DMA_INIT.DMA_PeripheralBaseAddr = (

uint32_t

)DAC_DHR12R1_ADDR; DMA_INIT.DMA_Memory0BaseAddr = (

uint32_t

)&function; DMA_INIT.DMA_DIR = DMA_DIR_MemoryToPeripheral; DMA_INIT.DMA_BufferSize = SINE_RES; DMA_INIT.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_INIT.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_INIT.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; DMA_INIT.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; DMA_INIT.DMA_Mode = DMA_Mode_Circular; DMA_INIT.DMA_Priority = DMA_Priority_High; DMA_INIT.DMA_FIFOMode = DMA_FIFOMode_Disable; DMA_INIT.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull; DMA_INIT.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_INIT.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_Init(DMA1_Stream5, &DMA_INIT); DMA_Cmd(DMA1_Stream5, ENABLE); DAC_Cmd(DAC_Channel_1, ENABLE); DAC_DMACmd(DAC_Channel_1, ENABLE); }

Posted on July 06, 2016 at 22:29

Well what frequencies you can hit will depend on the input clock and the points in the sine table. The period should be an N-1 value to hit the exact frequencies

There is a dual sine output example about half way down

https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Help%20with%20simple%20ADC%20on%20STM32F4&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B&currentviews=...

.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
nps
Associate II
Posted on July 07, 2016 at 05:25

Hi clive1,

Thanks for the reply. I will see the link. I am not currently interested in frequency but the working principle. My understanding is, as long as timer delay does not effect DAC over run, any count must trigger a DAC conversion, be it very large (reload value say 0x8000, for which DAC output may vary very slowly) or be it a very small value (say 0x20). Any count in the timer must trigger DAC. Am I right sir? But this is not happening. What am I missing? Thank you once again.

Posted on July 07, 2016 at 18:38

My experience with the STM32's is that you can program the timers here to anything you want, and the DACs will support rates up to 1 MSps, depending on the external loading.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..