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
Örnek 5: Timer kesmesi ile 4 Bitlik Binary(ikili) Geri Sayıcı(15-0)
LIST P=16F84A
#INCLUDE