22 Şubat 2011 Salı

2. Kesmeler (devam 2)

Devre 5
Öncelikle devremizi inceleyelim. Devre yapı itibariyle diğer devrelerden farklı değil. PortB.0 bacağına bir buton bağlanmış PortC ucuna ise dört adet led bağlı. (Led’lerin çalışma voltajı +5V’a alınmış ve bu nedenle de direnç bağlanmamıştır.)

Burada RB0 harici kesmesinin nasıl kullanılacağını inceleyeceğiz. Port isimlerine dikkat edilirse RB0/INT ifadesini göreceksiniz. Buradaki INT kısaltması interrupt kelimesinin kısaltmasıdır yani bu ucun kesme giriş noktası olduğunu göstermektedir. Butonun bağlanışına dikkat ederseniz, Buton basılı değilken bu uç Logic 0’da kalmaktadır. Butona basıldığında ise Logic olarak 1 durumuna gitmektedir. Bu önemli bir durumdur. Çünkü bu girişin hangi Logic durumda kesmeye gideceği ayarlamamız gerekmektedir. Dışarıdan gelen bilgi Logic 1 olduğunda kesme oluştur yada Logic 0 olduğunda kesme oluştur. Hangi durum devremiz için uygunsa birisinin seçilmesi gerekir. Eğer bu ayar yapılmadı ise standart olarak bu Logic 1’e gidince kesme oluştura ayarlıdır. Bunun ayarlamasını daha sonraki örnekte inceleyeceğiz. Şimdiki örneğimizde kesme Logic 1’deyken oluşacaktır.
 Prg 16:

           Device 16F877
XTAL 4

 TRISB = %00000001
 PORTB = 0
 TRISC = 0
 PORTC = 0

 ON_HARDWARE_INTERRUPT GoTo Kesme
 INTCON = %10010000 
 GoTo AnaProgram

Kesme:
    Toggle PORTC.1
    INTCON.1 = 0
Context Restore

AnaProgram:
    PORTC.0=1
    DelayMS 500
    PORTC.0=0
    DelayMS 500
GoTo AnaProgram


Klasik cihaz ve kristal tanımlamalarının ardından Portların tanımlamaları yapılmıştır. PortB’nin 0 nolu ucu giriş diğer uçları çıkış, PortC’nin bütün uçları çıkış olarak tanımlanmıştır.

“ON_HARDWARE_INTERRUPT GoTo Kesme” satırında donanımsal kesme oluştuğunda ana programdan ayrılıp gidilmesi gereken etiket adresi belirtilmiştir.

 INTCON = %10010000 satırında  ise evrensel kesme ile birlikte PortB.0 kesmesi aktif hale getirilmiştir. Hemen arkasından GoTo Ana Program diyerek asıl çalışacak olan program etiketine gidilmiştir. Çünkü eğer bu işlem yapılmaz ise kesme rutini programın başında tanımlandığı için kesme oluşmasa da kesme rutini çalışacaktır. Bu istenmeyen bir durumdur bu yüzden programın çalışması sırasında kesme rutininin üzerinden atlanması gerekmektedir.

Ana program içinde yapılan işlem programdan da görebileceğiniz gibi 500 Ms aralıklar ile PortC.0’a bağlı olan led’in yakılıp söndürülmesidir. Bu işlem mikrodenetleyici tarafından bir döngü içinde sürekli tekrar edilirken eğer butona basılırsa bir kesme oluşacaktır. Programın neresinde olursanız olun kesme oluştuğunda direk olarak kesme isimli alt programa yönlenirsiniz. Bu alt programda PortC.1’rine bağlı Led durum değiştirecektir. Alt programdan geri dönerken önce ilgili bayrağı INTCON.1 = 0 komutunu kullanarak sıfırlamamız gerekmektedir. Context Restore komutu ile de ana programda kaldığımız yere geri dönmekteyiz. Eğer bayrağı sıfırlamadan ana programa geri dönersek bayrak hala Logic 1 olduğu için yeniden kesme oluşmamış olsa bile kesme alt programına tekrar geri dönüş yaparız.

Bu programı eğer kesme kullanmaz isek aşağıdaki şekilde de yazabiliriz.

Prg 17:

            Device 16F877
XTAL 4

 TRISB = %00000001
 PORTB = 0
 TRISC = 0
 PORTC = 0

AnaProgram:
    If PORTB.0=1 Then Toggle PORTC.1
    PORTC.0=1
    DelayMS 500
    PORTC.0=0
    DelayMS 500
GoTo AnaProgram


Yukarıdaki programın kesme kullanmadan farkı ne diye düşünürseniz; programa dikkatli baktığınızda farkın çok büyük olduğunu göreceksiniz. If önermesi ile butona basılmasının kontrolü yapıldıktan sonra yaklaşık olarak 1 sn boyunca butona basılma kontrolü tekrar yapılmamakta. Eğer bu sırada butona basılıp çekilirse program butona basıldığının farkına varmayacaktır. Normal çalışmasına devam edecektir.  Böylelikle basılan tuşlar kaçırılacak ve programınız yapması gereken işi yapamayacaktır.