GIE nin resetlenmesi

Başlatan serdararikan, 25 Nisan 2015, 17:41:13

serdararikan

ADC_Read:
	movf	val1,W
	movwf	ADCON0
	movlw	16
	movwf	count	
	clrf	val1
	clrf	val1+1
ad_go:
	bsf	ADCON0,2
	btfsc	ADCON0,2
	goto	$-1
	movf	ADRESH,W
	movwf	val2+1
	bsf	STATUS,RP0
	movf	ADRESL,W
	bcf	STATUS,RP0
	movwf	val2
	call	add_u16
	movlw	255
	movwf	val2
	decfsz	val2
	goto	$-1
	decfsz	count
	goto 	ad_go
	movlw	4
	movwf	val2
	call	shft_r_16
	return


programımda Timer0 kesmesi var ayrıca programda alt program olarak yukarıdaki adc okuma rutinini kullanıyorum.fakat program kesmeye girdiği anda nedense intcon.7 yani GIE 0 oluyor. sorunu bir türlü çözemedim.gözden kaçırdığım bir yer olmalı.assembly konusunda uzman arkadaşların yardımını bekliyorum.
not:  gie nin adc okuma rutini çalışıyorken kesme gelmesi durumunda 0 olduğunu tesbit ettim bu nasıl olabilir????

JOKERAS

Selam,

Kullandığınız işlemci tek kesme özelliğine sahipse o sebeple GİE otomatik olarak kapanıyordur.
Şöyleki;
Low priority interrupt, high priority interrupt gibi.

Diyelimkl siz adc ve timer interrupt'ı kullanıyorsunuz,adc interrupt geldi,
peşindende  timer interrupt geldi,işlmeciniz tek kesme özelliğine sahip olduğu için 2.gelen interrupt'ın
bir önemi kalmamış oluyor.
Bu sebepleri göz önüne alarak GİE'yi otomatik olarak kapatmışlardır diye düşünüyorum.

Bir kesme içindeyken başka kesmenin gelmesini engellemektir amaç,zaten tek kesme özeliğindeki bir işlemcide bunun açık yada kapalı olmasının anlamıda yok!
Bu durumda şöyle yapılabilinir,2. kesme flag'nin durumu temp edilip "ha evet 2. kesme isteğide gelmiş"denir ve ona göre kod yorumlanır.
Diye düşünüyorum.

ferdem

GIE, interrupt enable biti. Bir kesmeye girildiğince başka bir kesme ile bölünme olmasın diye GIE nin 0 da tutulması, yeni kesme alınmaması mantıklı değil mi?
Hangi model PIC kullanıyorsunuz, üst serilerde interrupt priority ayarı yapılabiliyordu, o modellerde öncelikli kesme geldiğinde kesme içinde başka kesmeye dallanıyor olsa gerek ancak düşük modellerde bir kesme geldiğinde GIE 0 yapılır. Kesme esnada başka kesme gelirse ilgili biti 1 yapar ama bekler, aktif kesme bittiğinde GIE 1 e çekilir, çekilir çekilmez sıradaki kesme rutini işletilir.

ADC konusunu anlayamadım(?)

JOKERAS  yazmış, değiştirmeden gönderiyorum.

serdararikan

Kullandigim iskemci 16f877. GIE nin kesmeye girerken 0 olduğunu ilk defa duydum.datasheette nerede yazıyor? Eger oyle bir durum varsa ayni anda birden fazla kesme kullanılması olası olmaz.

Tagli

Datasheet'in C revizyonunda 153. sayfada (DS39582C-page 153):
Alıntı YapWhen an interrupt is responded to, the GIE bit is cleared to disable any further interrupt, the return address is pushed onto the stack and the PC is loaded with 0004h. Once in the Interrupt Service Routine, the source(s) of the interrupt can be determined by polling the interrupt flag bits. The interrupt flag bit(s) must be cleared in software before re-enabling interrupts to avoid recursive interrupts.

GIE'nin kapalı olması, kesme şartları sağlandığı zaman kesme bayraklarının kalkmasına engel değildir. Kesme dönüşünde RETFIE komutu ile GIE tekrar 1 olur ve kalkmış durumda olan başka kesme bayrağı varsa hemen tekrar kesmeye girilir.
Gökçe Tağlıoğlu

JOKERAS

Alıntı yapılan: serdararikan - 26 Nisan 2015, 14:21:40
Kullandigim iskemci 16f877. GIE nin kesmeye girerken 0 olduğunu ilk defa duydum.datasheette nerede yazıyor? Eger oyle bir durum varsa ayni anda birden fazla kesme kullanılması olası olmaz.

16f877'de kesme bir tanemi?Birtane kesme varsa  ikinci kesme nereye gidecek?

Diyelimki Kesme vectör adresi pgm memory 0x0004,bir kesme oluştuğunda  PC bu adrese zıplar,
bu adres kesme rutinin başlangıç noktası.
Belli bir genişliği vardır onun içindirki kesme rutininde fazla komut yazılmaz,fonksiyona dalllandırılır veya flag'ler güncellenip çıkılır.

Şimdi aynı anda iki farklı kesme kullandığınızı düşünürsek ve iki kesme isteğide bir komut süresi(instruction)kadar bir ara ile geldiğini varsayarsak PC hangi kesmeyi kullanacak?
Her iki durumda gideceği adres bölgesi 0x0004.
Bu durumda if else merdiveni yapmak gerekiyor ama kesmelerden birini kaçırmış oluyorsunuz.
Tabii bu kritik durumlarda önem arz eder çok kritik bir durum yoksa,önemli değil.

Eğer çok kritik bir durum varsa çoklu kesme özelliğine sahip bir işlemci kullanacaksınız.
Kesme vectör 0x0004 high priority, kesme vectör 0x0008 low priority gibi.


serdararikan

aslında buradaki ilginçlik timer ile adc nin aynı anda kullanılmasında ortaya çıkıyor.verdiğim adc rutini tek başına gayet güzel çalışırken timer ile birlikte kullanıldığında adc rutini içerisinde GIE 0 oluyor ve bir daha timer kesmesi oluşmuyor.
kendine güvenen birisi varsa ben bu olayı çözerim diyen kodları koyabilirim buraya

JOKERAS

Alıntı yapılan: serdararikan - 26 Nisan 2015, 18:12:16
aslında buradaki ilginçlik timer ile adc nin aynı anda kullanılmasında ortaya çıkıyor.verdiğim adc rutini tek başına gayet güzel çalışırken timer ile birlikte kullanıldığında adc rutini içerisinde GIE 0 oluyor ve bir daha timer kesmesi oluşmuyor.
kendine güvenen birisi varsa ben bu olayı çözerim diyen kodları koyabilirim buraya

interrupt'tan çıkarken GIE tekrar set olurki!
Adc için neden kesme kullanıyorsunuzki?
Ne yapmak istiyorsunuz biraz anlatabilirmisiniz?

serdararikan

http://s4.dosya.tc/server2/duf2y3/Yeni_Klasor.rar.html

asm mplab ve isis dosyaları ekte. eğitim amaçlı pic i ladder ile programlayabilecek bir yazılım yapıyorum.GUI kısmında sorun yok.o kısım gayet güze çalışıyor.arka planda çalışacak asm kodlarını birbirleriyle uyumlu olarak çalışacak şekilde organize etmem lazım

Tagli

Net göremiyor olabilirim ama ADC kodu içinde kesme gelirse ne olacak? Kesme kodun PCLATH'ı uygun şekilde yedeklemiyor gibi. Kesme girişinde ilk iş PCLATH'ın yedeğini almalı (aynı STATUS için yaptığın gibi) sonra PCLATH'ı bulunduğun yere göre ayarlamalı (yani sıfırlamalı) ve çıkarken de eski haline geri getirmelisin.

Bunu yapmadığın durumda, ADC koduna göre ayarlı PCLATH ile kesme kodunda işlettiğin GOTO KesmeDon kısımları sorun çıkarır. Sen PCLATH yedeklemesi yapıyorsun ama kesme kodu page0'da, kendi içindeki GOTO'larda sorun çıkar.

Ayrıca PCLATH'ı elle ayarlamak yerine pagesel ve pageselw komutlarını kullan. Hata yapma ihtimalini azaltır.
Gökçe Tağlıoğlu

serdararikan

Alıntı yapılan: Tagli - 26 Nisan 2015, 18:46:25
Net göremiyor olabilirim ama ADC kodu içinde kesme gelirse ne olacak? Kesme kodun PCLATH'ı uygun şekilde yedeklemiyor gibi. Kesme girişinde ilk iş PCLATH'ın yedeğini almalı (aynı STATUS için yaptığın gibi) sonra PCLATH'ı bulunduğun yere göre ayarlamalı (yani sıfırlamalı) ve çıkarken de eski haline geri getirmelisin.

Bunu yapmadığın durumda, ADC koduna göre ayarlı PCLATH ile kesme kodunda işlettiğin GOTO KesmeDon kısımları sorun çıkarır. Sen PCLATH yedeklemesi yapıyorsun ama kesme kodu page0'da, kendi içindeki GOTO'larda sorun çıkar.

Ayrıca PCLATH'ı elle ayarlamak yerine pagesel ve pageselw komutlarını kullan. Hata yapma ihtimalini azaltır.

evt onu şuan bende fark ettim. düzenleyip tekrar deneyecem .teşk.ler