Donanım kesmesinde sorunvar

Başlatan hakıkat, 24 Temmuz 2012, 21:23:02

hakıkat

Merhaba ete hocam uzun zaman dır bir programla uğraiıyorum ama bir türlü sorunu gideremedim.Sizin forumda yaptığım araştımalara gore biraz benzeri var  ama yinede sorunu gderemedm.Yani sorunuma gelince donanım kesmesi kullanarak TMR0 kesmesiyle belirlenen zamanda devrenin çıkış yapmasını istiyorum belki program belli bir düzeye geldi ama zaman kesmesinde bir tirlü programı BAK etiketine yönlendiremiyorum .onun için T0IF=0 'kesme bayragi sıfırlanmıyor ve bundan dolayı nebelirlenen zaman gerçekleşiyor nede led2  ani yanmada sönmesi gerçekleşiyor. Çünkü led2 yanıyor ama sönmüyor. Umarım sorunumu anlata bildim. Programla sorunu daha iyi anlayacağınızı umuyorum.sorunu gidermeye yönelik ilgi gösterirseniz sevinirim
alıcı kısmı
@ DEVICE pic16F628 'islemci 16F628A 
@ DEVICE pic16F628, WDT_OFF 'Watch Dog timer kapali
@ DEVICE pic16F628, PWRT_ON 'Power on timer acik
@ DEVICE pic16F628, PROTECT_OFF 'Kod Protek kapali
@ DEVICE pic16F628, MCLR_ON 'MCLR pini kullaniliyor.
@ DEVICE pic16F628, XT_OSC 'Dahili osilatör kullanilmayacak
@ DEVICE pic16F628, LVP_OFF
@ DEVICE pic16F628, BOD_OFF

DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
DEFINE HSER_TXSTA 24h ' Enable transmit, BRGH = 1
DEFINE HSER_SPBRG 25  ' 9600 baud 4mhz de
DEFINE HSER_CLROERR 1 ' Clear overflow automatically

SYMBOL GIE  =INTCON.7   'genel interruptları açıyor
SYMBOL PEIE =INTCON.6   'peripheral interruptları açıyor
SYMBOL RCIE =PIE1.5     'USART Recive interrupt enable bit
SYMBOL RCIF =PIR1.5     'USART Receive interrupt flag bit
SYMBOL T0IE=INTCON.5    'TMR0  interrupt enable bit
SYMBOL T0IF=INTCON.2    'TMR0  interrupt flag bit
SYMBOL LED1=PORTA.3                   
SYMBOL LED2=PORTA.2
RCIE=1:PEIE=1:T0IE=0:GIE=1
ON INTERRUPT GOTO KESME

OPTION_REG=%10000101   '1/8
CMCON=7     
TRISB=%01000010
PORTB=0
TRISA =%00100000
PORTA=0

AL1    VAR  BYTE
AL2    VAR  BYTE
TEMP   VAR  BYTE
SART   VAR  BYTE
SURE   VAR  BYTE
US     VAR  BIT
I      VAR  BYTE
SAYAC  VAR  BYTE   
SN     VAR  BYTE
DAK    VAR  BYTE 
CLEAR

BASLA:
IF US=1 THEN 
    IF  AL1=11  THEN
        LED1=1:SART=1
        PAUSE 500
        LED1=0         
    ENDIF
    IF SART=1 AND AL1=21 THEN
       LED1=1:T0IE=1
       PAUSE 500
       LED1=0
    ENDIF
    IF SART=1 AND AL1=31 THEN
       LED1=1:LED2=1
       PAUSE 500
       LED1=0:LED2=0
    ENDIF
    IF SART=1 AND AL1=51 THEN
       LED1=1:SART=0:INTCON.5=0:SURE=0:DAK=0:SN=0
       PAUSE 500
       LED1=0
    ENDIF   
ENDIF
GOTO BASLA
;---------USART KESME-----------
DISABLE
KESME:
GIE=0 'tüm interruptlar? kapat yani INTCON.7=0
IF T0IF=1 THEN
SAYAC=SAYAC+1
  If SAYAC=67 Then      '61 adet kesme olunca 1 sn. süre geçiyor.(999424 us)
         SAYAC=0             'sayaç sifirlaniyor
         SN=SN+1            'saniye degeri bir artiriliyor
            If SN=60 Then     'saniye 60 olmus ise 1 dakika süre geçti o halde
               SN=0           ' saniye sifirlaniyor
               DAK=DAK+1       ' dakika degeri bir artiriliyor
               If dak=0 Then BAK
                 IF DAK=2 THEN 
                  LED2=1:LED1=1:T0IE=0
                   For I=0 To 200
                    PAUSE 10
                    Next I
                  LED2=0:LED1=0   
                     DAK=0:SN=0:SAYAC=0             ' dakika sifirlaniyor
                EndIf     
            EndIf
         EndIf
         'ENDIF
