Haberler:

Forum kuralları güncellendi LÜTFEN  okuyunuz:  https://bit.ly/2IjR3ME

Ana Menü

tmr0 kesmesi yardım

Başlatan vatandas30, 17 Ocak 2009, 14:19:16

vatandas30

arkadaşlar.
yapmak istediğim jeton kutusuna bir jeton atıldığında 20 dk. dan geriye saydırmak ve bunu lcd de göstermek. devreyi yaptım. aşağıdaki kodu yükledim. herşey normal. ilk başta jeton atınız yazıyor. jeton kutusuna jeton atınca 20 dk. dan geriye saymaya başlıyor ve 20 dk bitince röleyi açıyor, tekrar jeton atınız yazıyor.eğer 20 dk. dolmadan tekrar jeton atılırsa kalan sürenin üzerine 20 dk daha ekliyor.
sorunum da şu:
bazen 20 dk. bitince kendi kendine 99 dk. dan geriye saymaya devam ediyor. bazende jeton kutusundan gelen sinyali algılamıyor. burada tmr0 kesmesini kullandım. hatamı bulamadım. fikri olan var mı?
not:  aynı işi timer1 kullanarak yapabilir miyim. jeton atıldığı zaman çalışması daha mantıklı.
define osc 4
PORTA=0:portb=0
TRISB=%00000000   'PortB tamamı çıkış yapıldı.
TRISA=%00000001   'porta.o giriş yapıldı.
'-----------------------------------------------------------------
@ DEVICE pic16F628a                      'işlemci 16F628                                
@ DEVICE pic16F628a, WDT_OFF             'Watch Dog timer kapalı
@ DEVICE pic16F628a, PWRT_ON             'Power on timer açık
@ DEVICE pic16F628a, PROTECT_OFF         'Kod Koruma kapalı
@ DEVICE pic16F628a, MCLR_on             'MCLR pini kullanılıyor.
@ DEVICE pic16F628a, INTRC_OSC_NOCLKOUT  'Dahili osilatör kullanılacak 
'-----------------------------------------------------------------
DEFINE LCD_DREG	PORTB	'LCD data bacakları hangi porta bağlı?
DEFINE LCD_DBIT		4		'LCD data bacakları hangi bitten başlıyor?
DEFINE LCD_EREG	PORTB	'LCD Enable Bacağı Hangi Porta bağlı?
DEFINE LCD_EBIT		3		'LCD Enable Bacağı Hangi bite bağlı ?
define LCD RWREG         PORTB   	'LCD R/W Bacağı Hangi Porta bağlı?
define LCD_RWBIT    	2       		'LCD R/W Bacağı Hangi bite bağlı ?
DEFINE LCD_RSREG	PORTB	'LCD RS Bacağı Hangi Porta bağlı ?
DEFINE LCD_RSBIT	1		'LCD RS bacağı Hangi Bite bağlı  ?
DEFINE LCD_BITS		4		'LCD 4 bit mi yoksa 8 bit olarak bağlı?
DEFINE LCD_LINES	2		'LCD Kaç sıra yazabiliyor
'-------------------------------------------------------------------------
ON INTERRUPT GoTo KESME   'kesme oluşursa KESME adlı etikete git.
INTCON=%10100000
OPTION_REG=%10000101   	 'Pull up dirençleri İPTAL- Bölme oranı 1/64.
TMR0=0
CMCON=7    			'16F628 de komparatör pinleri iptal hepsi giriş çıkış
'----------------------------------------------------------------------------
symbol buton=porta.0
symbol ROLE=porta.1
SAYAC   VAR   BYTE
SN      VAR   BYTE
DAK     VAR   BYTE
'-----------------------------------------------------------------------------
CLEAR  'tüm değişkenler sıfırlandı
PAUSE 200
LCDOUT $FE,1
LOW PORTB.2  'LCD -R/W bacağı LOW'a çekildi. 

'-----------------------------------------------------------------------------

