Haberler:

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

Ana Menü

rb0 kesme sorunu

Başlatan feridunarslan, 09 Şubat 2007, 09:55:34

feridunarslan

merhaba arkadaşlar
rb0 kemesi oluşup tamamlandığında programın kaldığı yerden değilde benim istedigim yerden yada program kodlarının basından başlamasını istiyorum bunu asm ile nasıl yaparım yardım ederseniz sevinirim

Prof.EleCTroN

kesme programı sonunda kullanılan retfie komutu yığından kesilmiş olan program adresini alıp o adrese GIE bitini aktif yaparak atlar. Eğer kesmeden sonra başka bir adrese gidilmek isteniyora goto komutu kullanılır. Önemli bir husus GIE biti eğer kesme tekrar yapılmak isteniyorsa uygun bir yere goto dan önce yada sonra aktif edilmelidir.
Kesme_Prog
.
.
.
.
Kesme_Prog_Sonu
goto Istenilen_Prog

feridunarslan

tam anlayamadım kesme alt programı içerisinde GIE bitini sıfırlayıp retfie den sonramı goto komutu ile istedigimiz adrese gidiyoruz ve bu arada tekrar goto komutundan sonra yada önce GIE bitini set ediyoruz biraz acarmısın

Prof.EleCTroN

Kesme programı bittikten sonra tekrar kesme yapmak istiyorsan GIE bitini '1' yapman gerekir. RETFIE komutu bunu otamatik yapar (aynı zamanda programda kalınmış yere geri döndürür) fakat biz bunun yerine istediğimiz adrese gitmesi için GOTO komutunu kullanıyoruz, bu komut sadece istenilen adrese atlama yapar. (Kısaca istenilen adrese gitmesi için RETFIE yerine GOTO kullanıyoruz.) Kesme özelliğinin aktif olması içinde mikroişlemcinin kesme mantığına benzer bir şekilde yapmak istiyorsak GOTO komutundan bir satır önce GIE bitini '1' yaparız.
örneğin
Kesme_Prog 
. 
. 
. 
. 
Kesme_Prog_Sonu 
bsf INTCON, GIE
goto Istenen_Prog

XX_CİHAN_XX

Alıntı yapılan: "Prof.EleCTroN"Kesme programı bittikten sonra tekrar kesme yapmak istiyorsan GIE bitini '1' yapman gerekir. RETFIE komutu bunu otamatik yapar (aynı zamanda programda kalınmış yere geri döndürür) fakat biz bunun yerine istediğimiz adrese gitmesi için GOTO komutunu kullanıyoruz, bu komut sadece istenilen adrese atlama yapar. (Kısaca istenilen adrese gitmesi için RETFIE yerine GOTO kullanıyoruz.) Kesme özelliğinin aktif olması içinde mikroişlemcinin kesme mantığına benzer bir şekilde yapmak istiyorsak GOTO komutundan bir satır önce GIE bitini '1' yaparız.
örneğin
Kesme_Prog 
. 
. 
. 
. 
Kesme_Prog_Sonu 
bsf INTCON, GIE
goto Istenen_Prog
Bu işlem sakıncalıdır her kesme geldıgınde stack dolacak ve 8. kesmede program sapıtacak.
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.

feridunarslan

Prof.EleCTroN dediğin gibi yaptım ama devre calışmaz oldu baska bi yolu yordamı yokmudur bu işin yardımlarınızı bekliyorum arkadaşlar

Prof.EleCTroN

Neden program sapıtıyor? Stack taşınca program niye sapıtsın?

feridunarslan

arkadaşlar program calışmıyı yardım lutfen

XX_CİHAN_XX

Alıntı yapılan: "Prof.EleCTroN"Neden program sapıtıyor? Stack taşınca program niye sapıtsın?
Retfie nın yaptıgı iş
         BSF          INTCON,GIE
          RETURN

Bunu zaten belirtmişsin.Gelelim soruna.İnterrupt geldiginde yada alt program cagılıdıgında, Program ilgili alt yordama gitmeden once kaldıgın yerın adresını(program counter degerını ) stack a kaydeder.
Return komutu ıle geri donus yapılmadıgı surece bu adres stack registerinde kalır.Return kodu ile birlikte stack tan geri donecegı adres degerı program countere gerı yuklenır ve kesmenın geldıgı noktaya gerı donulmus olur.Bu durumda sen return demezsen her kesme geldıgınde stack a geldıgı noktanın adresı kaydedılecek ve 8 kesmede stack dolacaktır.Bu durumda kesmenın geldıgı noktaya sıcramalar olucak ve stack doldugu ıcın program cıınde cagılrılan altprogramların gerı donuslerı abuk yerelere olacaktır.Bu işlem yanlıştır.
Gelelim arkadaşın sorusuna......
Kesmeden donerken return yada retfie diyerek donebılırısn.Kısacası direk istediğin noktaya oradan dallanamazsın.Ancak soyle bır yontem onerebılırım, kesmeden cıkmadan gıtmek ıstedıgın yere gıdıp oradaki işin bitince kesmeden retfie diyerek cıkabılırısn.
Yada bu bi dongu ise ve kesmede bu sekılde uzun kalmak istemiyorsan.Bir falg regısterıne kesmeden cıkaraken set edersın.Kesmeden cıktıgında programın herzaman ugrayacagı noktalara , ana donguye felan bu flag bıtı set oldu mu dıye sorarsın. set oldu ıse ıstedıgın noktaya dallanıp o bıtı temızleyıp yapman gereken ıslerı yaparsın....
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.