BAK:
pauseus 20               
T0IF=0 'kesme bayragi sifirlanacak                           
GOTO CIK
ENDIF
HSERIN 5,BIR,[WAIT("ARA"),AL1]
TEMP=RCREG
RCREG=0
TEMP=0
US=1
GOTO CIK
BIR:US=0
CIK:
RCIF=0
GIE=1 'Yani INTCON.7=1 kesmeleri açt?k.
RESUME
ENABLE
END


verici kısmı
@ DEVICE pic16F628 'islemci 16F628A 
@ DEVICE pic16F628, WDT_OFF 'Watch Dog timer kapali
@ DEVICE pic16F628, PWRT_ON 'Power on timer acik
@ DEVICE pic16F628, PROTECT_OFF 'Kod Protek kapali
@ DEVICE pic16F628, MCLR_OFF 'MCLR pini kullaniliyor.
@ DEVICE pic16F628, XT_OSC 'Dahili osilatör kullanilmayacak
@ DEVICE pic16F628, LVP_OFF
@ DEVICE pic16F628, BOD_OFF

DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
DEFINE HSER_TXSTA 24h ' Enable transmit, BRGH = 1
DEFINE HSER_SPBRG 25  '9600 baud @ 4mhz
DEFINE HSER_CLROERR 1 ' Clear overflow automatically

CMCON=7           '16F628 de komparatör pinleri iptal hepsi giriş çıkış
OPTION_REG.7=1    'Dahili pull-up lar AKTİF yapıldı
TRISB=%11010000
PORTB=0
TRISA =%00000011
PORTA=0

VER1 VAR BYTE
VER2 VAR BYTE

SYMBOL UYANDIRMA=PORTB.0
SYMBOL LED=PORTB.3
SYMBOL BUTON1=PORTB.4
SYMBOL BUTON2=PORTB.6
SYMBOL BUTON3=PORTB.7
SYMBOL BUTON4=PORTA.0
CLEAR
PAUSE 500

START:   
LED=0
IF BUTON1=0 THEN
VER1=11
UYANDIRMA=1
GOSUB GONDER
UYANDIRMA=0:LED=1
PAUSE 300
ENDIF

IF BUTON2=0 THEN
VER1=21
UYANDIRMA=1
GOSUB GONDER
UYANDIRMA=0:LED=1
PAUSE 200
ENDIF

IF BUTON3=0 THEN
VER1=31
UYANDIRMA=1
GOSUB GONDER
UYANDIRMA=0:LED=1
PAUSE 200
ENDIF

IF BUTON4=0 THEN
VER1=51
UYANDIRMA=1
GOSUB GONDER
UYANDIRMA=0:LED=1
PAUSE 200
ENDIF       
PAUSE 100
GOTO START
           
'-------------------------ALT PROGRAMLAR---------------------------------------
GONDER:
HSEROUT [REP$AA\5,REP$00\5,REP$FF\5]'uyandirma sinyali preambl
HSEROUT [REP$AA\5,REP$00\5,REP$FF\5]'uyandirma sinyali preambl
HSEROUT [REP$AA\5,REP$00\5,REP$FF\5]'uyandirma sinyali preambl
HSEROUT [REP$AA\5,REP$00\5,REP$FF\5]'uyandirma sinyali preambl
HSEROUT [REP$AA\5,REP$00\5,REP$FF\5]'uyandirma sinyali preambl
HSEROUT ["A","R","A",VER1]
HSEROUT ["A","R","A",VER1]
HSEROUT ["A","R","A",VER1]
RETURN
END


F®T

#1

LED2=1:LED1=1:T0IE=0   ben kesme çıkışında :T0IE=1   olarak görmedim.
"Hakk" şerleri hayr eyler Zannetme ki gayr eyler Ârif anı seyreyler Mevlâ görelim neyler Neylerse güzel eyler.

ete

