Haberler:

Forum kuralları güncellendi LÜTFEN  okuyunuz:  https://bit.ly/2IjR3ME

Ana Menü

STM32F4 DMA DAC problemi

Başlatan kralsam, 03 Ocak 2017, 21:25:06

kralsam

Selamlar Arkadaşlar,

Daha önceden timer kullanarak DAC ile sinyal generatör yapmıştım fakat şimdi DMA ile yapmam gerekti. (DMA daha önce sadece SPI ile kullanmıştım.)Bunun için hızlı başlangıç için CubeMX kullandım. Fakat anlam veremediğim bir sorun yaşıyorum. DMA başlattığım an sinyal her örnekten sonra sıfır a düşüyor sanki örnek seyreltme yapıyor gibi. Düşük frekanslarda bilinen PAM(Pulse Amplitude Modulation) çıktı veriyor.

Sizce sorun nerede olabilir? Benzer uygulama yapan arkadaşlar var mı? (Discovery board ile PA4 ü kullandım)

kralsam

Bu arada tekrar timer içinde set ettiğimde sorunsuz çalışıyor ama DMA ile yazdığımda her örnekten sonra sanki 0 yazıyor.

eyupsepik

Eskiden potansiyometre ile Sinüs sinyalinin frekansını değiştiren bi ugulama yapmıştım DMA kullanarak. O zamanlar CubeMx kendini göstermemişti daha. Kodları ekliyorum belki işine yarar bi tarafı olur.



#include "stm32f4xx.h"
#include "stm32f4_discovery.h"

#define   OUT_FREQ          frq                             // Frekans değeri
#define   SINE_RES          128                                  // Çözünürlük bir peiyot yani 360 derece için 128 değer
#define   DAC_DHR12R1_ADDR  0x40007408                           // DAC kanal1 adresi DMA'nın her tetiklemede yazması için
#define   CNT_FREQ          42000000                             // Timer6 clock değeri 42Mhz
#define   TIM_PERIOD        ((CNT_FREQ)/((SINE_RES)*(OUT_FREQ))) // Otomatik yükleme değeri hesabı

const uint16_t function[SINE_RES] = { 2048, 2145, 2242, 2339, 2435, 2530, 2624, 2717, 2808, 2897, 
                                      2984, 3069, 3151, 3230, 3307, 3381, 3451, 3518, 3581, 3640, 
                                      3696, 3748, 3795, 3838, 3877, 3911, 3941, 3966, 3986, 4002, 
                                      4013, 4019, 4020, 4016, 4008, 3995, 3977, 3954, 3926, 3894, 
                                      3858, 3817, 3772, 3722, 3669, 3611, 3550, 3485, 3416, 3344, 
                                      3269, 3191, 3110, 3027, 2941, 2853, 2763, 2671, 2578, 2483, 
                                      2387, 2291, 2194, 2096, 1999, 1901, 1804, 1708, 1612, 1517, 
                                      1424, 1332, 1242, 1154, 1068, 985, 904, 826, 751, 679, 
                                      610, 545, 484, 426, 373, 323, 278, 237, 201, 169, 
                                      141, 118, 100, 87, 79, 75, 76, 82, 93, 109, 
                                      129, 154, 184, 218, 257, 300, 347, 399, 455, 514, 
                                      577, 644, 714, 788, 865, 944, 1026, 1111, 1198, 1287, 
                                      1378, 1471, 1565, 1660, 1756, 1853, 1950, 2047 };           

static void TIM6_Ayar(uint16_t period);
static void DAC1_Ayar(void);  
void GPIO_Ayar(void);
int ADC_Oku(void);
void ADC_Ayar(void);
int ConvertedValue = 0; 
int frq=5000;
int frqdegisti=0;