basla:
lcdout $FE,$82,"JETON ATINIZ"
if buton=0 then 
sayac=0
sn=0
dak=0
ROLE=1
LCDOUT $FE,1
GOTO ZAMAN
ENDIF
GOTO BASLA  

zaman:
IF BUTON=0 THEN
WHILE BUTON=0
WEND
DAK=DAK+20
ENDIF
lcdout $FE,$83,"KALAN SURE"
LCDOUT $FE,$C5,DEC2 DAK,":",DEC2 SN
GOTO zaman

DISABLE
KESME:
      SAYAC=SAYAC+1  	    
      IF SAYAC=61 then  	    
         SAYAC=0                   	    
             IF SN=0 THEN 
              SN=60
              DAK=DAK-1                
  	         ENDIF 
         SN=SN-1         
      ENDIF
         IF DAK=0 AND SN=0 and sayac=60 THEN
               ROLE=0
               INTCON.2=0
               LCDOUT $FE,1
               GOTO BASLA
         ENDIF   
         INTCON.2=0        'TMR0 Kesme bayrağı sıfırlanıyor
         RESUME
         ENABLE
         
END

ibo1973

1- jetonu algılaması konusunda şunu diyebilirim  tam kesmeye gittiği anda jeton atılırsa jetonu algılamaması olası jeton kısmını bence rb0 kesmesine koyman milletin jetonlarını yutmaması için oldukça kritik gibi duruyor yani jetonu rb0 kesmesi ile kulanmanı tavsiye ederim muhtemelen jeton sorunu bu şekilde aşılır


evet birde bundan bir tane kulanmanı tavsiye ederim IF BUTON=0 THEN  aynı isimli if döngüsünden bir tane kulanmanı tavsiye ederim

2- birde burdada değişkenleri sıfırlamanı tavsiye ederim

zaman: 
IF BUTON=0 THEN 
WHILE BUTON=0 
WEND 
DAK=DAK+20 
ENDIF 
lcdout $FE,$83,"KALAN SURE" 
LCDOUT $FE,$C5,DEC2 DAK,":",DEC2 SN 
GOTO zaman


sonuçta jeton atılsada atılmasada değişkenlerin durumu belli değil zira jeton atılmasada kesmeye gidiliyor ve değişkenlerin değeri değişiyor

vatandas30

cevabın için tşk .
Alıntı Yap
evet birde bundan bir tane kulanmanı tavsiye ederim IF BUTON=0 THEN aynı isimli if döngüsünden bir tane kulanmanı tavsiye ederim
bu cümleden neyi kastettiğini anlayamadım.
Alıntı Yap
birde burdada değişkenleri sıfırlamanı tavsiye ederim

Kod:

zaman:
IF BUTON=0 THEN
WHILE BUTON=0
WEND
DAK=DAK+20
ENDIF
lcdout $FE,$83,"KALAN SURE"
LCDOUT $FE,$C5,DEC2 DAK,":",DEC2 SN
GOTO zaman



sonuçta jeton atılsada atılmasada değişkenlerin durumu belli değil zira jeton atılmasada kesmeye gidiliyor ve değişkenlerin değeri değişiyor

tmr0 sürekli çalıştığı için jeton atılmadığı zaman zaten değişkenler sürekli değişiyor. ben bunu ilk jeton atıldığı zaman değişkenleri sıfırlayarak hallettim. ancak jeton atıldıktan sonra süre bitmeden değişkenleri sıfırlayamam. çünkü tekrar jeton atılırsa kalan sürenin üzerine 20 dk. eklemesi gerekiyor.
dediğin gibi jetonu bazen algılayamaması kesmeye gittiği anda atılırsa olabilir. ama donanım olarak şu an değiştiremiyorum. benim kafama takılan bazen süre bittiğinde 99 dk. dan geriye saymaya devam etmesi. bunu her zaman yapmıyor. sebebini bulamadım.
aslında tmr1 kesmesi istenildiği zaman açılıp, istenildiği zaman kapatılabiliyormuş. fakat nasıl kullanıldığı hakkında fazla bilgi bulamadım. belki tmr1 ile yapsam ilk jeton atıldığında daha hassas olabilir. en azından jeton atılmadan kesme oluşmaz .

