STM32VLDISCOVERY Push Button ve Led ile Inturrupt Mantığı

Güncelleme tarihi: 25 Kas

Interrupt: İşlemcinin devam eden komutları bırakarak interruptın gösterdiği komutları yapması ve sonra bıraktığı komutlara kaldığı yerden devam etmesi olarak tanımlanabilir. Türkçe’de kesme olarak da kullanılmaktadır. CPU’ya içerden veya dışardan olmak üzere farklı kaynaklardan gelebilir. İşlemciyi oluşturan çevrebirimlerle haberleşmek ve programların uyumlu calışması için kesmeler kullanılır. Yazılım kesmeleri(software interrupts), donanım kesmeleri (hardware interrupts) olmak üzere iki tür kesme vardır. Yazılım interruptlarında makine komutlarıyla programa dahil edilen kesmeler vardır. Donanım interruptlarında bir çevre birim tarafından işlemcinin kesme biriminin aktifleşmesiyle gerçekleşir ve kesme olduğunda çalışacak program gerçekleşir. Donanım kesmeleri de kendi içinde ikiye ayrılır. Bunlardan ilki önlenebilir kesme (IRQ-Interrupt Request), ikincisi ise önlenemez kesme (Non-Maskable Interrupt-NMI) olarak tanımlanır. IRQ’de işlemcinin kesme birimine komut geldiyse kesme gerçekleşir, kesme talebi gelmediyse işlemci kendi işlerine devam eder, gerçekleşmez. NMI’de ise hiçbir zaman bir kesme isteğine bağlı değildir. Programcı tarafından önlenemezler.




İşlemcide NVIC (Nested Vectored Interrupt Controller) kesmelerden sorumlu birimdir. Arm çekirdeğine kesme gelince karşılayan ilk kısımdır. Cortx-M çekirdeğiyle birlikte kesmelerden sorumlu NVIC gelir. Bir tane de bunla birlikte calısan SysTick timer gelir, doğrudan çekirdeğe erişebilen bir timer. İşletim sistemi kullanılmasa da sıradan bir timer gibi kullanılabiliyor.


Kesmelerin ayarlarının yapılası için NVIC ve kesme hatlarının (örneğin kesme anında hangi port aktif olacak) ayarlarının yapılması gerekir. Bu uygulamada NVIC ve EXTI ayarlamaları yapılmıştır. Harici kesme hangi line'da gerçekleşecekse o belirlenmiştir. Ledler out olarak kullanılmış push butondan input bilgisi alınmış ve butona basıldığında ledler kendi çalışmasını bırakıp 4 kez yanıp sönmektedir. Bu yanıp sönme işlemi bitince de kendi işlemlerine kaldığı yerden devam etmektedirler.


Kartın user manuelinde bulunan blok diyagramda de görüldüğü gibi çevrebirimlerin kullanılması için clock hatlarının aktifleştirilmesi gerekmektedir. Örneğin bu uygulamada kullanılan B ve C portu APB2 clock hattına bağlıdır ve clock ayarı yapılmıştır. Yine aynı şekilde EXTI interruptun bağlı olduğu bus hattı da APB2 clocktur. Ayrıca yine blok diyagramda Cortex-M3 CPU işlemcisinin hemen altında NVIC birimi bulunmaktadır. Burası da işlemcinin kesmelerden sorumlu ve herhangi bir kesmeyi ilk karşılayan kısımdır.





Malzemeler:

  • Led

  • Jumper kablolar

  • STM32VLDISCOVERY

  • Push button

  • 220 ohm direnç


Devre Şeması ve Kod:



#include "stm32f10x.h"                  // Device header
#include "stm32f10x_exti.h"             // Keil::Device:StdPeriph Drivers:EXTI


// 3 tane led yanarken sirayla butona basildiginda interrupt da gerceklesiyor ve ledler ayni anda yanip sönüyor.

void gpioConfig(); //pinlerin ayarlamalarinin yapildigi fonksiyon
void extiConfig(); //interrupt ayarlamalarinin yapildigi fonksiyon
void delay(); //gecikme fonksiyonu 




