16F628 ile Donanımsal Kesme Sorunu

Başlatan dyonizos, 17 Mart 2012, 02:19:17

dyonizos

selamlar arkadaşlar. aşağıdaki kodlarda nasıl bir sorun var acaba?
yapmak istediğim her pals geldiğinde PORTB.0 a sayi değişkenini bir artırmak yani encoderdan gelen palsleri saymak. Ancak bu arada BASLA etiketi içindeki ana programda bulunan işlemlerinde devam etmesi. Programda bir led 1 sn arayla yanıp sönüyor bu arada gelen palsleride lcd ekrana yazıyor. ( en azından oyle olmasını arzu ediyorum)
palsleri saydırabiliyorum ancak led başta bir kere yanıyor sonra bir daha sönmüyor yani ana program sanki devem etmiyor gibi.
Yardımcı olabilirmisiniz.




Device 16F628
Declare WATCHDOG OFF
Declare XTAL 20
Declare LCD_DTPIN PORTB.4
Declare LCD_RSPIN PORTB.2
Declare LCD_ENPIN PORTB.3
Declare LCD_INTERFACE 4
Declare LCD_LINES 2

ALL_DIGITAL = True
On_interrupt rotary
Symbol INTF = INTCON.1 ' RB0 External Interrupt Flag
Symbol INTE = INTCON.4 ' RB0 External Interrupt Enable
Symbol GIE = INTCON.7 ' Global Interrupt Enable

Dim sayi As Word

Symbol pin PORTB.0
Symbol led PORTA.1

TRISA=%11111100
TRISB=%00000001
PORTA=0
PORTB=0
TMR0=0
CMCON=$07
OPTION_REG=%01111000

GoTo basla

rotary:
If PORTB.0 = 1 Then

Inc sayi
Print At 1,1,"KESME :", Dec sayi,"    "
EndIf
INTF=0
Context Restore

           
basla:
While 1 = 1
High led
DelayMS 1000
Low led
GIE=0
INTE=1
GIE=1
Wend
End



mcan

Basic ile çok program yazmadım ancak programının sadece şu kısmını ele alsak,
basla:
While 1 = 1
High led
DelayMS 1000
Low led
GIE=0
INTE=1
GIE=1
Wend
End

Şimdi led yandı 1sn bekledi söndü 5 cycle bekledi (GIE=0 ,INTE=1 ,GIE=1,Wend) . Bu arada parantez içindeki ilk üç komutu tek cycle dönüşü  2 cycle olduğunu var saydım. Sonra led tekrar yandı. Yani led üzerinde ton süresi 1saniye civarı toff ise 5 cycle olan bir pwm uyguladığını düşün .Söndüğünü göremeyebilirisn. :) denemek için

While 1 = 1
High led
DelayMS 500
Low led
DelayMS 500
GIE=0
INTE=1
GIE=1
Wend
End
olarak değiştirip deneyebilirmisin.

ete

Programı biraz "C" mantığına göre yazmış gibisiniz.
Proton da çok iyi değilim ama kesme mantığı pek değişmez.
Birincisi PORTB.0 kesmesi iki şekilde kurulur. Birinicisi gelen sinyal Yükselen kenarda kesme oluşturur ki sizde öyle olmuş. Yada düşen kenarda kesme oluşturur. Option registeri 6. biti 1 ise yükselen 0 ise düşen kenarda kesme oluşur.
Şimdi yükselen kenarda bir kesme sistemini kurmuş iseniz kesme etiketinde ayrıca ;
IF PORTB.0=1 THEN şeklinde bir komut kullanmanız yersizdir. Çünki siz zaten o etikete PORTB.0 pini LOW dan HIGH seviyesine çıktığı için geldiniz.
O halde buı komutu oradan silin. Çok emin bir şekilde direk orada SAYI=SAYI+1 demeniz ve sonra onu ekrana vermeniz yeterlidir. Hatta ekrana verme işini kesinlikle kesme etiketinde yapmayın. Ekranı Basla satırından sonra halledin. Siz sayınızı bir artırıp kesmeden çıkın.
Basla satırınıdaki programı şöyle halledebilirsiniz;
basla:
Print At 1,1,"KESME :", Dec sayi,"    " 
High led
DelayMS 500
Low led
DelayMS 500
Goto basla
End

Tabiiki Rotary etiketindeki printat komutunu silmeniz gerekir.
Ben olsaydım Rotary alt programını programın sonuna yazardım. Başına Bir DISABLE eklemeniz gerekiyor sanırım.
Hepsi Bu kadar
Ete
Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

muhittin_kaplan

Hocam Disable Software Kesmede Kullanılıyor
Yanlız Ben Nezaman Donanımsal Kesme Kullanmaya Kalktıysam Kesin bir Patlak verdi

rotary: kesmesinin altında neden portb.0 ı kontrol ediyorsunuz zaten zaten interrupt a girdiğinde o pin yüzüne yani RB0 kesmesinenden dolayı giriyordur. o satır fazla.
Zaten Int kurulmamış
ALL_DIGITAL = True
On_interrupt rotary
Symbol INTF = INTCON.1 ' RB0 External Interrupt Flag
Symbol INTE = INTCON.4 ' RB0 External Interrupt Enable
Symbol GIE = INTCON.7 ' Global Interrupt Enable


