top of page

Digital to Analog Converter (DAC) Çevrebirimi


Dijitalden analoga dönüşüm sağlayan DAC 12 bitlik analog veriler oluşturur. PWM (pulse width modulators) olarak alınan dijital sinyalleri analog sinyallere dönüştürür. STM32'de dönüştürülen bu analog sinyaller sinüs veya üçgen dalgalarıdır, gürültü sinyali de oluşturulabilmektedir. 8 veya 12 bitlik modlarda sağa veya sola dayalı olarak çalıştırılabilmektedir. 2 kanal (channel 1 ve channel 2) bağımsız veya senkron olarak çalışabilmektedir. DAC olarak kullanılabilecek pinler kartta PA4 ve PA5'tir ve pinler analog input olarak atanır.




DAC'lerde yanda görüldüğü gibi mantığı voltage divider olan bir R-2R devresi (R-2R Ladder) bulunmaktadır. Örneğin yandaki DAC 4 bitliktir çünkü VA, VB, VC, VD olmak üzere 4 giriş bulunmaktadır. Burda kullanılan opampda empedansı düşürmek için kullanılmaktadır.

DAC çıkışındaki volt Vout=(Vref*D)/2^n şeklinde hesaplanır. Örneğin 12 bit çözünürlüğe sahip DAC için Vref=3.3V (STM32’nin analog besleme voltajı) Vout=3,3*4095)/(4096)~3.29 V olur. DAC’ler APB1 clock hattına bağlıdır ve clock sinyalini bu hat üzerinden almaktadırlar.


Bu uygulamada da PA4'e ve PA5'e bağlanan pinlerden DAC olarak kullanılmıştır. Potansiyometre ile 12 bitlik 0 ile 4095 arasında okuma yapıldıktan sonra belirlenen değerlere göre ledlere sinyal gönderilmiştir.


Malzemeler:


  • Led

  • Jumper kablolar

  • STM32VL Discovery

  • Potansiyometre


Devre Şeması ve Kod:








#include "stm32f10x.h"                  // Device header
#include "stm32f10x_dac.h"              // Keil::Device:StdPeriph Drivers:DAC


void gpioConfig(); // pinlerin ayarlanmasi 
void dacConfig(); //DAC'nin ayarlanmasi 
void adcConfig(); // ADC'nin ayarlanmasi 
void delay();

uint16_t readADC(); //ADC çevrim yaparken calisacak fonksiyon 


uint32_t deger;


int main(){
 
	gpioConfig();
	dacConfig();
	adcConfig();
	


while (1){
	
  deger= readADC(); //analog okuma yapiliyor 
	
	
	for (int i=0; i<4095; i++ ){
		
		
	if (deger== 0 && deger < 2048){ //deger 0-2048 arasinda ise 
	  
		DAC_SetChannel1Data(DAC_Align_12b_R,i); // channel1 yani PA4 set ediliyor. led yaniyor 
		
		
	}
	
	 if (deger==2048 && deger<4095){   //deger 2048-4095 arasinda ise
	   DAC_SetChannel2Data(DAC_Align_12b_R,i); // channel2 yani PA5 set ediliyor, led yaniyor 
		 
		
}

}
	
}


}
void gpioConfig(){

	GPIO_InitTypeDef GPIOInitStructure;
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); // A portunun clock hatti aktif ediliyor çünkü PA4 ve PA5 kullanilacak ledler icin 
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE); // potansiyometre için  kullaniiacak C portunun clock aktif ediliyor
	
	GPIOInitStructure.GPIO_Mode=GPIO_Mode_AIN; // DAC için kullanilan pinler Analog input mode'da çalisiyor
	GPIOInitStructure.GPIO_Pin=GPIO_Pin_5 | GPIO_Pin_4; // pin 4 ve pin 5 
	
	GPIOInitStructure.GPIO_Mode=GPIO_Mode_AIN; // potansiyometreden ADC okumasi yapiacak, analog input olarak belirlendi 
	GPIOInitStructure.GPIO_Pin=GPIO_Pin_0; // potasniyometre pin 0'a bagli 
	
	
	
	GPIO_Init(GPIOA,&GPIOInitStructure); // A portundaki ayarlamalar bildirildi
	GPIO_Init(GPIOC,&GPIOInitStructure); // B portundaki ayarlamalar bildirildi
	


}



void dacConfig(){
  
	DAC_InitTypeDef DACInitStructure;
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC,ENABLE); // DAC kullanmak icin APB1 clock hatti aktif edilmeli  
	
	DACInitStructure.DAC_LFSRUnmask_TriangleAmplitude=DISABLE; // olusan dalganin volt degeri
	DACInitStructure.DAC_OutputBuffer=ENABLE; //Empedansi düsürmekicin. R-2R devresinde oplamp var onun aktif inaktif edilmesiyle ilgili 
  DACInitStructure.DAC_Trigger=DAC_Trigger_None; //DAC için trigger kullanilmadi 
	DACInitStructure.DAC_WaveGeneration=DAC_WaveGeneration_None; // üretilen dalganin tipi su an için önemli degil none seçildi 
	
	
	DAC_Init(DAC_Channel_2,&DACInitStructure); // DAC channel 2 için ayarlama yapildigi bildirildi PA5 Channel 2'ye bagli 
	DAC_Cmd(DAC_Channel_2,ENABLE);
	
	DAC_Init(DAC_Channel_1,&DACInitStructure); // DAC channel 1 için ayarlama yapildigi bildirildi PA4 Channel 1'e bagli 
	DAC_Cmd(DAC_Channel_1,ENABLE);
	

}


void adcConfig(){
 
	ADC_InitTypeDef ADCInitStructure; //ADC ayarlamalari icin struct 
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE); // ADC'nin clock hattini aktif ettik ve ADC1'i kullanildi
	
	ADCInitStructure.ADC_ContinuousConvMode=ENABLE; //sürekli çevrim yapsin 	
  ADCInitStructure.ADC_DataAlign=ADC_DataAlign_Right; // most significant bitin saga dayali olacagi bildirildi
	ADCInitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None; // trigger kullanilmiyor 
	ADCInitStructure.ADC_Mode=ADC_Mode_Independent; // single mod okuma yapilacagi icin independent ayarlandi
  ADCInitStructure.ADC_NbrOfChannel=1; // 1 tane adc oldugu icin
	ADCInitStructure.ADC_ScanConvMode= DISABLE; // multichanel ADC kullanimi yapilacaksa aktif edilir diger verilerin cevrimi yapilacagi zaman
	
	ADC_Init(ADC1,&ADCInitStructure); // ADC'nin ayarlarinin yapildigi bildiriliyor 
	ADC_Cmd (ADC1,ENABLE); //ADC1 aktif ediliyor 
	

}


uint16_t readADC(){ // ADC'nin okuma yapacagi fonksiyon

  ADC_RegularChannelConfig(ADC1,ADC_Channel_10,1,ADC_SampleTime_55Cycles5); // ADC1,C0 ADC Channel 10'a bagli,1 adet ADC okumasi yapildi, dogruluk artmasi icin kac cyle'da okuma yapilsin parametreleri
	ADC_SoftwareStartConvCmd(ADC1,ENABLE); // okumanin baslayacagi bildiriliyor
	
	while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)==RESET);// çevrim devam ediyorsa burda kalsin. EOC 
	
	return ADC_GetConversionValue(ADC1); // çevrim bitince sonucu döndür
	


}


void delay( uint32_t time ){

    while (time--);

}






Comments


Son Paylaşımlar

banner300900.gif
banner300900.gif
bottom of page