ete

Programın kesme kısmında önemli bir hata var ve bu hata Dak=0, SN=0 ve SAYAC=60 olduğu zaman oluşuyor. Sanırım tamda senin belirttiğin gibi sıfırlama olduğu anda.
IF DAK=0 AND SN=0 and sayac=60 THEN
               ROLE=0
               INTCON.2=0
               LCDOUT $FE,1
               GOTO BASLA
         ENDIF    

Kesme kısmına girildiği zaman kesmeden kesme bayrağı mutlaka sıfırlanarak ve RESUME komutu ile çıkılması gerekir. Sen yukarıdaki satırların sonunda GOTO BASLA diye bir komut eklemişin. Burası yanlış
Oraya Goto CIK demen gerek ve CIK etiketinide ,
CIK:
       INTCON.2=0        'TMR0 Kesme bayrağı sıfırlanıyor
       RESUME
       ENABLE

şeklinde yerleştirmen gerek.
Kısaca kesme ile gelinen yerden GOTO ile geri dönemezsin.

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

vatandas30

üstadım. dak,sn sıfır olduğunda kesmeden çıkıp programı basla etiketine döndürmem gerekiyor. bunu başka türlü nasıl yapabilirim.
GOTO BASLA
yerine
RESUME BASLA

yazsam olur mu acaba?
(simülasyonda oluyor)

Tagli

Kesmenin nerede geleceği belli olmadığı için döneceği yer de belli olmaz. BASLA'ya gidebilmek için GOTO gerekecek, derleyici dönüşün nereye olacağını önceden bilemeyeceği için GOTO'yu yerleştiremez, çünkü senin istediğinin olabilmesi için döndükten hemen sonra bir GOTO'nun çalışması gerekiyor.

Bu durumda iki seçeneğin var:
1) Programın tasarımını değiştirmek. Ki sanırım yapılması gereken bu.
2) 18 serisi bir PIC kullanıp kesmeden çıkmak için ASM komutu olan POP'u çağırıp sonra GOTO kullanmak. Ama bence bu son çare olmalı.
Gökçe Tağlıoğlu

vatandas30

peki kesmeyi jeton atıldığında aktif hale getirip, süre bittiğinde kapatma şansım var mı?

Tagli

İlgili bayrağı kapatarak kesmeyi kapatabilirsin. Ama benim aklıma şöyle bir çözüm geldi: Süre bittiğinde kesmeden çıkıp başa dönmek istiyorsan bir değişken tanımla (bit olması yeterli). Zaman döngüsünün başında bu değişkeni kontrol etsin, 1 ise döngüye devam etsin, 0 ise Basla'ya gitsin. Sen süre sıfırlandığında kesmede bu değişkeni 0 yap. Program zaman döngüsünün içine dönüp de başına geldiğinde devam etme izni olmadığını anlayıp Basla'ya gider. Tabi jeton ilk atıldığında Zaman döngüsüne gitmeden önce bu izin değişkenini 1 yapmayı unutma.
Gökçe Tağlıoğlu

vatandas30

bence de mantıklı. aklıma böyle bişey gelmemişti. tşk .
ama az önce RESUME BASLA yazmıştım. bir kitapta kesmeden çıkınca nereden devam etmesini istiyorsanız RESUME nin önüne o etiketi yazın diyordu. devre şu anda sorunsuz çalışıyor. ama eğer sorun çıkarırsa senin dediğin daha mantıklı. deniyeceğim.

Tagli

PBP konusunda pek deneyimli değilim, yanılmış olabilirim yani. Ben olaya ASM açısından baktım ama belki derleyiciyi tasarlayanlar benim göremediğim bir çözüm görüp kullanmış olabilirler. Belki de RESUME BASLA, benim önerdiğim gibi bir kontrol değişkeni kullanıyordur. Ama derleyicinin kesmenin nerede geleceğini anlayabilmesi zor. Kodu sen yazdığın için kesmenin Zaman döngüsü içinde geleceğini bilebilirsin (tabi diğer yerlerde ilgili kesmeyi kapatmamışsan oralarda da gelebilir) ama derleyici bahsetmiş olduğum kontrol işini gerektiğinden daha fazla yerde yaptırıyor olabilir, tabi eğer tahmin ettiğim şekilde çalışıyorsa.

