Ders 4: Kesme İşlemleri ve Timer Bileşeninin Kullanımı

Transkript

Ders 4: Kesme İşlemleri ve Timer Bileşeninin Kullanımı
Hacettepe Robot Topluluğu
PIC Assembly Dersleri
4. Ders: Kesme Đşlemleri ve Timer
Bileşeninin Kullanımı
HUNRobotX - PIC Assembly Dersleri
4. Ders: Kesme Đşlemleri ve Timer
Bileşeninin Kullanımı
Yazan: Kutluhan Akman, Düzenleyen: Canol Gökel - 4 Haziran 2007
Kesmelere Giriş
Bu derse kesme (interrupt) tanımıyla başlayacağız ve TIMER kesmesinin kullanımı ile devam
edeceğiz. Kesmeyi şu şekilde açıklayabiliriz Armada'dan çıktınız ve Ümitköy’e doğru araba ile
gidiyorsunuz. Birden telefonunuz çalıyor ve arabayı kenara çekip konuşuyorsunuz, konuşma
bittikten sonra da yola kaldığınız yerden devam ediyorsunuz. Burada telefonun çalması kesme
oluşturmuş oluyor. Araba kullanmak ise ana programınız. Araba kullanırken kesme oluştu, kesme
programındaki işlemi yaptınız ve ana programa kaldığınız yerden devam ettiniz.
Kesme kullanımı programımızı çok kolaylaştırabilen ve karmaşıklıktan kurtarabilen bir araçtır.
Ne zaman olacağını bilmediğiniz bir durum karşısında programınızın bazı işlemler
gerçekleştirmesini istiyorsanız 2 seçeneğiniz vardır: Ya ne zaman olacağını bilmediğiniz durumun
oluşup oluşmadığını sürekli kontrol etmek ya da kesme kullanarak (sürekli siz programda kontrol
etmezsiniz ama işlemci siz farkında olmadan kontrol eder) sadece o durum oluştuğunda gerekli
işlemleri yapmak. Eğer programınız birçok işlem yapıyorsa kesmeler büyük kolaylık sağlar.
Geçen derste TRISA ve TRISB yazmaçlarını görmüştük, bunlar gördüğümüz ilk ayar
yazmaçlarıydı. TRISA yazmacını kullanarak PORTA'daki hangi ikililerin (pin'lerin) çıkış
hangilerinin ise giriş olarak kullanılacağını ayarlıyorduk. PIC'lerde kesmeleri ayarlamak için
kullanacağımız yine INTCON diye bir yazmacımız var. Hem bank 1'de hem de bank 0'da yer alan
bir yazmaç olduğu için INTCON 'u programlamak için bank değiştirmeye ihtiyacımız olmayacak.
16f84'te kesmelerin oluşabileceği durumlar şunlardır:
1- Eeprom'a yazma işlemi tamamlandığında,
2- Timer zamanlayıcısı taştığı zaman (yani 255'ten tekrar 0'a döndüğünde),
3- PORTB'nin 0. ikilisinden gelen harici bir kesme olduğunda,
4- PORTB'nin 4, 5, 6 veya 7. ikililerinde bir değişme olduğunda.
Siz programınızın yapacağı işleme göre INTCON yazmacını kullanarak bunlardan birisini ya da
istediğiniz kadarını kullanabilirsiniz.
4. Ders: Kesme Đşlemleri ve Timer Bileşeninin Kullanımı
Şimdi sıra ile INTCON'daki ikililerin ne manaya geldiğine bakalım.
O/Y-0
O/Y-0
O/Y-0
O/Y-0
O/Y-0
O/Y-0
O/Y-0
O/Y-X
GIE
EEIE
T0IE
INTE
RBIE
T0IF
INTF
RBIF
ikili 7
GIE: Global Interrupt Enable Đkilisi
ikili 0
EEIE: EE Write Complete Interrupt Enable Đkilisi
T0IE: TMR0 Overflow Interrupt Enable Đkilisi
INTE: RB0/INT External Interrupt Enable Đkilisi
RBIE: RB Port Change Interrupt Enable Đkilisi
T0IF: TMR0 Overflow Interrupt Flag Đkilisi
INTF: RB0/INT External Interrupt Flag Đkilisi
RBIF: RB Port Change Interrupt Flag Đkilisi
O: Okunabilir ikili
Y: Yazılabilir ikili
0: Temizlenmiş ikili
INTCON Yazmacının Đkilileri
7. ikili: GIE
1 yaparsak bütün kesmeler açık (herhangi bir kesme kullanacaksanız 1 olmalı), RETFIE komutu
ile otomatik olarak “1” yapılır.
0 yaparsak bütün kesmeler kapalı (hiçbir kesmeyi kullanmayacaksanız 0 olmalı), herhangi bir
sebeple program kesmeye girdiğinde "0" yapılır.
6. ikili: EEIE
Eeprom'a yazma işlemi bittiğinde kesme oluşmasını istiyorsanız bu biti "1" yapmalısınız,
kullanmayacaksanız "0".
5. ikili: T0IE
Eğer programınızda timer kullanıyorsanız ve istediğiniz kadar saydıktan sonra kesme oluşmasını
istiyosanız T0IE "1" olmalı, kullanamayacaksanız "0".
4. ikili: INTE
Eğer PORTB, 0'a dışarıdan gelen bir veri ile programınız kesmeye girsin istiyorsanız bu bit "1"
HUNRobotX - PIC Assembly Dersleri
olmalı, değilse "0" olmalı. PORTB, 0'a 1 gelince mi yoksa 0 gelince mi kesmeye girmesini
istediğinizi ise OPTION_REG yazmacından ayarlıyoruz. Bundan bu dersin diğer konusunda
bahsedilecek.
3. ikili: RBIE
PORTB'nin son 4 ikilisini (4, 5, 6, 7) giriş olarak ayarladıysanız ve bu girişlerde herhangi bir
değişim olduğunda haberiniz olsun istiyorsanız bu kesme çeşidini kullanabilirsiniz ve bu durumda
bu ikili "1" olmalı, kullanmayacaksanız "0" olmalı.
2. ikili: T0IF
T0IE ikilisini (5. ikili) "1" yaptıysanız ve timer 0 ile kesme oluşursa bu ikili 1 olur ve programınız
kesmeye girer. Böylece kesme programınıza girdiğinizde kesmenin nasıl oluştuğunu
anlayabilirsiniz. Kesmeden dönüşte bunu kendiniz "0" yapmanız gerekir aksi taktirde işlemci bir
daha timer 0 vasıtası ile kesmeye girmeyecektir. Bu şekilde eğer bir daha timer 0 ile kesmeye
girmesini istemiyorsanız bu ikiliyi geri 0 yapmazsınız ve bir daha da timer 0 ile kesmeye girmez.
1. ikili: INTF
INTE ikilisini (4. ikili) "1" yaptıysanız ve PORTB, 0 ile kesme oluşursa bu bit 1 olur ve
programınız kesmeye girer. Böylece kesme programınıza girdiğinizde kesmenin nasıl oluştuğunu
anlayabilirsiniz. Kesmeden dönüşte bunu kendiniz "0" yapmanız gerekir aksi taktirde işlemci bir
daha PORTB, 0 vasıtası ile kesmeye girmeyecektir. Bu şekilde eğer bir daha PORTB, 0 ile
kesmeye girmesini istemiyorsanız bu ikiliyi geri 0 yapmazsınız ve bir daha da PORTB, 0 ile
kesmeye girmez.
0. ikili: RBIF
RBIE ikilisini (3. ikili) "1" yaptıysanız ve PORTB'nin son 4 ikilisi (4, 5, 6, 7) ile kesme oluşursa
bu ikili 1 olur ve programınız kesmeye girer. Böylece kesme programınıza girdiğinizde kesmenin
nasıl oluştuğunu anlayabilirsiniz. Kesmeden dönüşte bunu kendiniz "0" yapmanız gerekir aksi
taktirde işlemci bir daha PORTB'nin son 4 ikilisi (4, 5, 6, 7) vasıtası ile kesmeye girmeyecektir.
Bu şekilde eğer bir daha PORTB'nin son 4 ikilisi (4, 5, 6, 7) ile kesmeye girmesini istemiyorsanız
bu ikiliyi geri 0 yapmazsınız ve bir daha da PORTB'nin son 4 ikilisi (4, 5, 6, 7) ile kesmeye
girmez.
Örnek
Şimdi bir örnek yapalım ve bu örnekte de ilk derste yazdığımız programı kullanalım. Elimizde 1
düğme ve 1 LED var, düğmeye her bastığımızda LED durum değiştirecek. Yani yanıyorsa
sönecek sönüyorsa yanacak. Bunun içinde PORTB, 0 harici kesmesini kullanalım. Tahmin
ettiğiniz gibi düğme PORTB, 0'a bağlı olacak. LED'i de PORTB, 1'e bağlayacağız.
4. Ders: Kesme Đşlemleri ve Timer Bileşeninin Kullanımı
Assembly Programı
Öncelikle PORTB'nin gerekli pin'lerini giriş/çıkış olarak ayarlayalım:
BSF
STATUS, RP0
; Bank 1'e geçtik.
MOVLW B'00000001'
MOVWF TRISB
; Port B'nin 0. ikilisi hariç tüm ikililerini çıkış
; yaptık.
BCF
STATUS, RP0
; Geri bank 0'a geçtik.
Şimdi INTCON yazmacını ayarlayalım.
MOVLW B'10010000'
;
;
;
;
;
7. ikili 1, dolayısı ile istediğimiz kesmeleri
kullanabiliriz. 4. ikili 1, PORTB kesmesini
kullanacağız, geri kalan ikililerle bu
programda işimiz olmadığı için onları "0"
yaptık.
MOVWF INTCON
GOTO $
; GOTO komutunda "$" işareti bulunulan satırı ifade
; ediyordu, yani bulunduğun satırda kal demek oluyor bu
; komutun bütünü.
Kesmeyi ayarladıktan sonraki işlem kesme alt programını yazmak olmalı. Kesme programları
0x004 numaralı program hafızasından başlayarak yazılıyordu, o zaman ORG komutu ile gerekli
adresi belirtmeliyiz. Ama programın ortalarına bunu yazamayız o yüzden şimdi yazacağımız
kesme programını sonradan programın üst tarafına taşımalıyız.
ORG
0x000
; Program buradan başlayacak,
HUNRobotX - PIC Assembly Dersleri
GOTO
ORG
BTFSS
GOTO
main
; Sonra da ana programa gidecek.
0x004
; Kesme alt programı ise buradan başlayacak.
INTCON, INTF
; Kesme PORTB, 0 ile mi oluşmuş?
KESMEDENCIK
; PORTB, 0 ile oluşmadıysa yapacak işlemim yok,
; kesmeden çık.
MOVLW B'00000010'
; PORTB, 1'i bu sayı ile XOR yaparsam; PORTB, 1
; işlemden önce "1" ise "0" olur, "0" ise "1"
; olur yani yanıyosa söner sönükse yanar.
XORWF PORTB, F
BTFSC PORTB, 0
; PORTB, 0 daki düğme bırakıldı mı?
GOTO $-1
; Bırakılmadıysa bırakılana kadar bekle, çünkü düğmeye
; basılı konumdayken kesmeden çıkarsa, yine düğmeye
; basılmış gibi algılanıp tekrar kesmeye girer ve ben
; bunu istemem.
KESMEDENCIK
BCF
INTCON, INTF
; Kesmeden çıkarken INTCON, INTF'i "0" yapmalıyım
; ki tekrar kesmeye girebilrsin.
RETFIE
; Ana programda kaldığın yere geri dön.
Şimdi komutların hepsini yerli yerine yazarak programımızı düzenleyecek olursak:
list
p=16F84
; Projenizi hangi işlemci ile yapacağınızı
; belirtiyorsunuz. Bu satırı programın başına yazdık.
__CONFIG
_CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC ; Kullanacağınız donanım
; konusunda bilgi veriyoruz (Bkz: 2. Ders notları)
#include <p16F84.inc>
; (Bkz: 2. Ders notları)
#DEFINE
PORTB, 1
LED
; Eğer yapacağınız tanımlama varsa onlar da
; buraya gelecek.
ORG
GOTO
ORG
BTFSS
GOTO
0x000
; Program buradan başlayacak,
main
; Sonra da ana programa gidecek.
0x004
; Kesme alt programı ise buradan başlayacak.
INTCON, INTF
; Kesme PORTB, 0 ile mi oluşmuş?
KESMEDENCIK
; PORTB, 0 ile oluşmadıysa yapacak işlemim yok,
; kesmeden çık.
MOVLW B'00000010'
; PORTB, 1'i bu sayı ile XOR yaparsam PORTB, 1
; işlemden önce "1" ise "0" olur, "0" ise "1"
; olur. Yani LED, yanıyorsa söner sönükse yanar.
XORWF PORTB, F
BTFSC PORTB, 0
; PORTB, 0'daki düğme bırakıldı mı?
GOTO $-1
; Bırakılmadıysa bırakılana kadar bekle, çünkü düğmeye
; basılı konumdayken kesmeden çıkarsa, yine düğmeye
; basılmış gibi algılanıp tekrar kesmeye girer ve ben
; bunu istemem.
KESMEDENCIK
BCF
INTCON, INTF
; Kesmeden çıkarken INTCO, INTF'i "0" yapmalıyım
; ki tekrar kesmeye girebilirsin.
4. Ders: Kesme Đşlemleri ve Timer Bileşeninin Kullanımı
RETFIE
; Ana programda kaldığın yere geri dön.
main
BSF
STATUS, RP0
; Bank 1'e geçtik.
MOVLW B'00000001'
MOVWF TRISB
; Port B’nin 0. ikilisi hariç tüm ikililerini çıkış
; yaptık.
BCF
STATUS, RP0 ; Geri bank 0'a geçtik
MOVLW B'10010000' ; 7. ikili 1, dolayısı ile istediğimiz kesmeleri
; kullanabiliriz. 4. ikili 1, PORTB kesmesini
; kullanacağız. Geri kalan ikililerle bu programda
; işimiz olmadığı için onları "0" yaptık.
MOVWF INTCON
GOTO $
; GOTO komutunda "$" işareti bulunulan satırı ifade ediyordu.
; Yani bu komutun bütünü "bulunduğun satırda kal" demek
; oluyor.
END
; Programımız burada bitiyor.
Programımızdaki "GOTO $" satırı yerine uzunca bir program gelebilirdi. Bu durumda bile bizim
düğme ve LED'in çalışmalarında hiçbir aksama olmaz, işlemci LED'i yakıp söndürmek için diğer
işlemleri bitirmeyi beklemezdi. Bunu kendiniz GOTO $ komutu yerine bir program yazarak
deneyiniz.
Eeprom kesmesi 6. derste ayrıntılı olarak anlatılacağından burada bahsetmeyeceğim. PORTB'nin
son 4 ikilisi ile ilgili kesmede (veya herhangi başka bir konuda) ise anlaşılmayan birşey varsa
forumda sorabilirsiniz
Kesme Kullanırken Dikkat Edilmesi Gerekenler
1- Programınız ana programın herhangi bir yerinde iken kesme koşulları gerçekleşebilir ve bu
durumda ana programda kullandığınız değişkenlerin içerikleri, mesela W yazmacının içeriği ve
SFR'lerin içerikleri kesmeden çıkışta değişime uğramış olabilir. Bu yazmaçlar kesme programında
da kullanılıyorsa ve değiştiriliyorsa, kesme programının başında bu yazmaçların yedeğini
almalısınız ve kesmeden çıkarken eski değerlerini geri yüklemelisiniz,
2- 1'den fazla kaynaktan kesme alıyorsanız (mesela hem timer, hem PORTB, 0) kesme
programının başında hangi nedenle kesme oluştuğunu kontrol edip ona göre gerekli işlemleri
yapmalısınız,
3- Kesme programından çıkarken, hangi kesme oluştu ise INTCON'daki o kesmeye ait interrupt
flag ikilisini tekrar pasif (0) yapmalısınız ki tekrar o kaynaktan kesme oluşabilsin.
HUNRobotX - PIC Assembly Dersleri
Timer
16F84'ün içinde dahili olarak zamanlama veya sayma işlemlerinizi kolaylaştırması için timer (geri
sayım) bileşeni bulunmaktadır. Bunun ismi TIMER 0'dır ve TMR0 yazmacı vasıtasıyla içeriği
kontrol edilir, OPTION_REG vasıtası ile de ayarları yapılır.
O/Y-1
O/Y-1
O/Y-1
O/Y-1
O/Y-1
O/Y-1
O/Y-1
O/Y-1
RBPU
INTEDG
T0CS
T0SE
PSA
PS2
PS1
PS0
ikili 7
RBPU: Global Interrupt Enable Đkilisi
ikili 0
INTEDG: Interrupt Edge Select Đkilisi
T0CS: TMR0 Clock Source Select Đkilisi
T0SE: TMR0 Source Edge Select Đkilisi
PSA: Prescaler Assignment Đkilisi
PS2-PS0: Prescaler Rate Select Đkilileri
O: Okunabilir ikili
Y: Yazılabilir ikili
1: Kurulmuş ikili
OPTION Yazmacının Đkilileri
Her yazmaç gibi bu da 8 ikililik bir yazmaçtır. 0–5. ikilileri yazmacı ayarlamak için kullanılır.
7. ikili: RBPU
Hatırlarsanız bir düğme bağlarken, eğer düğmeye basılınca "1" gelmesini istiyorsak düğmenin bir
tarafını direk "+"ya diğer tarafını ise bir dirençle "-"ye ve PIC'e bağlıyorduk. (yukarıdaki
resimdeki gibi). Bu işleme pull-down denir. Yani düğmeye basılmadığı anda girişi "0"
seviyesinde tutmak için kullanılır. Düğmeye basılmazken PIC bir direnç vasıtasıyla "-"ye bağlı
iken düğmeye basılınca direk "+" ya bağlı olur ve bu sayede düğmeye basılınca "+" basılmazken
de "-" gelir. Eğer bağlantıları değiştirip dirençli kısmı "+"ya bağlasaydık ve diğer kısmı da direk
"-"ye bağlasaydık bu işleme pull-up denirdi.
Đşlemcinin içinde de opsiyonel olarak direnç bağlamanıza gerek duymadan pull-up işlemini
yapabilirsiniz ama sadece PORTB için. Eğer bu ikiliyi 1 yaparsanız pull-up dirençlerini
işlemcinin içinden, haricen kullanmadan bağlayabilirsiniz. Eğer "0" yaparsanız kullanmazsınız.
4. Ders: Kesme Đşlemleri ve Timer Bileşeninin Kullanımı
6. ikili: INTEDG
Eğer PORTB, 0'ı kesme işlemi için kullanıyorsak, bu bacağa "0" gelince mi kesme olacak yoksa
"1" gelince mi kesme olacak bunu değiştirebiliriz. Eğer bu ikili "0" olursa "0" gelince, "1" olursa
"1" gelince kesme gerçekleşir.
5. ikili: T0CS
Timer 0'da sinyal kaynağı olarak 2 seçeneğimiz var (hani ya zaman sayacak, ya da istediğimiz bir
şeyi sayacak ya). Đşlemciye bağlamış olduğumuz osilatörü (kristali) ya da dışarıdan vereceğimiz
bir veriyi kaynak olarak kullanabiliriz. Eğer dışarıdan bir kaynak vereceksek bunun verileceği yer
PORTA, 4'tür.
Bu bit "1" olursa timer 0 kaynağını PORTA, 4'ten alır, eğer "0" olursa timer 0 kaynağını
osilatörden alır. Timer 0 kaynağı osilatör olarak belirtilirse Osc/4 olarak kaynağı kullanır. Yani 4
MHz lik kristal kullanıyorsanız, timer 0'ın kaynağı 1 MHz'tir yani saniyede 1 milyon defa sinyal
algılıyordur.
4. ikili: T0SE
Bu ikili "1" olursa timer 0, döngü sinyalinin düşen kenarı ile sayar, "0" olursa çıkan kenarı ile
sayar.
Düşen kenar: Bir düğmeye basınca + geldiğini düşünelim. O zaman düğmeyi bıraktığımız an
+'dan -'ye geçmiş ve dolayısı ile düşen kenar üretmiş oluyoruz.
Çıkan kenar: Düğmeye basınca + geliyorsa, düğmeye bastığımızda çıkan kenar üretmiş oluruz.
Bu durumları şekilde görerek neden "düşen kenar" ve "çıkan kenar" tanımlarının kullanıldığını
daha iyi anlayabiliriz:
Sinyalimiz (Volt)
Düşen Kenar
5 (Yani +)
0 (Yani -)
Zaman
Çıkan Kenar
3. ikili: PSA
Bu ikili "0" ise önbölücü, timer 0 için kullanılır; "1" ise WDT için kullanılır. WDT'yi daha sonraki
HUNRobotX - PIC Assembly Dersleri
derslerde göreceğiz. Önbölücü ise gönderdiğimiz sinyalleri gruplandırarak her grubun 1 sinyal
olarak kabul edilmesini sağlar. Mesela önbölücü değeri 8 ise, her sinyalde timer 1 artacağına 8
sinyalde 1 artar.
2. 1. ve 0. ikililer:
Bu bitler ile önbölücünün değeri ayarlanır.
Đkililerin Değerleri TMR0 Oranı WDT Oranı
000
1:2
1:1
001
010
011
100
101
110
111
1:4
1:8
1 : 16
1 : 32
1 : 64
1 : 128
1:2
1:4
1:8
1 : 16
1 : 32
1 : 64
1 : 256
1 : 128
Tablo 1: Önbölücü Oran Seçimi Đkilileri
Eğer bu ikilileri 000 olarak ayarlarsak önbölücü değeri 2 olur, yani her 2 sinyal geldiğinde timer
0, 1 sinyal gelmiş gibi işlem yapar. Eğer 256 sinyalde 1 sinyal gelmiş gibi davranmasını istiyorsak
bu 3 ikiliyi 111 olarak ayarlamalıyız.
Örnek
Kendi kendine yanıp sönen bir LED yapalım, fakat bu yanıp sönmedeki zamanlamayı timer ile
ayarlayalım. LED'imiz PORTA, 0'a bağlı olsun ve saniyede 2 defa yanıp sönsün. Saniyede 2 defa
yanıp sönmesi için her yanma ve sönme arasında ¼ saniye yani 250 milisaniye olsun. Bu
gecikmeyi sağlamak için biraz matematik hesabı ile önbölücü ayarlarını yapmalıyız. Eğer
önbölücü ayarları yeterli gelmezse, kesme hizmet programı içerisine birkaç satırlık bir tekrarlama
algoritması ekleyerek zamana ince ayar çekebiliriz.
Önbölücü Ayarlarının Yapılması
Eğer 4 Mhz'lik kristal kullanıyorsak 1 mikrosaniye de TMR0 yazmacının içeriği 1 artacak
demiştik. TMR0, 8 ikililik bir yazmaç olduğuna göre maksimum 255'e kadar artabilir. Önbölücü
ayarlanarak bu 1 mikrosaniyelik sürenin değiştirilebileceğini söylemiştik. Eğer önbölücü 16
olursa, TMR0'ın içeriği 16 mikrosaniyede 1 artacaktır. Bu da demektir ki sağlayabileceğimiz
maksimum gecikmeyi 16 kat arttırdık. 4 Mhz kullanılarak toplam sağlanabilecek gecikmeye
bakalım:
Her TMR0 artması için gerekli gecikme×TMR0 ' ın sayacağı miktar×önbölücü değeri
4. Ders: Kesme Đşlemleri ve Timer Bileşeninin Kullanımı
= 1x256x256=65536 mikrosaniye =65.536 milisaniye
Görüldüğü gibi maksimum sağlanabilecek gecikme bizim gereksinimimizin çok altında. Bu
durumda kesme hizmet programında kesmeye girilen miktarı saydırarak, gecikme miktarını
arttırmamız gerekecek. Bunu en yakın olarak sağlamak için hesaplarımızı yapalım:
50 milisaniyelik gecikme sağlarsak bunu da kesme alt programında 5 kere saydırırsak ihtiyacımız
olan 250 milisaniyelik gecikmeyi sağlamış oluruz.
50 milisaniyelik gecikme için, önbölücüyü 256 olarak ayarlarsak ve TMR0 ile 195 saydırırsak
195×256=49.92 milisaniyelik bir gecikme hesaplamış oluruz. Bu da bizim için yeterli. TMR0
256 olunca taşıyor, kesme oluşturuyor demiştik. 195 saydırmak için TMR0'ı öyle bir değerden
başlatmalıyız ki 195 sayınca 256'ya ulaşmalı, bu değer de tabii ki 256195=61 'dir. Yani TMR0
saymaya başlamadan önce içeriğine 61 sayısını yüklemeliyiz. Kesme alt programında da 5 kere
saydırma işlemini yaptığımızda gerekli gecikme programı yazılmış olacak.
Assembly Programı
list
p=16F84A
#include <p16F84A.inc>
__CONFIG
Denetleyiciyi tanımladık.
Denetleyicinin kendisine has
tanımlamalarını yüklemek için
kullanılmıştır.
_CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC
#DEFINE
SAYAC EQU
ORG
;
;
;
;
LED
0X19
0x000
PORTA,0
; Kesme programında 5 kere saydırma işlemi için
; kullanılacak
; Denetleyicinin reset vektör adresi, reset yaparsak
; Program buradan devam eder
GOTO BASLA
ORG
0X004
DECFSZ
SAYAC
GOTO KESMEDENDON
MOVLW D'5'
; SAYAC 1 azaltıldı, 0 ise 1 komut atlandı.
; SAYAC "0" değilse RETFIE ile tekrar kesmenin
; oluştuğu adrese geri dönüldü.
; Eğer SAYAC "0" olduysa buraya atlanacak ve bir sonraki
; kesmeye hazırlık olması için tekrar SAYAC yazmacına
; desimal 5 değeri yüklendi.
MOVWF SAYAC
MOVLW B'00000001'
XORWF PORTA
KESMEDENDON
MOVLW D'61'
MOVWF TMR0
; LED bağlı yer olan PORTA'da XOR işlemi ile
; durum değiştirildi, yanıyorsa söndürüldü,
; sönükse yakıldı.
HUNRobotX - PIC Assembly Dersleri
BCF
INTCON,T0IF
RETFIE
; Tekrar TMR0 kesmesi ile kesme oluşabilmesi
; için INTCON, T0IF = 0 yapıldı.
; Programda kalınan yere geri dönüldü.
BASLA
BSF
STATUS,RP0 ; BANK1'e geçildi.
BCF
TRISA, 0
; TRISA, 0 "0" yapılarak, PORTA, 0 çıkış yapıldı
MOVLW B'00000111' ; Đlgili ikililerle ilgili açıklama ders içeriğinde
; verilmiştir.
MOVWF OPTION_REG
BCF
STATUS,RP0 ; BANK0'a geçildi.
BCF
LED
; LED'in ilk konumu sönük olarak ayarlandı.
MOVLW B'10100000'
; Đlgili ikililerin açıklaması ders içeriğinde
; verilmiştir.
MOVWF INTCON
MOVLW D'61'
; Yaptığımız hesaplamada TMR0'a 61 yükleyerek
; istediğimiz zaman gecikmesini sağlamıştık.
MOVWF TMR0
MOVLW D'5'
MOVWF SAYAC
GOTO $
; Bu komut yerine 1000 satırlık bir program da yazsak
; LED'imizin istediğimiz zaman aralığında yanıp sönmesine
; zeval gelmez. Đşte bu yüzden kesme denen şeyi icat
; etmişler.
END
Kaynaklar
Antrak Gazetesi
PIC 16F84 Datasheet
Bağlantılar
http://robot.ee.hacettepe.edu.tr/
http://www.microchip.com/

Benzer belgeler

Slayt 1 - cobanoglu

Slayt 1 - cobanoglu Örnek 5: Timer kesmesi ile 4 Bitlik Binary(ikili) Geri Sayıcı(15-0) LIST P=16F84A #INCLUDE CLRF PORTB BSF STATUS, 5 MOVLW b'11010111' MOVWF OPTION_REG MOVLW h'0F' MOVWF TRISA CLRF TRI...

Detaylı