Aynı anda iki ayrı kesme kaynağı kullanılacak ise öncelikle kesmeyi kimin oluşturduğunu bulmak gerekiyor.
Bunun yoluda kesme bayrağı dır. O halde kesme bayrağına bakarak önce programı ilgili kısma yönlendirmek ve orada işlemleri yaptıktan sonra her birinde kesme bayrağını sıfırlaman gerekiyor. Aksi halde program sürekli aynı kesmeyi oluşturup o kısımdan çıkamaz. Sen bunları yapmışsın. Bu kısımda hata yok.
Ama yaptığın bir hata var, Kesme kullanılan programlar içinde PAUSE komutunu kullanmaktan kaçınmalısın. Programa bakarsan bolca PAUSE 500 komutu kullanmışsın.
Bu ne gibi bir sorun yapabilir izah edeyim.
Program TMR0 kesmesi kullanıyor. Bu kesme adlı etikete sabit bir zaman süresi sonunda programın sürekli gitmesi demektir.
Peki program PAUSE 500 komutunu görünce ne yapacak. Bu kısımda 500 ms bekleyecek. Bu esnada kesme oluşsa bile oraya gidemeyecektir. Zira Pause 500 süresi bitmeden gidemez.  TMR0 sayacı geri planda çalışan ve hiç durmayanbir sayactır. O sürekli bir yandan sayacak ve sürekli kesme oluşturacaktır. Buda sana kesme bayrağının hiç sıfırlanmadığı şeklinde yansıyacaktır.
Yapman gerekn şu,
PAUSE 500 için,
DELAY:
FOR I=0 to 5000
  Pauseus 1
Next
RETURN
şeklinde bir alt program kullan. Pause 500 gördüğün yere GOSUB DELAY yaz. Her şey düzelecektir. Zira program burada yalnızca 1us bekleme yapar. diğerinede 500 ms bekleme yapıyor idi.
Gördüğüm sorun bu ve çözümüde açıkladığım şekildedir.

Ete

hakıkat

Ete hocam,
Kosurumuma bakmayın kısa sürede cevap yazamadım araya biraz zaman girdi neyse şimdi baka bildim .
hocam dediğiniz gibi yaptım ama her buttonda program takılı kalıyor.Led1 sürekli yanık kalıyor.Bu arada programın
zaman kısmını T0IE=1'in olduğu yerde belirleyip o şekilde sayaç olan kısma yönlendiremezmiyiz. aslında biraz denedim
program iyi görünüyordu ama program kapalıyken bile zaman tekrarlıyordu.Yani program sıfırlanmıyordu.Sizce sorunu nasıl giderebiliriz.

ete

Verici programda bir kusur var. Pullp dirençleri OPTION_REG=1 iken aktif olmaz. 1 yerine sıfır yazmalısın. Böylece pullup dirençleri aktif olup butonlar çalışacaktır. Ayrıca veri yollanırken yalnızca bir kere uyandırma sinyali ve bir kerede veri yollanması yeterlidir.
Birden fazla bu konuda satır ilave edilmesi çalışma hassasiyetini bozar.

Alıcı programda gerekli değişiklikleri yaptım ve sistemi simule ettim sorunsuz çalışıyor.
Alıcı programın son hali aşağıdaki şekildedir.

@ DEVICE pic16F628 'islemci 16F628A 
@ DEVICE pic16F628, WDT_OFF 'Watch Dog timer kapali
@ DEVICE pic16F628, PWRT_ON 'Power on timer acik
@ DEVICE pic16F628, PROTECT_OFF 'Kod Protek kapali
@ DEVICE pic16F628, MCLR_ON 'MCLR pini kullaniliyor.
@ DEVICE pic16F628, XT_OSC 'Dahili osilatör kullanilmayacak
@ DEVICE pic16F628, LVP_OFF
@ DEVICE pic16F628, BOD_OFF

DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
DEFINE HSER_TXSTA 24h ' Enable transmit, BRGH = 1
DEFINE HSER_SPBRG 25  ' 9600 baud 4mhz de
DEFINE HSER_CLROERR 1 ' Clear overflow automatically

SYMBOL GIE  =INTCON.7   'genel interruptları açıyor
SYMBOL PEIE =INTCON.6   'peripheral interruptları açıyor
SYMBOL RCIE =PIE1.5     'USART Recive interrupt enable bit
SYMBOL RCIF =PIR1.5     'USART Receive interrupt flag bit
SYMBOL T0IE=INTCON.5    'TMR0  interrupt enable bit
SYMBOL T0IF=INTCON.2    'TMR0  interrupt flag bit
SYMBOL LED1=PORTA.3                   
SYMBOL LED2=PORTA.2
RCIE=1:PEIE=1:T0IE=0:GIE=1
ON INTERRUPT GOTO KESME

