Download as pdf or txt
Download as pdf or txt
You are on page 1of 10

KOCAELİ ÜNİVERSİTESİ - MEKATRONİK MÜHENDİSLİĞİ MİKRODENETLEYİCİ LABORATUARI

DENEY-5

SABANCI ATL ÖĞRETMENLERİNDEN YAVUZ AYDIN ve UMUT MAYETİN'E VERDİKLERİ


DESTEK İÇİN TEŞEKKÜR EDİYORUZ

31
KOCAELİ ÜNİVERSİTESİ - MEKATRONİK MÜHENDİSLİĞİ MİKRODENETLEYİCİ LABORATUARI

MİKRODENETLEYİCİDE KESME BİRİMİ

Mikrodenetleyicinin değişik kaynaklardan gelen uyarıcı sinyaller ile mevcut programın


çalışmasını kesip, önceden tanımlanmış alt programı işleterek tekrar ana programa dönüp
kaldığı yerden devam etmesi işlemine ‘kesme’‘ ’ denir. Tasarımı yapılan sistemlerde çoğunlukla
çıkış verileri belirli girişler karşılığında değiştirilmektedir. Bu sebepten giriş verilerinin sürekli
denetlenmesi gerekliliği doğar. Denetleme esnasında mikrodenetleyici çalışma süresinin ve
hızının büyük bir kısmı işgal edilir. Bu da karmaşık sistemlerde mikrodenetleyicinin
mikrodenetleyicinin bazı giriş
değişimlerini kaçırmasına sebep olabilir.

Program aracılığıyla yapılan belirli zaman aralıklarında sürekli olarak kontrol edilen işleme
‘yoklama’’ adı verilir. Yoklama işlemi ile aynı anda sadece bir işlem yapılacağından,
mikrodenetleyicilerde çeşitli kesme birimlerinden faydalanılır. Program ile yapılması gereken
işlemler kesme alt programı tarafından donanımsal olarak yapılırsa aynı anda birden fazla işlem
yapılmış olur. Bu nedenlerden dolayı yoklama işlemi yerine ‘kesme’ arabirimi kullanılır. Özetle:
 Sürekli denetim (yoklama) işleminde
o Mikrodenetleyici, yalnızca bir bayrak ya da giriş/çıkış ucunu kontrol edebilir.
o Dolayısıyla başka bir işlem gerçekleştirememektedir.
 Kesme yönteminde
o Mikrodenetleyici normal çalışmasına devam
de etmektedir
o Herhangi bir kesme sinyali oluştuğunda o kesmeye ait alt programı gerçekleştirip,
ana programa (kaldığı yere) geri dönülmektedir.
o Bu sayede mikrodenetleyici aynı zamanda birden fazla işlemi gerçekleştirebilir.

çalıştırıla alt programa “kesme hizmet programı” (ISR-Interrupt Service


Kesme geldiğinde çalıştırılan
Routine) denir.

PIC mikrodenetleyicilere enerji ilk geldiği anda veya PIC sıfırlandığında(resetlendiğinde)


program sayacı 0000h adresini gösterir. Bu adrese reset vektörü denir. Böylelikle
mikrodenetleyici enerji uygulandığında ilk başta 0000h adresine bakar. Buradaki komutu
işleyerek çalışmaya başlar. Aynı özellik kesme durumlarından biri meydana geldiğinde de
gerçekleşir. Kesme durumunda program sayacı 0004h adresine gider. Bu adrese kesme kesm vektörü
denir. Bu adreste kesme alt programının(ISR) başlangıç adresi vardır.

32
KOCAELİ ÜNİVERSİTESİ - MEKATRONİK MÜHENDİSLİĞİ MİKRODENETLEYİCİ LABORATUARI

MİKRODENETLEYİCİDE KESME BİRİMİ

Bir kesme isteği alındığında mikrodenetleyicide şu işlemler gerçekleşir;


 O an çalıştırılmakta olan komutun çalışması tamamlanır.
 Program sayacının değeri (PC) yığına (Stack) kaydedilir.
 Diğer kesmeler (düşük öncelikli) engellenir.
 Program kesme vektör adresine yönlendirilir.
 Buradan kesme alt programının başlangıç adresi program sayacına yüklenir.
 Kesme hizmet programı çalışmaya başlar.
 Kesme altprogramı tamamlandığında yığından en son kalınan ana programa ait
