简体   繁体   中英

Can't generate sine wave using DAC and DMA on STM32

I have problem generating sine wave with my STM32F303K8 nucleo board. In my opinion, everything is configured as it should be, but I can see gnd on the oscilliscope, so it is not working. Maybe anybody has an idea why? Heres the code:

#include "stm32f30x.h"
#include <stdio.h>

#define DAC_DHR12R2_ADDRESS      0x40007414

const uint16_t Sine12bit[32] = {
    2047, 2447, 2831, 3185, 3498, 3750, 3939, 4056, 4095, 4056,
    3939, 3750, 3495, 3185, 2831, 2447, 2047, 1647, 1263,  909,
     599,  344,  155,   38,    0,   38,  155,  344,  599,  909,
     263, 1647};

DAC_InitTypeDef             DAC_InitStructure;
DMA_InitTypeDef             DMA_InitStructure;
GPIO_InitTypeDef            GPIO_InitStructure;
TIM_TimeBaseInitTypeDef     TIM_TimeBaseStructure;

static void DMA_setup(void){
    DMA_InitStructure.DMA_PeripheralBaseAddr = DAC_DHR12R2_ADDRESS;
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&Sine12bit;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
    DMA_InitStructure.DMA_BufferSize = 32;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    DMA_Init(DMA1_Channel1, &DMA_InitStructure);
    DMA_Cmd(DMA1_Channel1, ENABLE);
    DAC_DMACmd(DAC1, DAC_Channel_1, ENABLE);
}

static void DAC_setup(void){
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);

    GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_4;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    DAC_InitStructure.DAC_Trigger = DAC_Trigger_T6_TRGO;
    DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;
    DAC_InitStructure.DAC_Buffer_Switch = DAC_BufferSwitch_Disable;
    DAC_Init(DAC1, DAC_Channel_1, &DAC_InitStructure);
}

static void TIMER_setup(void){
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);

  TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
  TIM_TimeBaseStructure.TIM_Period = 100;
  TIM_TimeBaseStructure.TIM_Prescaler = 0;
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure);

  TIM_SelectOutputTrigger(TIM6, TIM_TRGOSource_Update);
  TIM_Cmd(TIM6, ENABLE);
}

int main(void){
    TIMER_setup();
    DAC_setup();
    DMA_setup();
    DAC_Cmd(DAC1, DAC_Channel_1, ENABLE);
}

Your program does only some settings, still missing the "working" part - that would be a timer interrupt and inside the interrupt a single value from Sin12 array to be sent to the DAC, not matter how. Start first without DMA and when OK you may improve it by changing to DMA support.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM