STM32F1xx Dual DAC DMA örnek

Başlatan SpeedyX, 24 Şubat 2013, 17:07:32

SpeedyX

Merhaba,

Aşağıda stm32f1xx için stdperiph kullanarak dma ve timer kontrollü dual dac kullanımı ile ilgili örnek paylaşıyorum.

DualDAC değişkenine
DualDAC = ((uint32_t)DACB << 16) + (uint32_t)DACA;

şeklinde 0-4095 aralığında yazdığınız değerleri timer tetiklemeli olarak çift kanal çıkışa aktarır.

#include "stm32f10x.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_tim.h"
#include "stm32f10x_dac.h"
#include "stm32f10x_dma.h"

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define DAC_DHR12RD_Address      0x40007420

uint32_t DualDAC = (0x7FF << 16) + 0x7FF;

void SetupDACDMA(void)
{
  /* Init Structure definition */
  DAC_InitTypeDef            DAC_InitStructure;
  DMA_InitTypeDef            DMA_InitStructure;
  TIM_TimeBaseInitTypeDef    TIM_TimeBaseStructure;
  GPIO_InitTypeDef 			 GPIO_InitStructure;

  /* System Clocks Configuration */
  /* Enable peripheral clocks ------------------------------------------------*/
#if !defined STM32F10X_LD_VL && !defined STM32F10X_MD_VL
  /* DMA2 clock enable */
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);
#else
  /* DMA1 clock enable */
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
#endif
  /* GPIOA Periph clock enable */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  /* DAC Periph clock enable */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);
  /* TIM2 Periph clock enable */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

  /* Once the DAC channel is enabled, the corresponding GPIO pin is automatically
     connected to the DAC converter. In order to avoid parasitic consumption,
     the GPIO pin should be configured in analog */
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_4 | GPIO_Pin_5;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  /* TIM2 Configuration */
  /* Time base configuration */
  TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
  TIM_TimeBaseStructure.TIM_Period = 0x19;
  TIM_TimeBaseStructure.TIM_Prescaler = 0x0;
  TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

  /* TIM2 TRGO selection */
  TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update);

  /* DAC channel1 Configuration */
  DAC_InitStructure.DAC_Trigger = DAC_Trigger_T2_TRGO;
  DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;
  DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Disable;
  DAC_Init(DAC_Channel_1, &DAC_InitStructure);
  /* DAC channel2 Configuration */
  DAC_Init(DAC_Channel_2, &DAC_InitStructure);

#if !defined STM32F10X_LD_VL && !defined STM32F10X_MD_VL
  /* DMA2 channel4 configuration */
  DMA_DeInit(DMA2_Channel4);
#else
  /* DMA1 channel4 configuration */
  DMA_DeInit(DMA1_Channel4);
#endif
  DMA_InitStructure.DMA_PeripheralBaseAddr = DAC_DHR12RD_Address;
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&DualDAC;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
  DMA_InitStructure.DMA_BufferSize = 1;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

#if !defined STM32F10X_LD_VL && !defined STM32F10X_MD_VL
  DMA_Init(DMA2_Channel4, &DMA_InitStructure);
  /* Enable DMA2 Channel4 */
  DMA_Cmd(DMA2_Channel4, ENABLE);
#else
  DMA_Init(DMA1_Channel4, &DMA_InitStructure);
  /* Enable DMA1 Channel4 */
  DMA_Cmd(DMA1_Channel4, ENABLE);
#endif

  /* Enable DAC Channel1: Once the DAC channel1 is enabled, PA.04 is
     automatically connected to the DAC converter. */
  DAC_Cmd(DAC_Channel_1, ENABLE);
  /* Enable DAC Channel2: Once the DAC channel2 is enabled, PA.05 is
     automatically connected to the DAC converter. */
  DAC_Cmd(DAC_Channel_2, ENABLE);

  /* Enable DMA for DAC Channel2 */
  DAC_DMACmd(DAC_Channel_2, ENABLE);

  /* TIM2 enable counter */
  TIM_Cmd(TIM2, ENABLE);
}


Not: başlık stm32 örnekler konusuna taşınabilir.

tekosis

elinize sağlık hocam. acaba bu kodlar hangi derleyicide yazılıdı?
İlim ilim bilmektir, ilim kendin bilmektir, sen kendin bilmezsin, bu nice okumaktır.

mir_as82

Hocam dual dac dan kasıt nedir? Ref. gerilim 5 volt ise, biz A ve B nin toplamını 4095 yazarsak, konfigüre edilmiş çıkışlara (dual olduğundan 2 çıkış ) 5V gerilim verecek mi?? Anladığım doğru mu?

SpeedyX

Merhaba

Alıntı yapılan: tekosis - 30 Aralık 2013, 12:58:45
elinize sağlık hocam. acaba bu kodlar hangi derleyicide yazılıdı?
Kodlar cocoox da yazıldı ama cmsis olan her derleyicide sorunsuzça çalışır, bir değişiklik yapmanıza gerek yok.

Alıntı yapılan: mir_as82 - 30 Aralık 2013, 13:14:56
Hocam dual dac dan kasıt nedir? Ref. gerilim 5 volt ise, biz A ve B nin toplamını 4095 yazarsak, konfigüre edilmiş çıkışlara (dual olduğundan 2 çıkış ) 5V gerilim verecek mi?? Anladığım doğru mu?
Dual DAC demek, aynı anda stereo çıkış verebilen DAC demek oluyor, yani içinde 2 tane ayrı dac modülü var ve tek bir 32bitlik regiter a yazmak suretiyle, 2 dac ın da çıkışına değer ataması yapabiliyorsunuz.
Kodda bir timer tetiklemesi ile RAM de tutulan değer sürekli olarak dac çıkışlarına güncellenir, timer frekansını değiştirerek güncelleme hızını belirleyebilirsiniz.
Sistem DMA ile çalıştığından işlem gücü istemez, sadece kurulum yapmanız yeterli, zaten kodlar sırf kurulum (init) dan ibaret.