int main()
{
  GPIO_Ayar();
  ADC_Ayar();
  TIM6_Ayar(TIM_PERIOD);
  DAC1_Ayar();

  
 while(1)
 {
   ConvertedValue= ADC_Oku(); // ADC okuma işlemi yap ve değeri değişkene at
   if(ConvertedValue>0 && ConvertedValue<500 && frq!=2000) // Değer kontrolü ve değerin değme kontrolü
   {
     
     frqdegisti=1;
     frq=2000;
    
   }

   if(ConvertedValue>500 && ConvertedValue<1000 && frq!=3000)
   {
      frqdegisti=1;
     frq=3000;
     
   }
   if(ConvertedValue>1000 && ConvertedValue<1500 &&frq!=4000)
   {
     frqdegisti=1;
     frq=4000;
    
   }
   if(ConvertedValue>1500 && ConvertedValue<2000 && frq!=5000)
   {
     frqdegisti=1;
     
     frq=5000;
      
   }
   
    if(ConvertedValue>2000 && ConvertedValue<2500 && frq!=6000)
   {
      frqdegisti=1;
     frq=6000;
     
   }
    
     if(ConvertedValue>2500 && ConvertedValue<3000 && frq!=7000)
   {
      frqdegisti=1;
     frq=7000;
     
   }
   
     if(ConvertedValue>3000 && ConvertedValue<3500 && frq!=8000)
   {
      frqdegisti=1;
     frq=8000;
     
   }
   
     if(ConvertedValue>3500 && ConvertedValue<4000 && frq!=8500)
   {
      frqdegisti=1;
     frq=8500;
     
   }
     if(ConvertedValue>4000 && ConvertedValue<5000 && frq!=9000)
   {
      frqdegisti=1;
     frq=9000;
     
   }
   if(frqdegisti==1)
   {
     TIM6_Ayar(TIM_PERIOD);
     frqdegisti=0;
   
   }
   
 }
}


 
 
void ADC_Ayar(){
 ADC_InitTypeDef ADC_init_structure; 
 GPIO_InitTypeDef GPIO_initStructre; 
 
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);// ADC1 saat kaynağı aç APB2 ye bağlı
 RCC_AHB1PeriphClockCmd(RCC_AHB1ENR_GPIOCEN,ENABLE);//GPIOC nin clock kaynağını aç AH1 e bağlı
 //Analog pin configuration
 GPIO_initStructre.GPIO_Pin = GPIO_Pin_0;// PC0 kanal 10
 GPIO_initStructre.GPIO_Mode = GPIO_Mode_AN; //Analog mod ayarlaması
 GPIO_initStructre.GPIO_PuPd = GPIO_PuPd_NOPULL; //pull-down ya da pull-up gerekmiyor.
 GPIO_Init(GPIOC,&GPIO_initStructre);//Ayarları porta uygula
 //ADCayarları
 ADC_DeInit();
 ADC_init_structure.ADC_DataAlign = ADC_DataAlign_Right;//ADC'den okunan değer registere sağa yaslı yazılacak register 32 bit
 ADC_init_structure.ADC_Resolution = ADC_Resolution_12b;//12 bit ADC kullanılacak 0-4096 
 ADC_init_structure.ADC_ContinuousConvMode = ENABLE; //çevrim işlemi sürekli olacak
 ADC_init_structure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;// Okuma Timer 1 in CC1 i ile senkron olacak (Bundan emin değilim:/)
 ADC_init_structure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;//okuma için tetikleme sinyali yok
 ADC_init_structure.ADC_NbrOfConversion = 1;
 ADC_init_structure.ADC_ScanConvMode = DISABLE;//Tarama şeklinde değil zaten tek kanal ayarlandı
 ADC_Init(ADC1,&ADC_init_structure);//Ayarları ADC1 e uygula
 //ADC1 i aktif et
 ADC_Cmd(ADC1,ENABLE);
 //ADC1 Kanal 10 Örnekleme zamanı 144 saykıl
 ADC_RegularChannelConfig(ADC1,ADC_Channel_10,1,ADC_SampleTime_144Cycles);
}
int ADC_Oku(){
 ADC_SoftwareStartConv(ADC1);//Okumaya başla
 while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));//Okuma işlemi sonuna kadar bekle 
 return ADC_GetConversionValue(ADC1); //Okunan değeri geri döndür
}

static void TIM6_Ayar(uint16_t period)
{
  TIM_TimeBaseInitTypeDef TIM6_TimeBase; // Timer struct tanımlaması 

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE); //Timer 6 clock kaynağı aç APB1
 
  TIM_TimeBaseStructInit(&TIM6_TimeBase);  //Temel timer olarak kullan
  TIM6_TimeBase.TIM_Period        = (uint16_t)period;   //periyot dışarıdan gelecek       
  TIM6_TimeBase.TIM_Prescaler     = 0;       //Ön bölücü yok
  TIM6_TimeBase.TIM_ClockDivision = 0;    //Clock bölme yok
  TIM6_TimeBase.TIM_CounterMode   = TIM_CounterMode_Up;  //Yukarı sayıcı ayarla
  TIM_TimeBaseInit(TIM6, &TIM6_TimeBase); // Ayarları uygula
  TIM_SelectOutputTrigger(TIM6, TIM_TRGOSource_Update); //Tetikleyici olarak kullan kesme ile 

  TIM_Cmd(TIM6, ENABLE); //Timer 6 yı aktif et
}
 //DAC ayarları 
static void DAC1_Ayar(void)
{
   RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE); // DAC clock kaynağı aç APB1
  
   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE); //DMA clock kaynağı aç AHB1
  DAC_InitTypeDef DAC_INIT; //DAC struct tanımlaması
  DMA_InitTypeDef DMA_INIT; //DMA struct tanımlaması
  
  DAC_INIT.DAC_Trigger        = DAC_Trigger_T6_TRGO;  //Tetikleme sinyalini Timer6dan al
  DAC_INIT.DAC_WaveGeneration = DAC_WaveGeneration_None;  //Sinyal üretimi yok (Aslında burada direk üçgen dalga veya gürültü üretebiliriz)
  DAC_INIT.DAC_OutputBuffer   = DAC_OutputBuffer_Enable; //Çıkış tamponu aktif
  DAC_Init(DAC_Channel_1, &DAC_INIT);  // DAC kanal1 PA4

  DMA_DeInit(DMA1_Stream5);
  DMA_INIT.DMA_Channel            = DMA_Channel_7;  //DAC kanal 7 
  DMA_INIT.DMA_PeripheralBaseAddr = (uint32_t)DAC_DHR12R1_ADDR;  //Verinin taşınacağı adres DAC kanal1 
  DMA_INIT.DMA_Memory0BaseAddr    = (uint32_t)&function; // Verinin alınacağı adres function dizisi. sinüs noktaları
  DMA_INIT.DMA_DIR                = DMA_DIR_MemoryToPeripheral; //Hafızadan donanıma veri taşıma yapılcak
  DMA_INIT.DMA_BufferSize         = SINE_RES;  // Tampon SINE_RES kadar olacak yani 128 elemanlı
  DMA_INIT.DMA_PeripheralInc      = DMA_PeripheralInc_Disable; //Tek bir DAC kanalı kullanılacak artma yok.
  DMA_INIT.DMA_MemoryInc          = DMA_MemoryInc_Enable; //Hafızadaki adreste artma var. Dizinin bir sonraki elemanını alması için
  DMA_INIT.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; // Donanıma aktarılacak Verilerin her biri 8 bir olacak (Word 16 bit veri)
  DMA_INIT.DMA_MemoryDataSize     = DMA_MemoryDataSize_HalfWord;   // Hafızadan alınan veriler de 8 bit
  DMA_INIT.DMA_Mode               = DMA_Mode_Circular;   // Dizi bittiğinde başa dön
  DMA_INIT.DMA_Priority           = DMA_Priority_High; //Önceliği yüksek
  DMA_INIT.DMA_FIFOMode           = DMA_FIFOMode_Disable;  //İlk giren ilk çıkar pasif
  DMA_INIT.DMA_FIFOThreshold      = DMA_FIFOThreshold_HalfFull; //
  DMA_INIT.DMA_MemoryBurst        = DMA_MemoryBurst_Single;//Veriler teker teker hafızadan alınsın
  DMA_INIT.DMA_PeripheralBurst    = DMA_PeripheralBurst_Single; // Veriler teker teker donanıma basılsın
  DMA_Init(DMA1_Stream5, &DMA_INIT); //Ayarları DMA ya uygula

  DMA_Cmd(DMA1_Stream5, ENABLE);  // DMA'yı aktif et stream5 kanal7
  DAC_Cmd(DAC_Channel_1, ENABLE); //DAC kanal1 i aktif et
  DAC_DMACmd(DAC_Channel_1, ENABLE); // DMA'yı DAC kanal1 e bağla (aktif et)
}
//GPIO Ayarları
void GPIO_Ayar()
{
GPIO_InitTypeDef gpio_A; //GPIO struct tnımlaması
 
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);  // GPIOA clock kaynağı aç                
  gpio_A.GPIO_Pin  = GPIO_Pin_4; // 4. pin PA4 DAC için 
  gpio_A.GPIO_Mode = GPIO_Mode_AN; // Analog mod
  gpio_A.GPIO_PuPd = GPIO_PuPd_NOPULL; // Pull-up pull-down yok
  GPIO_Init(GPIOA, &gpio_A); // Ayarları GPIOA ya uygula

  


}