yazarak değil

ALL_DIGITAL = True

Symbol INTF = INTCON.1 ' RB0 External Interrupt Flag
Symbol INTE = INTCON.4 ' RB0 External Interrupt Enable
Symbol GIE = INTCON.7 ' Global Interrupt Enable 

gie=0
inte=1
gie=1


On_interrupt rotary
yazarak interrupt aktif edilir

Kısaca Kodlarını  aşağıya vereyim


Device 16F628
Declare WATCHDOG OFF
Declare XTAL 20
Declare LCD_DTPIN PORTB.4
Declare LCD_RSPIN PORTB.2
Declare LCD_ENPIN PORTB.3
Declare LCD_INTERFACE 4
Declare LCD_LINES 2 

ALL_DIGITAL = True

Symbol INTF = INTCON.1 ' RB0 External Interrupt Flag
Symbol INTE = INTCON.4 ' RB0 External Interrupt Enable
Symbol GIE = INTCON.7 ' Global Interrupt Enable 

TRISA=%11111100
TRISB=%00000001
PORTA=0
PORTB=0
TMR0=0 
CMCON=$07 
OPTION_REG=%01111000


Dim sayi As Word

Symbol pin PORTB.0
Symbol led PORTA.1

GIE=0
INTE=1
GIE=1

On_interrupt rotary

GoTo basla 

context save
rotary:
gie=0
inte=0
Inc sayi
Print At 1,1,"KESME :", Dec sayi,"    " 
delayms 5
inte=1
gie=1
INTF=0
Context Restore 

            
basla:
While 1 = 1
High led 
DelayMS 1000
Low led
Wend
End


ama hala garanti edemiyorum bu hw kesmeyi. çünki kesme içerisinde print komutu var.

dyonizos

Alıntı yapılan: muhittin_kaplan - 17 Mart 2012, 19:17:55
Hocam Disable Software Kesmede Kullanılıyor
Yanlız Ben Nezaman Donanımsal Kesme Kullanmaya Kalktıysam Kesin bir Patlak verdi

rotary: kesmesinin altında neden portb.0 ı kontrol ediyorsunuz zaten zaten interrupt a girdiğinde o pin yüzüne yani RB0 kesmesinenden dolayı giriyordur. o satır fazla.
Zaten Int kurulmamış
ALL_DIGITAL = True
On_interrupt rotary
Symbol INTF = INTCON.1 ' RB0 External Interrupt Flag
Symbol INTE = INTCON.4 ' RB0 External Interrupt Enable
Symbol GIE = INTCON.7 ' Global Interrupt Enable


yazarak değil

ALL_DIGITAL = True

Symbol INTF = INTCON.1 ' RB0 External Interrupt Flag
Symbol INTE = INTCON.4 ' RB0 External Interrupt Enable
Symbol GIE = INTCON.7 ' Global Interrupt Enable 

gie=0
inte=1
gie=1


On_interrupt rotary
yazarak interrupt aktif edilir

Kısaca Kodlarını  aşağıya vereyim


Device 16F628
Declare WATCHDOG OFF
Declare XTAL 20
Declare LCD_DTPIN PORTB.4
Declare LCD_RSPIN PORTB.2
Declare LCD_ENPIN PORTB.3
Declare LCD_INTERFACE 4
Declare LCD_LINES 2 

ALL_DIGITAL = True

Symbol INTF = INTCON.1 ' RB0 External Interrupt Flag
Symbol INTE = INTCON.4 ' RB0 External Interrupt Enable
Symbol GIE = INTCON.7 ' Global Interrupt Enable 

TRISA=%11111100
TRISB=%00000001
PORTA=0
PORTB=0
TMR0=0 
CMCON=$07 
OPTION_REG=%01111000


Dim sayi As Word

Symbol pin PORTB.0
Symbol led PORTA.1

GIE=0
INTE=1
GIE=1

On_interrupt rotary

GoTo basla 

context save
rotary:
gie=0
inte=0
Inc sayi
Print At 1,1,"KESME :", Dec sayi,"    " 
delayms 5
inte=1
gie=1
INTF=0
Context Restore 

            
basla:
While 1 = 1
High led 
DelayMS 1000
Low led
Wend
End


ama hala garanti edemiyorum bu hw kesmeyi. çünki kesme içerisinde print komutu var.

Hocam çok teşekkürler kodlar sizin verdiğiniz şekilde çalışıyor. Kesme içindeki print komutunuda kesme dışına çıkardım ancak gelen pulse leri çift olarak sayıyor bunun nedeni ne olabilir?

rotary:
Inc sayi
INTF=0
Context Restore

kesmeyi sadece bu şekilde bırakırsam teker teker sayıyor.


muhittin_kaplan

hallolmuş kolay gelsin. belki benimde atladığım bir yer vardır.