interrupt kullanımında problem

Başlatan CaFFeiNe, 13 Mart 2005, 19:23:56

CaFFeiNe

merhaba

interrupt kullanırken ilginç bir problemle karşılaştım ve tüm uğraşılarıma rağmen sebebini bulamadım problem şöyle interrupt kullanarak bir ledi 1sn aralıklarla yakıp söndürüyorum aynı andada lcd de bir ekran görüntüsü var fakat

LOOP:
PAUSEUS 100
GOTO LOOP

şeklinde olduğunda çalışıyor

PAUSEUS 100 komutunu sildiğimde

LOOP:
GOTO LOOP

şeklinde çalışmıyor program sürekli baştan başlıyor onuda SCREEN altprogramına PAUSE 500 gecikmeleri koyarak farkettim

neden acaba? kodlar aşağıda ve devreyi board üstüne kurarak deniyorum proteusta değil işlemci 16f877


   DEFINE OSC 8            
   DEFINE LCD_DREG PORTD  
   DEFINE LCD_DBIT 4      
   DEFINE LCD_RSREG PORTD  
   DEFINE LCD_RSBIT 2      
   DEFINE LCD_EREG PORTD  
   DEFINE LCD_EBIT 3      
   DEFINE LCD_BITS 4      
   DEFINE LCD_LINES 4      

   LED         VAR PORTC.5  
   FLAG       VAR BYTE
   IZIN        VAR FLAG.0
   X           VAR BYTE    
   T0IF        VAR INTCON.2

   TRISD = %00000011
   OPTION_REG = %00000111
   ON INTERRUPT GOTO MY_INTERRUPT
   INTCON = %10100000
   LOW IZIN
   GOSUB SCREEN
LOOP:
   PAUSEUS 100
   GOTO LOOP

MY_INTERRUPT:
   DISABLE
   IF IZIN THEN                    
     IF T0IF THEN          
       X = X + 1
       IF X = 30 THEN
        IF LED = 1 THEN
          LOW LED
        ELSE
          HIGH LED
        ENDIF
        X = 0
       ENDIF
       LOW T0IF            
     ENDIF
   ENDIF    
   RESUME
   ENABLE
   
SCREEN:
   LCDOUT $FE, 1
   PAUSE 500
   LCDOUT $FE, 2,   "TEST EKRANI         "
   HIGH IZIN
   PAUSE 500
   RETURN

Veli B.

Gözüme acele ile çarpanlar;
1- kesme rutini içinde iki tane if komutu yanlış kullanılıyor,"if izin then " gibi
eğer izin ne ise?
2- screen bölümünü kesme rutini üzerine almanı tavsiye ederim.
3- programı sonlandırmanı da!!!!! End ile
4- T0IF için low yerne =0 kullanmanı ama denediğim için değil başka birkaç yerde low vw =0 farkını yaşadığım için...
birde kullandığın lcd ne?
44780 uyumlu lcd ler için görülebilir adress 128 den başlar.
Kolay gelsin...

ete

@caffeine,

Sonuca pek etkili olmayacak hatalar görüyorum. SIrası ile;

- ADC leri kullanmadığına göre iptal etmen gerekir ADCON=7 ile
- Disable komutu interrupt labelinden önce kullanılır.
- interrupt olayı gerçekleştiğinde TOIF zaten 1 olacaktır. Neden burada ayrıca if TOIF=1 ise gibi ifadeyi kullandın. Halbuki int rutini sonunda bu flag direkt TOIF=0 şeklinde hiç bir şarta bağlı olmaksızın sıfırlanmalıdır.
- Bence INT bölümünde lüzümundan fazla if kullanmışsın. Bir kısmı elimine edilebilir. Örneğin LED değişkeni için LED=1-LED demen yeterli. LED=1 ise LED=0 olur. LED=0 ise LED=1 olur ve if komutuna bağlı olmadan halletmiş olursun.
- Birde izin değişkeni zaten high dan başka bir seçeneği yok neden bunuda bir şarta bağladın?. Zira programın başında Screen'e gidfiyor ve orada high oluyor. Sonra program loop'a giriyor ve hiç bir şekilde izin LOW olmuyor. O halde neden if izin then (yani if izin=1 ise demek) diyorsun bunu anlamadım.

Kolay Gelsin
ETE
Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

CaFFeiNe