feridunarslan

cihan kardesim dedigin gibi yaptım yani kesme icerisnde bir registirin falanca birini set edip dongu icerinde test ettirip cozume ulastım yalnız bi miktar calıstıktan sonra pic kilitleniyor bende o yuzden kesme geldigi anda dongulere hıc bulasmadan istedigim yere dllanmasını istedim bu konuyuda bı turlu basaramadım yardım cı olabilirseniz sevinirim teşekkürler

XX_CİHAN_XX

Alıntı yapılan: "feridunarslan"cihan kardesim dedigin gibi yaptım yani kesme icerisnde bir registirin falanca birini set edip dongu icerinde test ettirip cozume ulastım yalnız bi miktar calıstıktan sonra pic kilitleniyor bende o yuzden kesme geldigi anda dongulere hıc bulasmadan istedigim yere dllanmasını istedim bu konuyuda bı turlu basaramadım yardım cı olabilirseniz sevinirim teşekkürler
Kesmeden retfie ile cıkmadan once kullandıgınız kesme flagını clear etmenız gerkır.Ornegın rb0 kesmesı kullanıyorsanız kesmeden cıkmadan once BCF      INTCON,INTF demenız gerekır.Ve kesmeye girildigini belirten bir regsiterin bir bitini set edın.Kesmeden cıktıktan sonrada ana dongu içersinde bu biti sorarak gitmen gereken yerlere dallan ve yapmak istediklerini yap fakat bu biti clear etmeyı unutma.Bundan başka bir cozum su an ıcın yok gibi.Eger yapcagın iş cok uzun degılse kesmeden cıkmadan once o işi hallet ve kesmden cık diyebilirim.
Tam olarak yapmak istedigin işi anlatırsan belki daha iyi bir cozum yolu bulabılırız ama su an ıcın tek cozumun bu gıbı gelıyor.Yazılımını kontrol et baska hatalar yapıyor olabılırsın....
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.

Prof.EleCTroN

Alıntı yapılan: "XX_CİHAN_XX"
Alıntı yapılan: "Prof.EleCTroN"Neden program sapıtıyor? Stack taşınca program niye sapıtsın?
Retfie nın yaptıgı iş
         BSF          INTCON,GIE
          RETURN

Bunu zaten belirtmişsin.Gelelim soruna.İnterrupt geldiginde yada alt program cagılıdıgında, Program ilgili alt yordama gitmeden once kaldıgın yerın adresını(program counter degerını ) stack a kaydeder.
Return komutu ıle geri donus yapılmadıgı surece bu adres stack registerinde kalır.Return kodu ile birlikte stack tan geri donecegı adres degerı program countere gerı yuklenır ve kesmenın geldıgı noktaya gerı donulmus olur.Bu durumda sen return demezsen her kesme geldıgınde stack a geldıgı noktanın adresı kaydedılecek ve 8 kesmede stack dolacaktır.Bu durumda kesmenın geldıgı noktaya sıcramalar olucak ve stack doldugu ıcın program cıınde cagılrılan altprogramların gerı donuslerı abuk yerelere olacaktır.Bu işlem yanlıştır.
Evet bende bunu zaten biliyorum. Fakat arkadaş zaten kesme programından geri dönmek istemiyor onun yerine istediği adrese atlamak istiyor. O yüzden geri dönüş olmayacağı için stack in taşması önemsizdir.

Edit: Aşağıdaki programı yeni yazdım.

;********************************************************************
;Program Adı:Deney3.asm												*
;Program İşlevi:													*
;MCU:PIC16F877														*
;Kristal Frekansı:4 MHz												*
;Tarih:xx/xx/200x													*
;********************************************************************
;********************************************************************
				list			P=16F877			;MPASM 'a PIC i tanıt.
				include			<P16F877.INC>		;PIC16F877 saklayıcı tanımlamar dosyası kullanılsın.