Ekleme: Sanırım nasıl yaptığını anladım. Gerçi forumda daha önce bahsedilmişti ama o zaman tam anlayamamıştım.
Alıntı yapılan: "[url=http://www.melabs.com/resources/pbpmanual/PicBasic Pro Manuel[/url]"]ON INTERRUPT will add an instruction after every statement to check whether or not an interrupt has occurred. DISABLE turns off the addition of this instruction. ENABLE turns it back on again. Usually the additional instruction will not be much of a problem, but long programs in small microcontrollers could suffer.
Anladığım kadarıyla aslında PicBasic Pro fiziksel anlamda kesmeye hiç gitmiyor. Yaptığı şey ENABLE-DISABLE arasında kalan her komuttan sonra kesme bayraklarını kontrol etmek (ve herhalde bunu enable bitleriyle AND'liyordur). Kesme parçasından dönüşte bir etikete gidebiliyorsa ve bunu yaparken yığında birikme olmuyorsa bunun tek açıklaması kesme parçasına GOTO ile gidiyor olması (gerçi yine aynı sitede RESUME'den sonra etiket kullanılırsa yığındaki dönüş değerlerinin geçersiz olacağına dair bir şey yazmış, bu kısmı anlamadım). O halde kesme gelen yere geri dönebilmesi için de kullanıcının yazdığı her komut için bu komutların sonunu işaret eden bir GOTO olması gerekir ve bu da büyük ihtimalle PC değiştirilerek atlama yapılan bir GOTO tablosudur. Zaten daha önce bir başlıkta kesme bölümünün içi boş bile olsa sadece "ON INTERRUPT ETIKET" yazıldığında kodun önemli ölçüde şiştiğinden bahsedilmişti.

Bu anlattıklarım tabi sadece benim tahminlerim. Tamamen yanılıyor da olabilirim.
Gökçe Tağlıoğlu

elmaalma

Alıntı yapılan: "vatandas30"peki kesmeyi jeton atıldığında aktif hale getirip, süre bittiğinde kapatma şansım var mı?

Jeton okuma için TMR0 kesmesi  yerine 10ms bir ilgili portu okuyup değerlendirseniz  nasıl olur?

ete

GOTO BASLA yazan yere RESUME BASLA dersen olur.
RESUME BASLA şeklinde son kısma yazarsan program her kesmeden sonra başa döneceği için olmaz.

Şu anda sorunsuz çalışıyor ise bırak çalışsın sorun çıkmaz.

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

ibo1973

ufak tefek hatalar olabilir programda denemedim ama mantık olraka bu şekilde kurmayı denesen programı sanırım daha iyi sonuç alırsın üzerinde hatalar varsa düzeltip bi dene istersen