komut adresi program sayacına geri yüklenir. Normal program akışı devam eder.

Mikrodenetleyicide herhangi bir kesme meydana geldiğinde o kesmeye ait bayrak (flag) ‘1’
olur. Kısaca kesme bayrağı aktif olur. PIC16F877A mikrodenetleyicisinde 14 adet kesme kaynağı
bulunur. Bu kesme kaynaklarının kontrolü ve ayarları için kullanılan kaydediciler şunlardır:

Kaydedici Adı Görevi Adresi


OPTION_REG Timer0 kontrol kaydedicisi (Harici Kesme) 81h
INTCON Kesme kontrol kaydedicisi 0Bh
PIE1 Çevresel kesme yetkilendirme-1 kaydedicisi 8Ch
PIE2 Çevresel kesme yetkilendirme-2 kaydedicisi 8Dh
PIR1 Çevresel kesme bayrakları-1 kaydedicisi 0Ch
PIR2 Çevresel kesme bayrakları-2 kaydedicisi 0Dh

CCS C ile PIC programlamda kullanılan Kesme Direktifleri ve Komutları

 #int_XXX // Kullanılacak kesmeye ait altprogramının başlangıcını gösterir.


○ #INT_AD // Analog-dijital dönüşüm tamamlandı kesmesi
○ #INT_CCP1 // CCP1 biriminde Capture veya Compare sağlandı kesmesi
○ #INT_CCP2 // CCP2 biriminde Capture veya Compare sağlandı kesmesi
○ #INT_EEPROM // EEPROM yazma tamamlandı kesmesi
○ #INT_EXT // Harici kesme
○ #INT_OSCF // Sistem osilatörü hatası kesmesi
○ #INT_PSP // Paralel porttan veri alındı kesmesi
○ #INT_RB // Port B (B4-B7) değişiklik kesmesi
○ #INT_RDA // Seri porttan veri alındı kesmesi
○ #INT_SSP // SPI veya I2C aktiflik kesmesi
○ #INT_TBE // Seri port veri gönderim belleği boş kesmesi
○ #INT_TIMER0 // Timer 0 (RTCC) taşma kesmesi
○ #INT_RTCC // Timer 0 (RTCC) taşma kesmesi
○ #INT_TIMER1 // Timer 1 taşma kesmesi
○ #INT_TIMER2 // Timer 2 taşma kesmesi

33
KOCAELİ ÜNİVERSİTESİ - MEKATRONİK MÜHENDİSLİĞİ MİKRODENETLEYİCİ LABORATUARI

MİKRODENETLEYİCİDE KESME BİRİMİ

 #priority kesme_ismi, kesme_ismi…


Bir kesme meydana geldiğinde o kesme fonksiyonu yürütülürken başka bir kesme meydana
gelse dahi aktif olamaz. İlk başta yürütülen kesme fonksiyonu bitmesi gereklidir. Fakat aynı
anda meydana gelen kesmelerde hangi kesmenin geçerli olacağını belirlemek için öncelik
verilmelidir.
○ #priority ext, timer0, timer1 // Kesme öncelikleri sırayla ext, timer0 ve timer1

 enable_interrupts(kesme_ismi); // Kesmeleri aktif etmek için kullanılır.


○ enable_interrupts(INT_EXT) // Harici kesme aktif
○ enable_interrupts(INT_TIMER1) // Timer1 kesmesi aktif
○ enable_interrupts(GLOBAL) // Aktif kesmeler için genel kesme yetkisi ver.

 disable_interrupts(kesme_ismi); // Kesmeleri pasif etmek için kullanılır.


○ disable_interrupts(INT_EXT) // Harici kesme pasif
○ disable_interrupts(INT_TIMER1) // Timer1 kesmesi pasif
○ disable_interrupts(GLOBAL) // Aktif kesmeler için genel kesme devre dışı

 clear_interrupt(kesme_ismi);
Kesme bayraklarını temizlemek için kullanılır. Bir kesme altprogramına girildiğinde kesme
işlemi sonlandırılırken kesme bayrağı otomatik olarak temizlenir. Kesme bayrağını elle
temizlemek için kullanılır.
○ clear_interrupt(INT_EXT) // Harici kesme bayrağını temizle
○ clear_interrupt(INT_CCP1) // CCP kesme bayrağını temizle

 ext_int_edge(value); // Harici kesme pini kenar seçimini belirler.