OPTION_REG=%10000101   '1/8
CMCON=7     
TRISB=%01000010
PORTB=0
TRISA =%00100000
PORTA=0

AL1    VAR  BYTE 56
AL2    VAR  BYTE 57
TEMP   VAR  BYTE
SART   VAR  BYTE
SURE   VAR  BYTE
US     VAR  BIT
I      VAR  BYTE
SAYAC  VAR  BYTE   
SN     VAR  BYTE
DAK    VAR  BYTE
Z      VAR  WORD
CLEAR

BASLA:
IF US=1 THEN 
    IF  AL1=11  THEN
        LED1=1:SART=1
        PAUSE 500
        LED1=0
        US=0       
    ENDIF
    IF SART=1 AND AL1=21 THEN
       LED1=1:T0IE=1
       GOSUB DELAY
       LED1=0
       US=0
    ENDIF
    IF SART=1 AND AL1=31 THEN
       LED1=1:LED2=1
       GOSUB DELAY
       LED1=0:LED2=0
       US=0
    ENDIF
    IF SART=1 AND AL1=51 THEN
       LED1=1:SART=0:INTCON.5=0:SURE=0:DAK=0:SN=0
       GOSUB DELAY
       LED1=0
       US=0
    ENDIF   
ENDIF
GOTO BASLA

delay:
      FOR Z=0 TO 40000:NEXT
      RETURN
     
;---------USART KESME-----------
DISABLE
KESME:
GIE=0 'tüm interruptlar? kapat yani INTCON.7=0
IF T0IF=1 THEN
SAYAC=SAYAC+1
  If SAYAC=67 Then      '61 adet kesme olunca 1 sn. süre geçiyor.(999424 us)
         SAYAC=0             'sayaç sifirlaniyor
         SN=SN+1            'saniye degeri bir artiriliyor
            If SN=60 Then     'saniye 60 olmus ise 1 dakika süre geçti o halde
               SN=0           ' saniye sifirlaniyor
               DAK=DAK+1       ' dakika degeri bir artiriliyor
               If dak=0 Then BAK
                 IF DAK=2 THEN 
                  LED2=1:LED1=1:T0IE=0
                   pause 200
                  LED2=0:LED1=0   
                     DAK=0:SN=0:SAYAC=0             ' dakika sifirlaniyor
                EndIf     
            EndIf
         EndIf

BAK:
pauseus 20               
T0IF=0 'kesme bayragi sifirlanacak                           
GOTO CIK
ENDIF
HSERIN 5,CIK,[WAIT("ARA"),AL1]
TEMP=RCREG
US=1
CIK:
GIE=1 'Yani INTCON.7=1 kesmeleri açt?k.
RESUME
ENABLE
END


Ete

hakıkat

Gönderdiğiniz programı denedim.ISIS te oluyor ama pratikte zaman başlatan buttona basıldığı zaman led1 sürekli yanmaktadır.Bu zaman zarfında bende biraz farklı yerde zaman belirlemenin üzerine çalıştım.program her bir şekilde çalışıyor yalnız devreyi açtığın andan itibaren (zaman ayarlı tuşa basılmadan ) zaman sayacı başlamaktadır.Yani mesala gönderdiğim programda zaman ayarı 2 dakikadır.Devreyi sadece açıp 1 dakika  beklenilse ve sonra devrenin zamanı başlatan tuşuna basıldığı zaman 2 dakika sonra değilde 1 dakika sonra  devre çıkış vermektedir.Yada devre açıldıktan 2 dakika sonra zaman başlatma tuşuna  basıldığı zaman ise devre çıkış vermemektedir. Bunun nedeni sizce ne olabilir yoksa kesmenin kendi özelliğinden mi kaynaklanıyor devre açılır açılmaz donanım kesmesi açılıp zaman işliyor tam olarak sorunu anlayamadım .Yani bu normalmidir. Umarım  sorunu anlatabilmişimdir.
alıcı
@ DEVICE pic16F628 'islemci 16F628A 
@ DEVICE pic16F628, WDT_OFF 'Watch Dog timer kapali
@ DEVICE pic16F628, PWRT_ON 'Power on timer acik
@ DEVICE pic16F628, PROTECT_OFF 'Kod Protek kapali
@ DEVICE pic16F628, MCLR_ON 'MCLR pini kullaniliyor.
@ DEVICE pic16F628, XT_OSC 'Dahili osilatör kullanilmayacak
@ DEVICE pic16F628, LVP_OFF
@ DEVICE pic16F628, BOD_OFF

DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
DEFINE HSER_TXSTA 24h ' Enable transmit, BRGH = 1
DEFINE HSER_SPBRG 25  ' 9600 baud 4mhz de
DEFINE HSER_CLROERR 1 ' Clear overflow automatically

SYMBOL GIE  =INTCON.7   'genel interruptları açıyor
SYMBOL PEIE =INTCON.6   'peripheral interruptları açıyor
SYMBOL RCIE =PIE1.5     'USART Recive interrupt enable bit
SYMBOL RCIF =PIR1.5     'USART Receive interrupt flag bit
SYMBOL T0IE=INTCON.5    'TMR0  interrupt enable bit
SYMBOL T0IF=INTCON.2    'TMR0  interrupt flag bit
SYMBOL LED1=PORTA.3                   
SYMBOL LED2=PORTA.2
RCIE=1:PEIE=1:T0IE=0:GIE=1
ON INTERRUPT GOTO KESME

OPTION_REG=%10000101   '1/8
CMCON=7     
TRISB=%01000010
PORTB=0
TRISA =%00100000
PORTA=0

AL1    VAR  BYTE
AL2    VAR  BYTE
TEMP   VAR  BYTE
SART   VAR  BYTE
SURE   VAR  BYTE
US     VAR  BIT
I      VAR  BYTE
SAYAC  VAR  BYTE   
SN     VAR  BYTE
DAK    VAR  BYTE 
CLEAR

BASLA:
IF US=1 THEN 
    IF  AL1=11  THEN
        LED1=1:SART=1
        PAUSE 500
        LED1=0         
    ENDIF
    IF SART=1 AND AL1=21 THEN
       LED1=1:T0IE=1:SURE=2
       GOSUB DELAY
       LED1=0
    ENDIF
    IF SART=1 AND AL1=31 THEN
       LED1=1:LED2=1
       GOSUB DELAY
       LED1=0:LED2=0
    ENDIF
    IF SART=1 AND AL1=51 THEN
       LED1=1:SART=0:INTCON.5=0:SURE=0:DAK=0:SN=0
       GOSUB DELAY
       LED1=0
    ENDIF   
ENDIF
GOTO BASLA
DELAY:
FOR I=0 to 5000
  Pauseus 1
Next
GOTO BASLA
;---------USART KESME-----------
DISABLE
KESME:
GIE=0 'tüm interruptlar? kapat yani INTCON.7=0
IF T0IF=1 THEN
SAYAC=SAYAC+1
  If SAYAC=67 Then      '61 adet kesme olunca 1 sn. süre geçiyor.(999424 us)
         SAYAC=0             'sayaç sifirlaniyor
         SN=SN+1            'saniye degeri bir artiriliyor
            If SN=60 Then     'saniye 60 olmus ise 1 dakika süre geçti o halde
               SN=0           ' saniye sifirlaniyor
               DAK=DAK+1       ' dakika degeri bir artiriliyor
               IF SURE>0 AND SURE=DAK THEN
                  LED2=1:LED1=1:T0IE=0
                   For I=0 To 200
                    PAUSE 10
                    Next I
                  LED2=0:LED1=0   
                     DAK=0:SN=0:SAYAC=0             ' dakika sifirlaniyor
                EndIf     
            EndIf
         EndIf
         'ENDIF
BAK:
pauseus 20               
T0IF=0 'kesme bayragi sifirlanacak                           
GOTO CIK
ENDIF
HSERIN 5,BIR,[WAIT("ARA"),AL1]
TEMP=RCREG
RCREG=0
TEMP=0
US=1
GOTO CIK
BIR:US=0
CIK:
RCIF=0
GIE=1 'Yani INTCON.7=1 kesmeleri açt?k.
RESUME
ENABLE
END


ete

Basla satırından sonraki if döngüsünde hala pause 500 mevcut. Bunu da kaldırmalısın.
İsis de devre doğru çalışıyorsa gerçekte de çalışması gerekir.
Çalışmıyor ise mutlaka devrende bir hata vardır. Devreni göremeyeceğim için daha fazla yardımcı olmam imkansız gözüküyor.
Ben kendi yazdığımı denemiş ve sorunsuz çalıştığını görmüştüm.
Söylenecek tek bir şey var devren isis de çalıştığı gibi çalışması gerek. Eksik olan şey devrende dir.

Ete

Powered by EzPortal