;********************************************************************
;1 saniye gecikme için etiket tanımlamarı.							*
;********************************************************************
SayacA			equ				0x70				;
SayacB			equ				0x71				;
SayacC			equ				0x72				;			

;********************************************************************
;Reset ve kesme programları için yönlendirme rutinleri.				*
;********************************************************************
				org				0x00				;Reset vektörü adresi.
				goto			Ana_Program			;Ana_Proram a git.
	
				org				0x04				;Kesme vektörü adresi.
				goto			Kesme				;Ana_Program a git. (kesme rutini kullanılmıyor.)
Kesme
				bcf				INTCON, INTF		;
				movlw			0xFF				;
				movwf			PORTD				;
				call			Bekle_1_Sn			;
				clrf			PORTD				;
				call			Bekle_1_Sn			;
				bsf				INTCON, GIE			;
				goto			LED7				;

Ana_Program
				call			Kur					;Portların kurulması için alt programa dallan.
				clrf			PORTD				;PORTB temizlenir.
LED0
				bsf				PORTD,0				;
				call			Bekle_1_Sn			;
				bcf				PORTD,0				;
				call			Bekle_1_Sn			;
				goto			LED0				;
;********************************************************************
LED7			
				bsf				PORTD,7				;
				call			Bekle_1_Sn			;
				bcf				PORTD,7				;
				call			Bekle_1_Sn			;
				goto			LED7				;
;********************************************************************
Kur
				bsf				STATUS,RP0			;
				clrf			TRISD				;
				movlw			0xFF				;
				movwf			TRISB				;
				bcf				STATUS,RP0			;
				bsf				INTCON,INTE			;
				bsf				INTCON,GIE			;
				return
;********************************************************************
;1 saniyelik gecikme alt programı									*
;********************************************************************
Bekle_1_Sn
				movlw			D'6'				;
				movwf			SayacC				;
				movlw			D'24'				;
				movwf			SayacB				;
				movlw			D'167'				;
				movwf			SayacA				;
Dongu			
				decfsz			SayacA,1			;
				goto			Dongu				;
				decfsz			SayacB,1			;
				goto			Dongu				;
				decfsz			SayacC,1			;
				goto			Dongu				;
				nop									;
				return
				END

Bu program simule edilmiştir. Kesme programı 10 dan fazla çağırılmış ve programda hiçbir sapıtma olmamıştır.

XX_CİHAN_XX

Hatırlatma:
Alıntı yapılan: "feridunarslan"merhaba arkadaşlar
rb0 kemesi oluşup tamamlandığında programın kaldığı yerden değilde benim istedigim yerden yada program kodlarının basından başlamasını istiyorum bunu asm ile nasıl yaparım yardım ederseniz sevinirim

Alıntı yapılan: "Prof.EleCTroN"Fakat arkadaş zaten kesme programından geri dönmek istemiyor onun yerine istediği adrese atlamak istiyor. O yüzden geri dönüş olmayacağı için stack in taşması önemsizdir.
stack tasması onemlıdır.
Alıntı yapılan: "Prof.EleCTroN"
Kesme programı bittikten sonra tekrar kesme yapmak istiyorsan GIE bitini '1' yapman gerekir.

retfie demeden istediğin noktaya dallanırsın.
kesmeyı acarsın.
hic retfie demedıgın ıcın her kesmede stack dolar.
stack tasması onemlıdır cunku bu arkadas dallandıgı yerde alt program calıstıramaz!!!
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.

Prof.EleCTroN

Alıntı Yapstack tasması onemlıdır.
Bu programa göre değişir.

Alıntı Yapretfie demeden istediğin noktaya dallanırsın.
kesmeyı acarsın.
hic retfie demedıgın ıcın her kesmede stack dolar.
stack tasması onemlıdır cunku bu arkadas dallandıgı yerde alt program calıstıramaz!!!
Yukarıda verdiğim programda dallandığım yerde alt program çalıştırıyorum.

XX_CİHAN_XX

Arkadaşım yukarıda hazırladığın kod için teşekkür ederim.
Anlatmak istediğim şeyin ispatı oldu.
Verdiğin programdaki 1 sanıyelık altprogramın dongu degerlerını 1-1-1
olarak degıstır ve mplabta simulasyonu yap ben az once yaptım
stack taşması olduktan sonra zaman alt progmına giriyor return dedıgınde kur isimli alt programa sıcrıyor oradan return dedgınde zaman alt progrmının dongulerınde cakılıp kalıyor vs...
Yanı yukarıda demek istediğimi anlatan cok guzel bır kod hazırlamıssın.Mplabta stack tastıktan sonra sımulasyon yapmaya bıraz devam etseydın haklı oldugumu gorurdun.
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.