○ ext_int_edge(H_TO_L); // ‘1’ den ‘0’a düşerken kesme
○ ext_int_edge(L_TO_H); // ‘0’ dan ‘1’e yükselirken kesme

34
KOCAELİ ÜNİVERSİTESİ - MEKATRONİK MÜHENDİSLİĞİ MİKRODENETLEYİCİ LABORATUARI

DENEY 5-1: MİKRODENETLEYİCİDE HARİCİ KESME UYGULAMASI

AMAÇ: Mikrodenetleyicilerde harici kesme birimini kullanımını öğrenmek.

GİRİŞ: PIC16F877A mikrodenetleyicisinde harici kesme özelliğine sahip yalnızca 1 pin


bulunmaktadır. Bu pin PORTB’nin 0 nolu pini olup RB0/INT olarak adlandırılmaktadır. 40 pin
yapısına sahip 18FXXX ve 18FXXXX serisi mikrodenetleyicilerin birçoğunda 3 adet harici kesme
özellikli pin bulunmaktadır. Belirtilen pinlerin dışındaki diğer pinlere bu özellik atanamaz.
Donanımsal olarak tanımlanmış bu pinlerin dışındaki herhangi bir pine harici kesme özelliği
atanamaz.

Harici kesme özelliği yoğun bir komut akışına sahip sistemlerde acil olarak duruma
müdahale edilmesi isteniyorsa sıklıkla tercih edilir. Kesme işlemi sonrasında sistem tekrar
kaldığı yerden çalışmaya devam eder.

Bu uygulamada mikrodenetleyicide PORTD’ye bağlı 8 adet led üzerinde farklı


animasyonlar gerçekleştirilecektir. Sistem çalıştığında birinci animasyon ile başlayacaktır.
Sistem ledler üzerinde yanıp sönme işlemini gerçekleştirirken kesme butonuna basılırsa,
sıradaki animasyona geçilecektir. Kesme butonuna her basıldığında diğer animasyon
görüntüsüne geçilecektir.

NOT: Uygulamada yer alan butonun sorgulanması işlemini önceki uygulamalarda verildiği
gibi sürekli döngü içerisinde yapılması durumunda nasıl bir sonuç alınacağını test ediniz.

Animasyon 1 

Animasyon 2 

Animasyon 3 

Animasyon 4 

Animasyon 5 

35
KOCAELİ ÜNİVERSİTESİ - MEKATRONİK MÜHENDİSLİĞİ MİKRODENETLEYİCİ LABORATUARI

DENEY 5-1: MİKRODENETLEYİCİDE HARİCİ KESME UYGULAMASI

DEVRE ŞEMASI

KESME PROGRAMI AKIŞ DİYAGRAMI

//KESME PROGRAMI BAŞLAT

//”animasyon” değeri 5’ten küçükse,


değeri 1 arttır.

//Değilse “animasyon” değerini 1


yap.

//KESME PROGRAMI BİTİR

36
KOCAELİ ÜNİVERSİTESİ - MEKATRONİK MÜHENDİSLİĞİ MİKRODENETLEYİCİ LABORATUARI

DENEY 5-1: MİKRODENETLEYİCİDE HARİCİ KESME UYGULAMASI

AKIŞ DİYAGRAMI

//Başlık dosyası tanıt


//Osilatör ayarla
//Ana program başlat

//8bitlik animasyon isimli


değişken tanımla
//PORTD çıkış
//PIN_B0 giriş
//PORTD = 0x00
//EXT_INT aktif
//Genel kesme aktif

//Sonsuz döngüyü başlat.

//”animasyon” değeri 1’e eşitse


//PORTD’ye 0x00 gönder
//250ms bekle
//PORTD’ye 0xFF gönder
//250ms bekle

//”animasyon” değeri 2’ye eşitse


//PORTD’ye 0xF0 gönder
//250ms bekle
//PORTD’ye 0x0F gönder
//250ms bekle

//”animasyon” değeri 3’e eşitse


//PORTD’ye 0xC3 gönder
//250ms bekle
//PORTD’ye 0x3C gönder
//250ms bekle

