Haberler:

Foruma Resim Yükleme ve Boyut Sınırlaması ( ! )  https://bit.ly/2GMFb8H

Ana Menü

I. Sayfada INTERRUPT

Başlatan ahmetinrodisi, 28 Kasım 2005, 21:43:43

ahmetinrodisi

Merhaba arkadaşlar.Programımda kullandığım kesmeyi org 0x800  adresinden başlatmak istiyorum.Bunu yapmak için ise şöyle bir yöntem denedim:

org 0x004
nop
bcf PCLATH,4
bsf PCLATH,3            ;Select page 1
goto Kesmeye_git
...
...
...
org 0x800
Kesmeye_git
movfw PCLATH
movwf PCLATH_TEMP

...
...
movfw PCLATH_TEMP
movwf PCLATH
retfie
End

Böyle deneyip MPLAB da execute yaptığımda sorun olmuyor, fakat proteus da simulasyonunu yaptığımda proteus kilitlenip öyle kalıyor.Bilgisayarımın CPU su % 100 oluyor yani.Form da yaptığım araştırmalarda bu sayfa problemi ile ilgili güzel siteler var ama işin içinden ben çıkamadım.Programlar ve kullanılan dil çok kompleks geldi bana.Pic lerin Datasheetinde Paging başlığı altında bu konu var ama Interrupt tan bahsetmiyor.Bahsediyor şöyle:Intterrupt olduğu zaman PCLATH i koruyun.şu paging sorunuyla ilgili projemde en az 10 kez 20 kez denemeler yaptıysamda bir türlü başaramadım arkadaşlar.Bende
datasheetlerdeki ve formlardaki aynı şeyleri yazıyorum:

ORG 0x500
BCF PCLATH,4
BSF PCLATH,3 ;Select page 1
;(800h-FFFh)
CALL SUB1_P1 ;Call subroutine in
: ;page 1 (800h-FFFh)
:
ORG 0x900 ;page 1 (800h-FFFh)
SUB1_P1
: ;called subroutine
;page 1 (800h-FFFh)
:
RETURN ;return to
;Call subroutine
;in page 0
;(000h-7FFh)

Fakat bir türlü page 1 deki komutları okutamıyorum yada programım hiçbirzaman doğru dürüst çalışmıyor.Sırf bu yüzden başaramazsam daha üst seviyeli yeni bir dil öğrenip projemi öyle yazmayı deneyecem.Her geçen başarısız deneme morali çok kötü bozuyor arkadaşlar.Bu sorunu başaracağıma ümidim kalmadı diyebilirim.Son şansım benden önce bu yollardan geçen sizler arkadaşlar.Gerçekten dileğin benden ne dilerseniz :)

XX_CİHAN_XX

Bir zamanlar bende aynı dertden muzdarip olmuştum.Sanırım şöyle yapman gerek.

org 0x004
nop
bcf PCLATH,4
bsf PCLATH,3 ;Select page 1
goto Kesmeye_git
...
...
...
org 0x800
Kesmeye_git
...
...
...

BCF PCLATH,4
BCF PCLATH,3
retfie
End

Bu şekilde çalışacagını dusunuyorum
Yirmi yaşındaki bir insan, dünyayı değiştirmek ister . Yetmiş yaşına gelince , yine dünyayı değiştirmek ister, ama yapamayacağını bilir.

refik1

ahmetinrodisi  nin sayfa değişimindede sorun yok aslında
eğerki 800h adresinde pclath nin 3 bitini değiştirmiyorsa


XX_CiHAN_XX  arkadaşımın yazdığıda çalışmazise
birde şunu dene  aslında hepsininde çalışması lazım.


org 0x004
nop
bcf PCLATH,4
bsf PCLATH,3 ;Select page 1
goto Kesmeye_git
Alt_Programdan_çık
retfie





...
...
...
org 0x800
Kesmeye_git
...
...
...

BCF PCLATH,4
BCF PCLATH,3
goto     Alt_Programdan_çık
End

ahmetinrodisi

sağolun arkadaşlar. Şimdi denedim birçok kez fakat sonuç yine olumsuz. Org 800 den başayan kesme 0A0B adresinde bitiyor.Yani page2 ye geçmiyor. Denerken şöyle bişey keşfettim ama.Org 800 ve 804(dahil) arası LCD de hiç mesj yok.org 805 yazdığımda kesmeye_git ifadesinin hemen üstünde bulunan birkaç karekter ekrana çıkıyor.Org 806 da ise proteusda sim. yaparken CPU % 100 oluyor.org 807 de ve daha sonrası için Kesme çalışmıyor, ama diğer şeyler normal çalışıyor.Belkide kesme çalışıyor ama ekrana doğru mesjları göndereceğine boş şey gönderiyor.Bilmiyorum arkadaşlar.Gerçekten çalışması gereken program abuk bubuk hatalar yapıyor.Isteyen arkadaşlara,yardımcı olabilecek arkadaşlara pogramı ve Proteusdaki halini gönderebilirim.Program çok uzun diye, birde bu programla kim uğraşır diye çekiniyorum arkadaşlar.Tekrar herşey  için çok teşekürler.