kralsam

Alıntı yapılan: eyupsepik - 04 Ocak 2017, 22:24:42
Eskiden potansiyometre ile Sinüs sinyalinin frekansını değiştiren bi ugulama yapmıştım DMA kullanarak. O zamanlar CubeMx kendini göstermemişti daha. Kodları ekliyorum belki işine yarar bi tarafı olur.



#include "stm32f4xx.h"
#include "stm32f4_discovery.h"

#define   OUT_FREQ          frq                             // Frekans değeri
#define   SINE_RES          128                                  // Çözünürlük bir peiyot yani 360 derece için 128 değer
#define   DAC_DHR12R1_ADDR  0x40007408                           // DAC kanal1 adresi DMA'nın her tetiklemede yazması için
#define   CNT_FREQ          42000000                             // Timer6 clock değeri 42Mhz
#define   TIM_PERIOD        ((CNT_FREQ)/((SINE_RES)*(OUT_FREQ))) // Otomatik yükleme değeri hesabı

const uint16_t function[SINE_RES] = { 2048, 2145, 2242, 2339, 2435, 2530, 2624, 2717, 2808, 2897, 
                                      2984, 3069, 3151, 3230, 3307, 3381, 3451, 3518, 3581, 3640, 
                                      3696, 3748, 3795, 3838, 3877, 3911, 3941, 3966, 3986, 4002, 
                                      4013, 4019, 4020, 4016, 4008, 3995, 3977, 3954, 3926, 3894, 
                                      3858, 3817, 3772, 3722, 3669, 3611, 3550, 3485, 3416, 3344, 
                                      3269, 3191, 3110, 3027, 2941, 2853, 2763, 2671, 2578, 2483, 
                                      2387, 2291, 2194, 2096, 1999, 1901, 1804, 1708, 1612, 1517, 
                                      1424, 1332, 1242, 1154, 1068, 985, 904, 826, 751, 679, 
                                      610, 545, 484, 426, 373, 323, 278, 237, 201, 169, 
                                      141, 118, 100, 87, 79, 75, 76, 82, 93, 109, 
                                      129, 154, 184, 218, 257, 300, 347, 399, 455, 514, 
                                      577, 644, 714, 788, 865, 944, 1026, 1111, 1198, 1287, 
                                      1378, 1471, 1565, 1660, 1756, 1853, 1950, 2047 };           

static void TIM6_Ayar(uint16_t period);
static void DAC1_Ayar(void);  
void GPIO_Ayar(void);
int ADC_Oku(void);
void ADC_Ayar(void);
int ConvertedValue = 0; 
int frq=5000;
int frqdegisti=0;

int main()
{
  GPIO_Ayar();
  ADC_Ayar();
  TIM6_Ayar(TIM_PERIOD);
  DAC1_Ayar();

  
 while(1)
 {
   ConvertedValue= ADC_Oku(); // ADC okuma işlemi yap ve değeri değişkene at
   if(ConvertedValue>0 && ConvertedValue<500 && frq!=2000) // Değer kontrolü ve değerin değme kontrolü
   {
     
     frqdegisti=1;
     frq=2000;
    
   }

   if(ConvertedValue>500 && ConvertedValue<1000 && frq!=3000)
   {
      frqdegisti=1;
     frq=3000;
     
   }
   if(ConvertedValue>1000 && ConvertedValue<1500 &&frq!=4000)
   {
     frqdegisti=1;
     frq=4000;
    
   }
   if(ConvertedValue>1500 && ConvertedValue<2000 && frq!=5000)
   {
     frqdegisti=1;
     
     frq=5000;
      
   }
   
    if(ConvertedValue>2000 && ConvertedValue<2500 && frq!=6000)
   {
      frqdegisti=1;
     frq=6000;
     
   }
    
     if(ConvertedValue>2500 && ConvertedValue<3000 && frq!=7000)
   {
      frqdegisti=1;
     frq=7000;
     
   }
   
     if(ConvertedValue>3000 && ConvertedValue<3500 && frq!=8000)
   {
      frqdegisti=1;
     frq=8000;
     
   }
   
     if(ConvertedValue>3500 && ConvertedValue<4000 && frq!=8500)
   {
      frqdegisti=1;
     frq=8500;
     
   }
     if(ConvertedValue>4000 && ConvertedValue<5000 && frq!=9000)
   {
      frqdegisti=1;
     frq=9000;
     
   }
   if(frqdegisti==1)
   {
     TIM6_Ayar(TIM_PERIOD);
     frqdegisti=0;
   
   }
   
 }
}


 
 