//”animasyon” değeri 4’e eşitse


//PORTD’ye 0x99 gönder
//250ms bekle
//PORTD’ye 0x66 gönder
//250ms bekle

//”animasyon” değeri 5’e eşitse


//PORTD’ye 0xAA gönder
//250ms bekle
//PORTD’ye 0x55 gönder
//250ms bekle

//Sonsuz döngüye git.

//Ana programı bitir.

37
KOCAELİ ÜNİVERSİTESİ - MEKATRONİK MÜHENDİSLİĞİ MİKRODENETLEYİCİ LABORATUARI

DENEY 5-1: MİKRODENETLEYİCİDE HARİCİ KESME UYGULAMASI

UYGULAMA KODLARI

#include "16F877A.h" //Mikrodenetleyici başlık dosyası tanıtılır.


#fuses XT //Kristal osilatör kullanılacak.
#use delay(clock=4M) //delay komutları için osilatör hızı 4Mhz
int8 animasyon=1; //8bitlik “sayi” isminde değişken tanımla
/*----------------------------------------------------------------------------*/
#int_EXT //Harici kesme programı göstergesi
void kesme_prog(void) //Harici kesme programı başlangıcı
{
if(animasyon < 5) //”animasyon” değeri 5’ten küçükse
animasyon ++; //”animasyon” değerini 1 arttır.
else //”animasyon” değeri 5’ten küçük değilse
animasyon = 1; //”animasyon” değişkenine 1 değeri yükle.
}
/*----------------------------------------------------------------------------*/
void main(void) //Ama program başlangıcı
{
set_tris_d(0x00); //PORTD’nin tüm pinlerini çıkış olarak kullan
output_float(PIN_B0); //PIN_B0 pini giriş olarak kullan
output_d(0x00); //PORTD’ye 0x00 bilgisi gönder.
ext_int_edge(L_TO_H); //Harici kesme Lojik 0’dan 1’e geçerken
enable_interrupts(INT_EXT); //Harici kesme aktif
enable_interrupts(GLOBAL); //Aktif kesmeler için genel kesme yetkisi ver
while(1) //Sonsuz döngü başlangıcı
{
/*----------------------------------------------------------------------------*/
if(animasyon == 1) //”animasyon” değeri 1’e eşitse
{
output_d(0x00); delay_ms(250); //PORTD’ye 0x00 gönder, 250ms bekle
output_d(0xFF); delay_ms(250); //PORTD’ye 0x00 gönder, 250ms bekle
}
/*----------------------------------------------------------------------------*/
if(animasyon == 2) //”animasyon” değeri 2’ye eşitse
{
output_d(0xF0); delay_ms(250); //PORTD’ye 0xF0 gönder, 250ms bekle
output_d(0x0F); delay_ms(250); //PORTD’ye 0x0F gönder, 250ms bekle
}
/*----------------------------------------------------------------------------*/
if(animasyon == 3) //”animasyon” değeri 3’e eşitse
{
output_d(0xC3); delay_ms(250); //PORTD’ye 0xC3 gönder, 250ms bekle
output_d(0x3C); delay_ms(250); //PORTD’ye 0x3C gönder, 250ms bekle
}
/*----------------------------------------------------------------------------*/
if(animasyon == 4) //”animasyon” değeri 4’e eşitse
{
output_d(0x99); delay_ms(250); //PORTD’ye 0x99 gönder, 250ms bekle
output_d(0x66); delay_ms(250); //PORTD’ye 0x66 gönder, 250ms bekle
}
/*----------------------------------------------------------------------------*/
if(animasyon == 5) //”animasyon” değeri 5’e eşitse
{
output_d(0xAA); delay_ms(250); //PORTD’ye 0xAA gönder, 250ms bekle
output_d(0x55); delay_ms(250); //PORTD’ye 0x55 gönder, 250ms bekle
}
/*----------------------------------------------------------------------------*/
}
}

38
KOCAELİ ÜNİVERSİTESİ - MEKATRONİK MÜHENDİSLİĞİ MİKRODENETLEYİCİ LABORATUARI

DENEY 5-2: MİKRODENETLEYİCİDE ZAMANLAYICI KESMESİ UYGULAMASI

UYGULAMA KODLARI (TIMER1 BİRİMİ)