programı önerilerin doğrultusunda adım adım değiştirerek aşağıdaki hale getirdim ve her adımda denedim sonuç aynı :((

lcd 44780 uyumlu

görülebilir alan demekle neyi kastettin anlamadım ama lcdde yazıyı görememe problemi yok


   DEFINE OSC 8            
   DEFINE LCD_DREG PORTD  
   DEFINE LCD_DBIT 4      
   DEFINE LCD_RSREG PORTD  
   DEFINE LCD_RSBIT 2      
   DEFINE LCD_EREG PORTD  
   DEFINE LCD_EBIT 3      
   DEFINE LCD_BITS 4      
   DEFINE LCD_LINES 4      

   LED         VAR PORTC.5  
   FLAG        VAR BYTE
   IZIN        VAR FLAG.0
   X           VAR BYTE    
   T0IF        VAR INTCON.2

   TRISD = %00000011
   OPTION_REG = %00000111
   ON INTERRUPT GOTO MY_INTERRUPT
   INTCON = %10100000
   IZIN = 0
   GOSUB SCREEN
LOOP:
   PAUSEUS 100
   GOTO LOOP

SCREEN:
   LCDOUT $FE, 1
   PAUSE 500
   LCDOUT $FE, 2,   "TEST EKRANI         "
   IZIN = 1
   PAUSE 500
   RETURN

MY_INTERRUPT:
   DISABLE
   IF IZIN = 1 THEN                    
     IF T0IF = 1 THEN          
       X = X + 1
       IF X = 30 THEN
        IF LED = 1 THEN
          LOW LED
        ELSE
          HIGH LED
        ENDIF
        X = 0
       ENDIF
       T0IF = 0            
     ENDIF
   ENDIF    
   RESUME
   ENABLE
   
   END

ete

@caffeine,

Mesajımı yazdım sonra tekrar düşündüm. Her ne kadar yazdıklarında bazı ufak hatalar olsada sonucu etkilemiyecek hatalar. O halde sorun nedir diye düşündüm ve buldum. Sorunun arada hiç bir komut olmaz ise Watch Dog Timer programı resetliyor. Bu nedenle program içinde

@ DEVICE pic16F877, WDT_off

komutunu kullanmalısın.

Kullan program düzelecektir.

Bu arada yukarıda vermiş olduğum örnek de LED=1-LED komutu port çıkışında çalışmayabilir. Onun yerine bana kalır ise TOGGLE LED komutunu kullan.

Kolay Gelsin
ETE
Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

CaFFeiNe

1. adcyi iptal etmeme gerek varmı kullandığım portlar PORTC ve PORTD

2. disable komutunu önede alıp denedim sonuç aynı

3. t0if i kullandım çünkü sadece timer kesmesinde ledin yanıp sönmesini istiyorum ve ileride
kesmeleride kullanabilirim rb0 gibi ozaman hangi kesmede ne iş yapılacaksa onları ayırmam gerek
if t0if = 1 olayını kaldırdım sonuç aynı

4. if leri elimine etmek için verdiğin örnek güzel bilmediğim birşey öğrenmiş oldum teşekkürler
(picbasic e yeni başladım sayılır)

5. izin değişkenini kullandım çünkü aslında değişik animasyonlu bir ekran görüntüsü oluşturuyordum
ve interrupt aslında ekrana yazan kodlar içeriyordu animasyon bitmeden interrupt içindeki koda
izin vermemem gerekiyordu yoksa animasyonu bozuyordu ben problemimi göstermek için kodu traşladım
ve basite indirgedim tabiiki (izin değişkeninide unutmuşum onuda kaldırdım sonuç aynı)


watchdog açıkmış doğru söylüyorsun tüh problem çözüldü
epic programerida yeni kullanmaya başladım icprogda direk ekranda watchdog durumunu görebiliyorduk epicte tongaya düştüm iyimi :))

çok teşekkürler

CaFFeiNe

ete arkadaşım birşey daha sormak istiyorum önceden asm kullanıyordum ve kesin zaman hassasiyeti olan programlar yazabiliyordum özellikle kesmeleri kullanırken tmr0 gibi ama bir karakter lcdye yazdırmak bile büyük iş oluyor asmde şimdi kesmelerle ilgili kritik programlar yazacaksak proton+ gerek diyorlar (hardware int varmış galiba) da nasıl bulacağız biliyormusun sende varmı?

ete

Proton Plus'ı çok yeni kullanmaya başladım. Int konusunda henüz girmedim. Ancak forumlardan okuduğum kadarı ile Proton Int konusunda daha iyi ve uygun deniyor. Bir program imkanı olur ise deneyeceğim.
Yüzde yüz emin olmak için denemekten başka çare yok.

PBPro da INT sorunu ana bölümde bir komut icra edilirken komut icrası bitmeden int bölümüne atlama olmuyordu. Anck bu olayı her programda hissetmek mümkün değil. Komut icrası uzun olan komutlar seçip kısa int bölümleri gerçekleştirerek bunu anlamak mümkün. Bunuda nasıl yaparız şimdilik aklıma bir şey gelmiyor. Bir ara rotary encoder okuyan buna bağlı bir takım işler yapan uzunca bir program yapmış idim. Aynı program başlangıç aşamsında bayağı kısa idi. Bir takım denemeler yapmıştım. Encoder'in hangi hızını sistem yakalayıp okuyabiliyor diye. Ozaman gördümki her iki program arasında çalışma hızı bakımından farklılıklar var.
Bu sistemi denemek için encoder'i bir step motora bağlamış ve istediğim sabit bir hızda döndürebiliyor idim. Sonuçta programın int kısmının her iki programda farklı çalıştığını anladım. O zaman PBP nun int konusunda sorun çıkardığından haberimde yoktu olayı sonradan anladım.

ETE
Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

CaFFeiNe

hımm peki

sende proton için crack yada keygen varmı acaba forumlarda birsürü yerde bahsediyor 2.1.3 için keygen filan ama birtürlü bulamadım