XX_CİHAN_XX

;********************************************
;RB0 KESMESINE BIR ORNEK
;KESME ALT PROGRAMI SAYFA1 DE YER ALMAKTADIR
;********************************************
                     LIST              P=16F877
                  INCLUDE              "P16F877.INC"
;********************************************
                  ORG                     0x00
                  GOTO              START
                   ORG                     0x04
;********************************************
                  BCF               INTCON,INTF         ;BUNU UNUTMA ONEMLI
                    BCF               PCLATH,4
                  BSF               PCLATH,3
                       GOTO               KESME
;********************************************
START
                  BSF               STATUS,5
                   MOVLW               0xFF
                     MOVWF               TRISB
                  CLRF               OPTION_REG     ;PULL_UP ENABLE/RB0 DUSEN
                      MOVLW                 .6                     ;KENAR OLARAK AYARLANDI
                    MOVWF                  ADCON1   ;TÜM PORTLAR DİJİTAL I/O KONUMUNDA
                  BCF                STATUS,5
;GEREKLİ SETUPLARI KENDİ PROGRAMINA GORE YAP
                   MOVLW                  0x90
                   MOVWF                INTCON          ;RB0 KESMESI AKTIF YAPILDI
;********************************************
MAIN
                     NOP
;GEREKLI KOMUTLAR      
                   NOP
                   GOTO                MAIN
;********************************************
;********************************************
                      ORG                       0x800
;********************************************
;********************************************
KESME
                  NOP
;GEREKLI KOMUTLAR      
                   NOP
;********************************************
                    BCF                       PCLATH,4
                  BCF                PCLATH,3      
                     RETFIE
;********************************************
                   END
 
Yukarıdaki programın mplabta simulasyonunu yaptım ve kesme geldiğinde org 800 e gidip geri dönebildiğini gördüm.Dolayısıyla sende bu mantıkla yazdıysan programını bir sorun olmaması gerekiyor.Böyle yaptığın halde düzgün çalışmıyorsa problemı baska yerde aramalısın.Benim tavsiyem programı proteustan once mplabda simule et ve bak kesmeye gitmesi gerekn yerde gidip donmesı gerekn yerde donuyormu.Programı bu sekılde adım adım ızle ve nerde sapıttıgını tespıt et.Ondan sonra gerklı duzeltmenı yap ve tekrar sımule et mplabda!
Hata duzelıncede proteusta denersın dostum kolay gelsin.
Yirmi yaşındaki bir insan, dünyayı değiştirmek ister . Yetmiş yaşına gelince , yine dünyayı değiştirmek ister, ama yapamayacağını bilir.

arslan74

Merhaba arkadaşlar,

Sayfalar arasında geçişte Mplap'ın ASM si bu konuda bize cok iyi bir kolaylık getirecek "pagesel" komutu ile donatılmış. CALL veya GOTO ile gideceğimiz sayfayı kontrol etmek yerine direkt "pagesel" komutu ile yapabiliriz. Böylelikle gideceğimiz yerin sayfa bilgisini bilmemiz gerekmemektedir.

Aşağıda kullandığım bir örneği kontrol edin.

INTERRUPT


;============================================================
movwf    w_temp                ; W'i W_temp'e sakla.
swapf    STATUS,w             ; status'u status_temp'e sakla
movwf    status_temp 

MOVFW	PCLATH          ; interrupta hangi sayfadan gelmiş isen
MOVWF	pclath_sakla    ;  pclath_sakla'a kayıt et.

clrf      PCLATH          ; page0 secili.
	
;============================================================



BTFSS    INTCON,INTF             ;INT. RB0'DAN Mİ GELDİ.
GOTO     INTEND	               ;HAYIR

;EVET RB0'DAN GELDİ.
BCF      INTCON,INTF		

;------------------------------------------------------------------------------------------
;Bu komut ile INT_RB0 adresinin bulunduğu sayfayı  derleyici otomatik secer. 
;Programda daha sonra INT_RB0 yerini değiştirsende programın çalışmasında hiç bir hataya neden olmaz.
; INT_RB0 dan INTEND giderkenden aynı şekilde 
;
; pagesel  INTEND
; goto     INTEND
;
; Şeklinde yapın.
;------------------------------------------------------------------------------------------

pagesel     INT_RB0 

GOTO        INT_RB0			; RB0 INT GİT.

;------------------------------------------------------------------------------------------

;=============================================================
;=============================================================
INTEND
	