define osc 4 
PORTA=0:portb=0 
TRISB=%00000000   'PortB tamamı çıkış yapıldı. 
TRISA=%00000001   'porta.o giriş yapıldı. 
'----------------------------------------------------------------- 
@ DEVICE pic16F628a                      'işlemci 16F628                                
@ DEVICE pic16F628a, WDT_OFF             'Watch Dog timer kapalı 
@ DEVICE pic16F628a, PWRT_ON             'Power on timer açık 
@ DEVICE pic16F628a, PROTECT_OFF         'Kod Koruma kapalı 
@ DEVICE pic16F628a, MCLR_on             'MCLR pini kullanılıyor. 
@ DEVICE pic16F628a, INTRC_OSC_NOCLKOUT  'Dahili osilatör kullanılacak 
'----------------------------------------------------------------- 
DEFINE LCD_DREG   PORTB   'LCD data bacakları hangi porta bağlı? 
DEFINE LCD_DBIT      4      'LCD data bacakları hangi bitten başlıyor? 
DEFINE LCD_EREG   PORTB   'LCD Enable Bacağı Hangi Porta bağlı? 
DEFINE LCD_EBIT      3      'LCD Enable Bacağı Hangi bite bağlı ? 
define LCD RWREG         PORTB      'LCD R/W Bacağı Hangi Porta bağlı? 
define LCD_RWBIT       2             'LCD R/W Bacağı Hangi bite bağlı ? 
DEFINE LCD_RSREG   PORTB   'LCD RS Bacağı Hangi Porta bağlı ? 
DEFINE LCD_RSBIT   1      'LCD RS bacağı Hangi Bite bağlı  ? 
DEFINE LCD_BITS      4      'LCD 4 bit mi yoksa 8 bit olarak bağlı? 
DEFINE LCD_LINES   2      'LCD Kaç sıra yazabiliyor 
'------------------------------------------------------------------------- 
ON INTERRUPT GoTo KESME   'kesme oluşursa KESME adlı etikete git. 
INTCON=%10100000 
OPTION_REG=%10000101       'Pull up dirençleri İPTAL- Bölme oranı 1/64. 
TMR0=0 
CMCON=7             '16F628 de komparatör pinleri iptal hepsi giriş çıkış 
'---------------------------------------------------------------------------- 
symbol buton=porta.0 
symbol ROLE=porta.1 
SAYAC   VAR   BYTE 
SN      VAR   BYTE 
DAK     VAR   BYTE 
'----------------------------------------------------------------------------- 
CLEAR  'tüm değişkenler sıfırlandı 
PAUSE 200 
LCDOUT $FE,1 
LOW PORTB.2  'LCD -R/W bacağı LOW'a çekildi. 

'----------------------------------------------------------------------------- 

basla: 
lcdout $FE,$82,"JETON ATINIZ" 
if dak<0 then ' dakika küçükse 0 dan 
           dak=0
           endif
if san<0 then 'saniye küçükse 0 dan
           sn=0
           endif                                 
if buton=0 then   
               ROLE=1 
               LCDOUT $FE,1 
               DAK=DAK+20 
           ENDIF 
if dak>=1 then ' dakika büyükse veya esitse bire
          lcdout $FE,$83,"KALAN SURE" 
          LCDOUT $FE,$C5,DEC2 DAK,":",DEC2 SN
          endif    
GOTO BASLA  

disable
KESME: 
      SAYAC=SAYAC+1         
      IF SAYAC=61 then         
               SAYAC=0                          
                     IF SN=0 THEN 
                               SN=60 
                               DAK=DAK-1                
                               ENDIF 
                        SN=SN-1          
                   ENDIF 
         IF DAK=0 AND SN=0 and sayac=60 THEN 
                                           ROLE=0 
                                           INTCON.2=0 
                                           LCDOUT $FE,1 
                                           resume
                                           enable
                                       endif    
         INTCON.2=0        'TMR0 Kesme bayrağı sıfırlanıyor 
         RESUME 
         ENABLE 
          
END

vatandas30

tşk .
kesme kısmında iki defa enable deyince program kilitleniyor.
ayrıca jeton kutusunda bi seçici anahtar var. sanırım jeton atıldığındaki sinyalin uzunluğunu belirliyor. milisaniye cinsinden. en uzununa aldığım zaman bile bazen devre sinyali algılamayabiliyor. sanırım kesmeye gittiği anda oluyor bu. o yüzden zaman işini kesme kullanmadan halletmeye çalışacağım.

vatandas30

sorunu çözdüm. zaten aklım almamıştı. çünkü jeton kutusunu üzerindeki  3 konumlu switch de 30,50 ve 100 ms yazıyor. bu sinyali picin almaması anormaldi.
ben jeton kutusunu yere koyuyordum. haliyle jeton tam olarak düşemiyordu. bu akşam farkettim ki jeton tam olarak düşebilecek şekilde yükseğe koyduğumda hiç sekme olmadı. yardımlarınız için tşk ederim. sizleri de yordum.