void ADC_Ayar(){
 ADC_InitTypeDef ADC_init_structure; 
 GPIO_InitTypeDef GPIO_initStructre; 
 
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);// ADC1 saat kaynağı aç APB2 ye bağlı
 RCC_AHB1PeriphClockCmd(RCC_AHB1ENR_GPIOCEN,ENABLE);//GPIOC nin clock kaynağını aç AH1 e bağlı
 //Analog pin configuration
 GPIO_initStructre.GPIO_Pin = GPIO_Pin_0;// PC0 kanal 10
 GPIO_initStructre.GPIO_Mode = GPIO_Mode_AN; //Analog mod ayarlaması
 GPIO_initStructre.GPIO_PuPd = GPIO_PuPd_NOPULL; //pull-down ya da pull-up gerekmiyor.
 GPIO_Init(GPIOC,&GPIO_initStructre);//Ayarları porta uygula
 //ADCayarları
 ADC_DeInit();
 ADC_init_structure.ADC_DataAlign = ADC_DataAlign_Right;//ADC'den okunan değer registere sağa yaslı yazılacak register 32 bit
 ADC_init_structure.ADC_Resolution = ADC_Resolution_12b;//12 bit ADC kullanılacak 0-4096 
 ADC_init_structure.ADC_ContinuousConvMode = ENABLE; //çevrim işlemi sürekli olacak
 ADC_init_structure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;// Okuma Timer 1 in CC1 i ile senkron olacak (Bundan emin değilim:/)
 ADC_init_structure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;//okuma için tetikleme sinyali yok
 ADC_init_structure.ADC_NbrOfConversion = 1;
 ADC_init_structure.ADC_ScanConvMode = DISABLE;//Tarama şeklinde değil zaten tek kanal ayarlandı
 ADC_Init(ADC1,&ADC_init_structure);//Ayarları ADC1 e uygula
 //ADC1 i aktif et
 ADC_Cmd(ADC1,ENABLE);
 //ADC1 Kanal 10 Örnekleme zamanı 144 saykıl
 ADC_RegularChannelConfig(ADC1,ADC_Channel_10,1,ADC_SampleTime_144Cycles);
}
int ADC_Oku(){
 ADC_SoftwareStartConv(ADC1);//Okumaya başla
 while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));//Okuma işlemi sonuna kadar bekle 
 return ADC_GetConversionValue(ADC1); //Okunan değeri geri döndür
}

static void TIM6_Ayar(uint16_t period)
{
  TIM_TimeBaseInitTypeDef TIM6_TimeBase; // Timer struct tanımlaması 

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE); //Timer 6 clock kaynağı aç APB1
 
  TIM_TimeBaseStructInit(&TIM6_TimeBase);  //Temel timer olarak kullan
  TIM6_TimeBase.TIM_Period        = (uint16_t)period;   //periyot dışarıdan gelecek       
  TIM6_TimeBase.TIM_Prescaler     = 0;       //Ön bölücü yok
  TIM6_TimeBase.TIM_ClockDivision = 0;    //Clock bölme yok
  TIM6_TimeBase.TIM_CounterMode   = TIM_CounterMode_Up;  //Yukarı sayıcı ayarla
  TIM_TimeBaseInit(TIM6, &TIM6_TimeBase); // Ayarları uygula
  TIM_SelectOutputTrigger(TIM6, TIM_TRGOSource_Update); //Tetikleyici olarak kullan kesme ile 

  TIM_Cmd(TIM6, ENABLE); //Timer 6 yı aktif et
}
 //DAC ayarları 