MOVFW	pclath_sakla	; pclath ı geri yükle
MOVWF	PCLATH
 
    swapf    status_temp,w           ; Saklanan Status değerini geri yükle.
    movwf    STATUS 

    swapf    w_temp,f                  ; W'i geri yükle.
    swapf    w_temp,w 

    retfie 
;============================================================

XX_CİHAN_XX

Pagesel komutunu unutmustum epeybı sure asm den elimi çekince boyle oldu tabı neyse arkadaşımızın yazdıgı program gayat detaylı ve guzel.
Fakat bir şey çok merak ettim sormadan edemiyecem daha oncede gormustum birçok programda mesaela statusu status_temp e yuklerken swapf komutunu kullanmıssın tabı aynı sekılde gerı alırkende bunun bır ozellıgımı var cunku movf ve movwf ıle de aynı ıslemı yapabılırsın.
Her ikiside aynı kapıya cıkmaz mı?
Mesela,
   movwf   w_temp
diyerek yedeklediğin w degerini,
   swapf    w_temp,f                  ; W'i geri yükle.
   swapf    w_temp,w
bu iki komut satırı ile geri almıssın onun yerine
   movf     w_temp,w
diyerek tek satırla geri alamazmıydın.Niye bu tur yedekleme işlemlerini illede swap kullanarak yatıgını merak ediyorum.Başka bir ozelliği mi oluyor boyle yapınca diye ister istemez düşünüyorum çunku bu sekılde birkac programda daha rastladım.Bana göre hiçbir espirisi yok bilmediğim birşey varsa bununla ilgili öğrenmek isterim.Saygılarımla,
Yirmi yaşındaki bir insan, dünyayı değiştirmek ister . Yetmiş yaşına gelince , yine dünyayı değiştirmek ister, ama yapamayacağını bilir.

arslan74

Yazar Mesaj XX_CİHAN_XX :
Alıntı YapFakat bir şey çok merak ettim sormadan edemiyecem daha oncede gormustum birçok programda mesaela statusu status_temp e yuklerken swapf komutunu kullanmıssın tabı aynı sekılde gerı alırkende bunun bır ozellıgımı var cunku movf ve movwf ıle de aynı ıslemı yapabılırsın.
Her ikiside aynı kapıya cıkmaz mı?

Cevab, her ikiside aynı kapıya cıkmaz.

Nedeni,

İnterrup ile, ana program herhangi bir yerde kesiliyor ve interrupta giriyor.
Tekrar int. den ana programa girerken W ve STATUS registerlerin içindeki bilgiler int. önceki bilgilerle aynı olmalı aksi takdirde program doğru calışmaz. W nin neden saklanması gerektiğini anlatmama gereyok sanırım.
STATUS'ü saklamamızın nedeni ise içinde sakladığı IRP, RP1, RP0, TO, PD, Z, DC, C bitlerini korumak içindir.
Peki nedne SWAPF'le saklaniyorda MOVFW sonrada MOVWF şeklinde saklanmiyor sorusuna gelince. "movf" komutunu incelendi mi cevabı kendiliğinden geliyor. Pic'in datasheetlerinde INSTRUCTION SET SUMMARY incelendiğinde de MOVF komutundan STATUS'ün Z (zero-sıfır) bitinin etkilendiği görülür. Yani STATUS'un içindeki bilgi H'00' olsun bunu MOVF komutu ile aktarırsak, Bu işlemde bilgi sıfır olduğu için Status'un Z biti etkilenir ve bir olur. Bu durumda H'00' bilgisi değilde H'04' bilgisi aktarılmış olur. int. cıkarkende aynı işlem gecerlidir. Oyüzden MOVF komutu ile STATUS bilgisi doğru olarak saklamaz. Peki neden SWAPF komutu ile kullanıldığı sorusuna gelince.

Cünkü SWAPF komutu ile STATUS'un içinde bitler etkilenmez.

Umarım cevabım sizi tatmin etmiştir.


Çalışmalarınız da başarılar,

Hasan ARSLAN

ahmetinrodisi

Çok sağolun arkadaşlar.Sorunu nihayet çözebildim.Dediğiniz gibi yapıp olayi simulasyonda denedim.Bu zamana kadar hep aynı hatayi yapmışım.Hep gözümden kaçmış.Yaptığım hata: Kesme içinde 0. sayfadan tablo okuma ifadeleri var,ben pclath e sayfa 0'ı yüklüyordum fakat geri döndükten sonra yani call komutundan sonra sayfa 1 i PCLATH e yüklemiyordum.Dolayisiyle program ilk goto komutunda sayfa 1 de gitmesi gereken yere değil sayfa 0 da rastgele biryerlere gidiyordu.MPLAB simulasyonu gerçekten çok güzel.Özellikle simule ederken Watch kısmından yazmaçları izleme olanağı çok kolaylık sağlıyor.Tekrar hepinize çok teşekürler arkadşlar, sizlerin açıklamaları olmasaydi başaramazdım.Sağlıcakla kalın...