int main (){
	
gpioConfig(); //pinlerin giris cikis olarak ayarlanmasi fonksiyonu
extiConfig(); // interrupt ayarlamasi ve kesme gercekleseceginde hangi islem yapilacak onun ayarlari fonsiyonu 
	
int ledArray[]={GPIO_Pin_0,GPIO_Pin_1,GPIO_Pin_2};	
	


while (1){ // bu kisimda interrupt gerceklesmezken ledler sirayla yanip sonmektedir 

for(int i=0;i<3; i++){
GPIO_SetBits(GPIOB,ledArray[i]);
delay(3600000);
GPIO_ResetBits(GPIOB,ledArray[i]);
delay(3600000);

}

for(int i=1;i>0; i--){
GPIO_SetBits(GPIOB,ledArray[i]);
delay(3600000);
GPIO_ResetBits(GPIOB,ledArray[i]);
delay(3600000);

}


}


}

void gpioConfig(){

	
	GPIO_InitTypeDef GPIOInitStructure;
	
	RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOB,ENABLE); //B portu için clock hatti aktif edildi ledler icin kullanilacak
	RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOC,ENABLE); //C portu icin clock aktif edildi buton icin kullanilacak
	
	GPIOInitStructure.GPIO_Mode=GPIO_Mode_Out_PP; //ledin push pull olarak kullanilacaginin ayari
	GPIOInitStructure.GPIO_Pin=GPIO_Pin_0 | GPIO_Pin_1| GPIO_Pin_2; //ledlerin pinleri B portunun 0 1 ve 2. pinleri
	GPIOInitStructure.GPIO_Speed=GPIO_Speed_50MHz; //hiz ayari
	GPIO_Init(GPIOB,&GPIOInitStructure);// B portundaki ayarlamalarin bildirilmesi
	
	
	GPIOInitStructure.GPIO_Mode=GPIO_Mode_IPD; // buton input olarak kullanildi, pull down
	GPIOInitStructure.GPIO_Pin=GPIO_Pin_0; // buton pinin baglandigi yer, C portu pin 0. Hiz ayarina gerek yok input oldugu icin 
  GPIO_Init(GPIOC,&GPIOInitStructure);	// C portundaki ayarlamalarin bildirilmesi
	


}

void extiConfig(){ //kesmelerin ayarlamalarinin yapildigi fonksiyon
	
	
	//2 structure olmali bir tanesi islemcinin kesme birimi NVIC digeri çevre birimlerden gelen harici kesme için EXTI
	
	EXTI_InitTypeDef EXTIIinitStructure;
	NVIC_InitTypeDef NVICInitStructure; 
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); // harici kesmelerin clock hatti aktif edildi
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource0); // hangi portta ve pinde gerceklesecekse interrupt bildirildi.  
	
	EXTIIinitStructure.EXTI_Line=EXTI_Line0; //kesmenin hangi lineda gerceklesecegi. Line0'da cunku C0 hatti line0'a bagli.
	EXTIIinitStructure.EXTI_LineCmd=ENABLE;
	EXTIIinitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
	EXTIIinitStructure.EXTI_Trigger=EXTI_Trigger_Rising;
	
	EXTI_Init(&EXTIIinitStructure); //EXTI ayarlarinin yapildigi bildiriliyor
	
	NVICInitStructure.NVIC_IRQChannel=EXTI0_IRQn; // Interrupt gerceklesince hangi fonksiyon cagirilacak onu belirler, line 0'daki interrtupt calisacak
  	NVICInitStructure.NVIC_IRQChannelCmd=ENABLE; // Interrupt sirasinda fonksiyona gitmesi gerektigi
	NVICInitStructure.NVIC_IRQChannelPreemptionPriority=1; //kesmenin öncelik sirasi 
	NVICInitStructure.NVIC_IRQChannelSubPriority=1;
	
	NVIC_Init(&NVICInitStructure); //NVIC ayarlarinin yapildigi bildiriliyor

}


void delay (uint32_t time){


while(time--);


}


void EXTI0_IRQHandler(){ // harici kesme gerceklestiginde calisacak olan fonksiyon. Ismı onceden belirli. 
	

if(EXTI_GetITStatus(EXTI_Line0)!=RESET){// Line0'a gelen bilgi varsa yani reset degilse sürekli calissin

for (int i=0; i<4; i++){ //kesme aninda ledler 4 kez yanip sonsun

GPIO_SetBits(GPIOB, GPIO_Pin_0 | GPIO_Pin_1| GPIO_Pin_2);

	
	delay (3600000);

GPIO_ResetBits(GPIOB, GPIO_Pin_0 | GPIO_Pin_1| GPIO_Pin_2);
	
	delay (3600000);
	
	
}

EXTI_ClearITPendingBit(EXTI_Line0); // kesme süresi dolunca kesmenin bittigini de haber vermek gerekiyor.
}




}






Son Paylaşımlar