static void DAC1_Ayar(void)
{
   RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE); // DAC clock kaynağı aç APB1
  
   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE); //DMA clock kaynağı aç AHB1
  DAC_InitTypeDef DAC_INIT; //DAC struct tanımlaması
  DMA_InitTypeDef DMA_INIT; //DMA struct tanımlaması
  
  DAC_INIT.DAC_Trigger        = DAC_Trigger_T6_TRGO;  //Tetikleme sinyalini Timer6dan al
  DAC_INIT.DAC_WaveGeneration = DAC_WaveGeneration_None;  //Sinyal üretimi yok (Aslında burada direk üçgen dalga veya gürültü üretebiliriz)
  DAC_INIT.DAC_OutputBuffer   = DAC_OutputBuffer_Enable; //Çıkış tamponu aktif
  DAC_Init(DAC_Channel_1, &DAC_INIT);  // DAC kanal1 PA4

  DMA_DeInit(DMA1_Stream5);
  DMA_INIT.DMA_Channel            = DMA_Channel_7;  //DAC kanal 7 
  DMA_INIT.DMA_PeripheralBaseAddr = (uint32_t)DAC_DHR12R1_ADDR;  //Verinin taşınacağı adres DAC kanal1 
  DMA_INIT.DMA_Memory0BaseAddr    = (uint32_t)&function; // Verinin alınacağı adres function dizisi. sinüs noktaları
  DMA_INIT.DMA_DIR                = DMA_DIR_MemoryToPeripheral; //Hafızadan donanıma veri taşıma yapılcak
  DMA_INIT.DMA_BufferSize         = SINE_RES;  // Tampon SINE_RES kadar olacak yani 128 elemanlı
  DMA_INIT.DMA_PeripheralInc      = DMA_PeripheralInc_Disable; //Tek bir DAC kanalı kullanılacak artma yok.
  DMA_INIT.DMA_MemoryInc          = DMA_MemoryInc_Enable; //Hafızadaki adreste artma var. Dizinin bir sonraki elemanını alması için
  DMA_INIT.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; // Donanıma aktarılacak Verilerin her biri 8 bir olacak (Word 16 bit veri)
  DMA_INIT.DMA_MemoryDataSize     = DMA_MemoryDataSize_HalfWord;   // Hafızadan alınan veriler de 8 bit
  DMA_INIT.DMA_Mode               = DMA_Mode_Circular;   // Dizi bittiğinde başa dön
  DMA_INIT.DMA_Priority           = DMA_Priority_High; //Önceliği yüksek
  DMA_INIT.DMA_FIFOMode           = DMA_FIFOMode_Disable;  //İlk giren ilk çıkar pasif
  DMA_INIT.DMA_FIFOThreshold      = DMA_FIFOThreshold_HalfFull; //
  DMA_INIT.DMA_MemoryBurst        = DMA_MemoryBurst_Single;//Veriler teker teker hafızadan alınsın
  DMA_INIT.DMA_PeripheralBurst    = DMA_PeripheralBurst_Single; // Veriler teker teker donanıma basılsın
  DMA_Init(DMA1_Stream5, &DMA_INIT); //Ayarları DMA ya uygula

  DMA_Cmd(DMA1_Stream5, ENABLE);  // DMA'yı aktif et stream5 kanal7
  DAC_Cmd(DAC_Channel_1, ENABLE); //DAC kanal1 i aktif et
  DAC_DMACmd(DAC_Channel_1, ENABLE); // DMA'yı DAC kanal1 e bağla (aktif et)
}
//GPIO Ayarları
void GPIO_Ayar()
{
GPIO_InitTypeDef gpio_A; //GPIO struct tnımlaması
 
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);  // GPIOA clock kaynağı aç                
  gpio_A.GPIO_Pin  = GPIO_Pin_4; // 4. pin PA4 DAC için 
  gpio_A.GPIO_Mode = GPIO_Mode_AN; // Analog mod
  gpio_A.GPIO_PuPd = GPIO_PuPd_NOPULL; // Pull-up pull-down yok
  GPIO_Init(GPIOA, &gpio_A); // Ayarları GPIOA ya uygula

  


}

Eyvallah hocam gerek kalmadı pointer hatası yapmışım.