TIMER1 birimi ile 1ms süreyi elde etmek için hesaplama formülünü yazarak bölme
oranını ve sayma başlangıç değerini belirleyelim.
Tov = Tosc x BölmeOranı x (65536 – TMR1)
1000 usn = 1usn x BölmeOranı x (65536 – TMR1)
1000 = BölmeOranı x (65536 – TMR1)

TIMER1 biriminde 1:1, 1:2, 1:4 ve 1:8 olmak üzere dört tür bölme oranı vardır. Basit bir
hesapla bölme oranı 1:1 seçildiğinde 1000 kez zamanlayıcı değerinin artışı toplam süre olarak
1ms’ye karşılık gelecektir. TIMER1 birimi 16bit olduğunda bölme oranları ve sayma değerinin
ayarlanması oldukça kolaydır. Bu durumda programda kullanılacak komut şu şekilde olacaktır.
setup_timer_1 ( T1_INTERNAL | T1_DIV_BY_1 );
#include "16F877A.h" //Mikrodenetleyici başlık dosyası tanıtılır.
#fuses XT //Kristal osilatör kullanılacak.

int16 say = 0; //16bitlik “say” isimli değişken tanımla.


#int_TIMER1 //TIMER1 kesme programı göstergesi
void kesme_prog(void) //Kesme programı başlangıcı
{
set_timer1(64536); //TIMER1 sayma değerini “64536”ya kur.
if(say < 999) //”say” değişkeni değeri 999’dan küçükse
say ++; //”say” değişkeni değerini 1 arttır.
else //”say” değişkeni değeri 999’dan küçükdeğilse
{ say = 0; //”say” değişkeni değerini 0 yap.
output_toggle(PIN_D0); } //PIN_D0 pinini Lojik olarak tersle.
}
void main(void) //Ana program başlangıcı
{
setup_timer_1(T1_INTERNAL | T1_DIV_BY_1); //TIMER1 birimini, zamanlayıcı
//…olarak 1:1 bölme oranı ile
//…kullan.
set_tris_d(0x00); //PORTD’nin tüm pinleri çıkış
output_d(0x00); //PORTD’ye 0x00 bilgisi gönder.
set_timer1(64536); //TIMER1 sayma değerini “64536”ya kur.
enable_interrupts(INT_TIMER1); //TIMER1 kesmesi aktif.
enable_interrupts(GLOBAL); //Aktif kesmeler için genel kesme yetkisiver.
while(1) //Sonsuz döngü başlangıcı
{ } //Sonsuz döngüyü işlemsiz döndür.
}

39
KOCAELİ ÜNİVERSİTESİ - MEKATRONİK MÜHENDİSLİĞİ MİKRODENETLEYİCİ LABORATUARI

MİKRODENETLEYİCİDE KESME UYGULAMASI

SORULAR

1. Yedi segment gösterge üzerinde 0’dan F’ye 100ms aralıklarla sayma işlemi
gerçekleştirilirken kesme butonuna basılması durumunda sayma işlemini durduran, sayma
işlemi durmuş olduğu anda kesme butonuna basılırsa tekrar saymaya devam etmesini sağlayan
programı yazınız.
2. Mikrodenetleyicide PORTD’ye bağlı ledler üzerinde 20ms aralıklarla 8bit binary sayıların
artarak saymasını sağlayan, kesme butonuna basıldığı anda o anki sayma değerini PORTC’ye
bağlı ledler üzerinde gösteren ve yine PORTD’Ye bağlı ledler üzerinde saymaya devam eden
programı yazınız.
3. Aşağıda verilen program bloğunda her bir satırın yanına açıklama yazınız. Tüm sistemin
çalışmasını kısaca özetleyiniz.

#include "16F877A.h"
#fuses XT
#use delay(clock=4M)

int1 stop = 0;
int8 sayac = 0;

#INT_EXT
void ext_isr(void)
{
if(stop == 0)
stop = 1;
else
stop = 0;
}
void main(void)
{
set_tris_d(0x00);
output_d(0x00);
ext_int_edge(L_TO_H);
enable_interrupts(INT_EXT);
enable_interrupts(GLOBAL);
while(1)
{
if(stop == 0)
{
output_d(sayac);
sayac++;
delay_ms(20);
}
}
}

40

You might also like