STM32 PROGRAMLAMA – STM32F4 TİMER İNPUT CAPTURE

Bu yazımda bir genel amaçlı zamanlayıcı kullanarak bir PWM sinyalinin sinyalinin darbe genişliğini ölçmeyi anlatacağım. Bu işlemleri bir STM32 mikrodenetleyici üzerinden anlatıyor olsamda mantığını anladıktan sonra herhangi bir mikrodenetleyiciyi kullanarak aynı ölçümleri yapabilirsiniz.

Öncelikle konuya başlamadan önce Zamanlayıcının ne olduğunu açıklamak istiyorum. Zamanlayıcı(timer) içerisinde bir adet sayıcı barındıran en önemli çevrebirimlerinden biridir. Her ne kadar zamanlayıcı olarak adlandırılsada donanım olarak özünde bir sayıcıdır zaman sayma işlemi yapmaz sadece kendisine gelen saat frekansı ile orantılı olarak lineer sayma işlemi gerçekleştirir ve biz bu sayma işleminin hızını kullanarak zaman bilgisine ulaşırız. Ölçmek istediğimiz zaman aralığında sayıcının kaç defa saydığını ölçerek ve bu değeri sayıcı frekansıyla çarparak o zaman aralığını hesaplayabiliriz.

PWM(Pulse Width Modulation), darbe genişliği modülasyonu bir kare dalga sinyalin doluluk oranı(duty cycle) nı değiştirerek o sinyalin analog çıktısını kontrol ettiğimiz yöntemdir. Özellikle mikrodenetleyici gibi sadece 0 ve 1 lerden oluşan dijital sistemlerde analog çıktı oluşturmanın en kolay yollarından birisidir. Fakat, bu yazımızda bu sinyalin analog karşılığından ziyade bu kare dalga sinyalin frekansı ve darbe genişliği ile ilgileneceğiz.

Yukarıda ki gibi bir PWM sinyalin frekansını ölçmek için yapmamız gereken şey iki yükselen kenar arasında geçen zamanı ölçmektir. Bu işlemi yaparken timer input capture modunu kullanmak gayet basit. Yapacağımız işlem özünde, ilk yükselen kenar anındaki sayıcı değerini bir değişkene kaydedip ikinci yükselen kenardaki sayıcı değerini yeni bir değişkene kaydedip daha sonra farklarını almaktır.

Darbe genişliğini ölçmek için ise , ilk yükselen kenarda kaydettiğimiz sayıcı değerinden sonra kesme polaritesini düşen kenara ayarlayıp bir sonraki düşen kenar anındaki sayıcı değerini yakalayıp aynı işlemi yapmalıyız.

Timerımızı input capture modu nda ayarladığımız zaman bu bahsettiğim yükselen ve düşen kenar kesmeleri oluştuğu anda sayıcı değeri donanım tarafından CCRx yazmacına kaydedilir ve biz bu CCR yazmacının değerini okuyarak işlem yapabiliriz.

Yukarıdaki fonksiyon ile timer2 nin 2 nolu kanalı input capture olarak ayarlandı ve Nvic tarafında kesmesi aktif edildi. Şimdi sıra bu yükselen ve düşen kenar kesmeleri oluştuğu zaman yapacağımız işleme geldi.

void timer2_init(void)
{
// 1 - timer2 nin clock unu aktif et
	 RCC->APB1ENR |= (1<<0); 
	
// 2 - input pinin bagli oldugu gpioA clock unu aktif et
	 RCC->AHB1ENR |= (1<<0);
	
// 3 - PA1 pinin GPIO ayarlarini yap
	
	GPIOA->MODER |= (1<<3);
	GPIOA->MODER &= ~(1<<2); // Alternate function olarak ayarla
	
	GPIOA->AFR[0] = 0b000000000010001; // AF1 olarak belirle
	

	
// 4 - timer2 ayarlarini yap
	
	TIM2->PSC = 99;
	TIM2->ARR =4000000;
	TIM2->CR1 |= (1<<0);  // sayıcı aktif
	TIM2->CCMR1 |= (1<<8); // CC2 channel is configured as input, IC2 is mapped on TI2.
	TIM2->CCER |= (1<<4);  // yakalama aktif
	TIM2->DIER |= (1<<0);  // update interrupt aktif
	TIM2->DIER |= (1<<2); 	//ch2 interrupt aktif
	TIM2->CCER &= ~TIM_CCER_CC2P; // polarity mode yükselen kenar
	
	
	
	

	
// 5 - nvic tarafinda timer2 ayarlarini yap
	
        NVIC_EnableIRQ(TIM2_IRQn); 
	NVIC_SetPriority(TIM2_IRQn, 0x03);

	
}
void TIM2_IRQHandler(void)
{
	
	
if(TIM2->SR & TIM_SR_CC2IF)
		
{

if((TIM2->CCER & TIM_CCER_CC2P)==0)     // kanalin aktif olmasi kesmenin oradan gelecegi anlamina gelmez/gpio pinini kontrol et
{
ch2yukselen = TIM2->CCR2;      // yukselen kenar degerini kaydet
TIM2->CCER |= TIM_CCER_CC2P;   // polariteyi düsen kenar olarak degistir
}

else
{
ch2dusen = TIM2->CCR2;
fark = ch2dusen- ch2yuselen;  // dusen kenar degerini kaydet ve yukselen kenar degerinden cikar
if(fark< 0)fark += 0xFFFF;    // eger sonuc negatifse taban tumleme yap
if(fark< 2010 && fark> 990)ch2=fark;
				
TIM2->CCER &= ~TIM_CCER_CC2P; // polariteyi yukselen kenar olarak ayarla

}
			
	TIM2->SR &= ~TIM_SR_CC2IF; // kesme bayrağını sıfırla
	
}
	

	
	}

yukarıda ki kesme fonksiyonu ile yükselen kenar ile düşen kenar arasındaki zamanı ölçerek darbe genişliğini belirleyebiliriz.

Timer ın sayıcısının çalışma frekansı, bağlı olduğu clock hattının prescaler değerinin bir fazlasına bölündüğündeki değere eşittir. Tİmer2 ikin bağlı olduğu clock hattı 100Mhz de çalışmakta iken ben precaler değerine 99 atayınca sayıcı frekansım 1 Mhz olmaktadır. Yani her 1 mikrosaniyede bir sayacaktır. ARR yazmacı ise sayıcımın maksimum değerini belirtmektedir ve bu uygulamada spesifik bir değer vermemiz gerekmiyor.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s