TMR0 kesmesi ve EUSART KESMESI

Başlatan toprak, 28 Mart 2012, 10:28:02

toprak

Merhaba arkadaslar
giris yapmam biraz zor oldu ama forumda artik bende varim.  :)
Neyse
Bir suredir keyped ile rf modul ile uzaktan kontrol edebilecegim bir zamanlayici yapmak istiyordum.16f688 ile yaptim.calisiyor.
fakat bir sorunu var anlamadim.simdilik tmr0 ve eusart in ayni kesmeden oldugunu dusunuyorum.sorun su.
vericiden *(yildiz) ile reset bilgisi gonderiyorum.ayrica * girdikten sonra keypad ile1 den 99 a kadar zaman girebiliyorum.ama  girdigim rakamlar sayi olusmadan aliciya gondermiyorum.sayi olustuktan sonra  kare ile gonderip alicida tmr0 i aktif yapiyorum.ama  yildiz yaptiktan sonra sayi olusturup bir sure bekliyorum ve sonra kare ile gonderiyorum.ama o bekledigim surede alicida hesaba katiliyor oysa ben onayladiktan sonra zaman baslamasi lazim. busorun nasil giderilebilir. tesekkurler.
Kişi kesinliklerle başlarsa gideceği yer kuşkulardır, ama kuşkularla başlayacak kadar doygun ise kesinliklere ulaşır.

ete

Toprak ,
Aramıza hoş geldin.  EUSART kesmesi ile TMR0 kesmesi aynı şey değildir. EUSART ile USART kesmesi aynı şeydir. Eusart Usartın biraz daha gelişmişi. Farkları henüz bilmiyorum ama kesme kısmına baktım değişiklik yok gözüküyor.

Önce TMR0 kesmesi nedir onu açıklayayım basitçe. TMR0 bir zamanlayıcı. Geri planda ana programdanbağımsız olarak sürekli çalışır. Bir ön değer vermez isen sıfırdan 255'e kadar sayar ve yeniden sıfıra dönerek işi bir döngü şeklinde sürdürür.
Kesme 'sini açarsan 255 den sıfır'a dönerken kesme bayrağını set ederek kesme oluşturur.
Bölücüleri vardır. 1/1 bölme oranını kullanırsan pic osilatörünün (dahili yada harici) her clk palsinde bir sayar.
1/2 bölme oranını kullanırsan her 2 clk paslinde bir sayar. 1/64 kullanırsan her 64 clk palsinde bir sayar. Kısaca bölme oranı onun saymasını geciktirir.  Kesme bayrağı kesme alt programında sıfırlanması gerekir. ksi halde yeniden kesme oluşmaz.

USART yada EUSART ise bir haberleşme portudur. Kullandığın pic de bu özellik var ise o pic in mutlaka bir TX birde RX pini vardır. TX genelde programcının isteği doğrultusunda yollama yapabildiği için kesme sisteminde kullanılmaz. Ama RX önemli bir ayrıcalıktır. Yani dışarıdan kablolu yada kablosuz bir bilgi almanın iki yolu vardır. Birinci yolda bir alma komutu yazarsın SERIN veya SERIN2 gibi ve başında beklersin. Beklemek zorundasın çünki ne zaman bilgi geleceğini bilemezsin. O halde sürekli bu komutu çalıştırıp bir şey geliyormu diye bakmak zorunda kalırsın. Arada başka işlerde yapayım dersen gelecek bilgiyi kaçırma ihtimalin yüksek olur.
İkinci yöntemde ise USART kesmesini açarsın ve sistem geri planda RX pinindenbir bilgi geliyormu diye senin için bakar durur.
Sende bu arada başka işlerle uğraşır ve gelenbilgi varmı diye bakmak ozrunda kalmazsın. Bir bilgi RX pininden girer girmez hemen kesme bayrağı set edilerek kesme oluşturulur. Program kesme etiketine gider ve orada verilmiş olan HSERIN komutu ile gelen bilgi alınır. Bu sistemde de kesme bayrağı silinmesi sıfırlanması gerekir. Ama bu bayrak direk ulaşılabilen bir register değildir. RCREG (alım registeri) içini boşaltarak bayrak otomatik sıfırlanır. TEMP=RCREG şeklinde bir komut bu işi yapabilir.
Böylece gelen bir başka bilgi için sistem tekrar beklemeye alınabilir.

Bir programda birden fazla kesme oluşturacak kaynak kullanılabilir. Kesme oluştuğunda hepsi aynı yere gider. Orada kesme bayraklarından hangisi set edilmiş ise ona ait kesmenin oluştuğunu anlar ve ona uygun komutları çalıştırırsın. Aksi halde USART kesmesi oluştuğunda TMR0 kesme komutlarınıda çalıştırırsan sistem düzgün çalışmayacaktır. Sendeki sorunların buna benzer şeyler olduğunu tahmin ediyorum. Program vermediğin için başka bir şey söylemek mümkün değil.

Nedense program verip ne sorunum var diye sormak pek alışkanlık haline gelmemiş. Herkes sanal olarak sorusunu sormaya hevesli. Durum öyle oluncada verilen cevaplar sanal oluyor maalesef. Verdiğim açıklamaları dikkatli okuyarak yeniden sistemini kontrol et belki sorunu bulabilirsin artık.

Ete

toprak

programlari verirsem sanirim ne yaptigim daha anlasilir.
'****************************************************************
'*  Name    : UNTITLED.BAS                                      *
'*  Author  : [select VIEW...EDITOR OPTIONS]                    *
'*  Notice  : Copyright (c) 2012 [select VIEW...EDITOR OPTIONS] *
'*          : All Rights Reserved                               *
'*  Date    : 3/25/2012                                         *
'*  Version : 1.0                                               *
'*  Notes   :                                                   *
'*          :                                                   *
'****************************************************************
@ DEVICE pic16F688 'islemci 16F688
@ DEVICE pic16F688, WDT_OFF 'Watch Dog timer kapali
@ DEVICE pic16F688, PWRT_ON 'Power on timer acik
@ DEVICE pic16F688, PROTECT_OFF 'Kod Protek kapali
@ DEVICE pic16F688, MCLR_OFF 'MCLR pini kullaniliyor.
@ DEVICE pic16F688, INTRC_OSC_NOCLKOUT  'Dahili osilator kullanilacak
@ DEVICE pic16F688, BOD_OFF
CMCON0=7     
ADCON0=0
ADCON1=0
ANSEL=0
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
define OSC 4
OSCCON=%01100111
WPUA=%00110111
TRISC=%00000111
TRISA =%00000000
OPTION_REG=%10000000
INTCON=%10000000
SYMBOL UYANDIRMA=PORTA.5
SYMBOL LED=PORTC.3
SYMBOL STUN1=PORTC.0
SYMBOL STUN2=PORTC.2
SYMBOL STUN3=PORTC.1
SYMBOL SATIRA=PORTA.0
SYMBOL SATIRB=PORTA.1
SYMBOL SATIRC=PORTA.2
SYMBOL SATIRD=PORTA.4
TUS   VAR BYTE
ZAMAN VAR BYTE
VER   VAR BYTE
A     VAR BYTE
B     VAR BYTE
BB    VAR BYTE
G     VAR BIT
R     VAR BIT
OB    VAR BIT
I     VAR BYTE
CLEAR
PAUSE 100
BASLA:
PORTA.0=1
PORTA.1=1
PORTA.2=1
PORTA.4=1
PORTC.0=1
PORTC.1=1
PORTC.2=1

UYANDIRMA=0
  LOW SATIRA
IF STUN1=0 THEN
TUS=1:GOSUB HESAP
WHILE STUN1=0
LED=1
WEND
ENDIF
IF STUN2=0 THEN
TUS=2:GOSUB HESAP
WHILE STUN2=0
LED=1
WEND
ENDIF
IF STUN3=0 THEN
TUS=3:GOSUB HESAP
WHILE STUN3=0
LED=1
WEND
ENDIF
     HIGH SATIRA
  LOW SATIRB
IF STUN1=0 THEN
TUS=4:GOSUB HESAP
WHILE STUN1=0
LED=1
WEND
ENDIF
IF STUN2=0 THEN
TUS=5:GOSUB HESAP
WHILE STUN2=0
LED=1
WEND
ENDIF
IF STUN3=0 THEN
TUS=6:GOSUB HESAP
WHILE STUN3=0
LED=1
WEND
ENDIF
    HIGH SATIRB
   LOW SATIRC
IF STUN1=0 THEN
TUS=7:GOSUB HESAP
WHILE STUN1=0
LED=1
WEND
ENDIF
IF STUN2=0 THEN
TUS=8:GOSUB HESAP
WHILE STUN2=0
LED=1
WEND
ENDIF
IF STUN3=0 THEN
TUS=9:GOSUB HESAP
WHILE STUN3=0
LED=1
WEND
ENDIF
   HIGH SATIRC
  LOW SATIRD
IF STUN1=0 THEN
R=1:GOSUB RES
WHILE STUN1=0
LED=1
WEND
ENDIF
IF STUN2=0 THEN
TUS=0:GOSUB HESAP
WHILE STUN2=0
LED=1:pause 300:LED=0
WEND
ENDIF
IF STUN3=0 THEN
G=1:GOSUB GONDER
WHILE STUN3=0
LED=1
WEND
ENDIF
    HIGH SATIRD
    LED=0
pause 100
GOTO BASLA
'*******************************************************************************
HESAP:
IF OB=1 THEN
A=TUS
A=A*10:BB=1:OB=0
ENDIF
IF BB=1  THEN
B=TUS
  ZAMAN=A+B
  ENDIF
RETURN
'*******************************************************************************
RES:
IF R=1 THEN
  UYANDIRMA=0:TUS=0:ZAMAN=0:R=0:G=0:LED=0:B=0:A=0:BB=0:OB=1
  VER=255
  UYANDIRMA=1:PAUSE 200
GOSUB GIT
UYANDIRMA=0:TUS=0:ZAMAN=0:LED=1:pause 300:LED=0:VER=0
ENDIF
  RETURN

'*******************************************************************************
GONDER:
  IF ZAMAN<>0 AND G=1 THEN   
VER=zaman
UYANDIRMA=1:PAUSE 200
GOSUB GIT
UYANDIRMA=0:TUS=0:ZAMAN=0:LED=1:pause 300:LED=0:VER=0
ENDIF
  RETURN
'*******************************************************************************
GIT:
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",VER] 
HSEROUT ["A","R","A",VER]
HSEROUT ["A","R","A",VER] 
RETURN
'*******************************************************************************
END

alici

'****************************************************************
'*  Name    : UNTITLED.BAS                                      *
'*  Author  : [select VIEW...EDITOR OPTIONS]                    *
'*  Notice  : Copyright (c) 2011 [select VIEW...EDITOR OPTIONS] *
'*          : All Rights Reserved                               *
'*  Date    : 25.11.2011                                        *
'*  Version : 1.0                                               *
'*  Notes   :                                                   *
'*          :                                                   *
'****************************************************************
@ DEVICE pic16F688 'islemci 16F688
@ DEVICE pic16F688, WDT_OFF 'Watch Dog timer kapali
@ DEVICE pic16F688, PWRT_ON 'Power on timer acik
@ DEVICE pic16F688, PROTECT_OFF 'Kod Protek kapali
@ DEVICE pic16F688, MCLR_OFF 'MCLR pini kullaniliyor.
@ DEVICE pic16F688, INTRC_OSC_NOCLKOUT  'Dahili osilator kullanilacak
@ DEVICE pic16F688, BOD_OFF
CMCON0=7     
ADCON0=0
ADCON1=0
ANSEL=0

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
define OSC 4          ' Çalýþma frekansý
OSCCON=%01100101
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

RCIE=1
PEIE=1
T0IE=0
GIE=1
ON INTERRUPT GOTO KESME

OPTION_REG=%11000101
WPUA=0
TRISC=%00100000
PORTC=0
TRISA =%00000000
PORTA=0
AL1   VAR BYTE
SURE  VAR BYTE
DAK   VAR BYTE
TUS   VAR BYTE
SN    VAR BYTE
SAYAC VAR BYTE
TEMP  VAR BYTE
I     VAR WORD
US    VAR BIT
K     VAR WORD
ARA   VAR WORD
SYMBOL LED=PORTC.3
SYMBOL ROLE=PORTA.5
CLEAR

ON INTERRUPT GOTO KESME

BASLA:
TUS=AL1:LED=0:ROLE=0
IF US=1 THEN
IF TUS=255 THEN
    LED=1:ROLE=0:PAUSE 200:LED=0:DAK=0:SN=0:SAYAC=0:SURE=0:
    AL1=0:TMR0=0:TUS=0:INTCON.5=0:PAUSE 100
ENDIF
ENDIF
IF US=1 THEN
IF TUS<>255 AND tus=al1 THEN
FOR I=0 TO 6
    LED=1:PAUSE 100:LED=0:PAUSE 100
     NEXT I
SURE=tus:TUS=0:T0IE=1:AL1=0:TMR0=0
ENDIF
ENDIF

GOTO BASLA


   
'*******************************************************************************   
DISABLE
KESME:
GIE=0 'tüm interruptlar? kapat yani INTCON.7=0
IF T0IF=1 THEN
      SAYAC=SAYAC+1      'kesme sayac?  1 sn= 61(sayac) x 256 (Tmr0) x 64 (bölme)
      IF SAYAC=61 then      '61 adet kesme olunca 1 sn. süre geçiyor.(999424 us)
         SAYAC=0             'sayaç s?f?rlan?yor
         SN=SN+1            'saniye de?eri bir art?r?l?yor
            IF SN=60 THEN     'saniye 60 olmu? ise 1 dakika süre geçti o halde
               SN=0           ' saniye s?f?rlan?yor
               DAK=DAK+1       ' dakika de?eri bir art?r?l?yor
             
            ENDIF
       ENDIF
       IF  SN=0 AND  DAK=0 THEN  BAK
       IF SURE<>0 AND DAK=SURE THEN
INTCON.5=0:ROLE=1:LED=1
FOR I=0 TO 1000
PAUSE 2
NEXT I
ROLE=0:SURE=0:LED=0:DAK=0:SN=0:DAK=0:SAYAC=0         
        ENDIF
BAK:               
T0IF=0 'kesme bayragi sifirlanacak                           
GOTO CIK
ENDIF
HSERIN 1,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

Kişi kesinliklerle başlarsa gideceği yer kuşkulardır, ama kuşkularla başlayacak kadar doygun ise kesinliklere ulaşır.

ete

Verici programda pek kusur yok. Yalnızca Heserin komutlarını düzensiz kullanmışsın.
Doüğru kullanım şekli
HSEROUT [REP$AA\5,REP$00\5,REP$FF\5]'uyandirma sinyali preambl
HSEROUT ["A","R","A",VER]
şeklinde iki satır. Bunları adetli vermek çok avantaj sağlamaz. Bir defa vermen yeterlidir.

Alıcı programdaki sorunlara gelince;
Kesme kullanılan programlarda Pause komutu kesinlikle kullanılmamalıdır. Bolca Pause 100 kullanmışsın. Bu kesme oluşumunda sorun yaratır. Pause 100 (100 ms) süresi dolmadan kesme oluşsa bile program Kesme etiketine atlayamaz.

KESME etiketinden önce mutlaka DISABLE komutunun verilmesi gerekir. Bu kesme içinden yeniden kesme oluşmasını önler.

100 ms lik bir pause gerekiyor ise bunu bir alt program şekline çevir ve Pause 100 yerine Gosub GECIKME şeklinde yaz.
Gecikme işinide;
FOR I=0 to 3000:next:return şeklinde halledebilirsin.
Basicde kesme olutuğunda o anda işlenen basic komutu bitmeden kesme etiketine atlanmaz. Burada da süre yada gecikme komutları önem kazanıyor. Pause 100 komutu, 100 ms lik süre dolmadan bitemez. Bu nedenle ya us seviyesinde en büyük 5 us olarak gecikme kullanmak ve bunu döngü ile uzatmak en doğru hareket olacaktır.
Kesme içinde pause kullanacak isen onu direk kullanabilirsin. 1000 adet pause 2 orada ne işine yarıyor belli değil bence lüzumsuz ve programı negatif etkileyen bir komut dizisi.

TEMP=RCREG  bu komut RCREG içini boşaltır. Bu ise USART kesme bayrağının sıfırlanmasını sağlar.
RCREG=0 Bu komuta gerek yoktur.
TEMP=0 Bunada gerek yok.

HSERIN 1,BIR,[WAIT("ARA"),AL1]   komutunda yer alan 1 rakamı beklenen bilginingelmesi için 1 ms bekleneceğini gelmez ise BIR etiketine atlanacağını gösteriyor. 1 ms bilgi almak için çok kısa bir süredir. Bunun enaz 3 ms dolayında olması beklenir. Bu nedenle bana kalırsa en azından 5-10 ms lik bir süre vererek normal çalışmayı sağla sonra deneyerek değeri düşür. Sorun oluştuğu anda bir önceki değeri kullanabilirsin.

Şimdlik tespitlerim bunlar.

Ete

toprak

Hocam
belirttiklerinize iliskin...
vericide
HSEROUT [REP$AA\5,REP$00\5,REP$FF\5]'uyandirma sinyali preambl
HSEROUT ["A","R","A",VER]
bunun sayisini dusurunce istikrarki haberlesme olmayabiliyor ama sayisini artirinca aliyor
  alicida
HSERIN 1,BIR,[WAIT("ARA"),AL1]  komutundaki 1 rakami yerine 5 yazdim yine ilk bilgiyi aliyorken
ikincisinde sorun olabiliyor.

program busekilde pratikde de calisiyor
uzun suredir deniyorum

fakat sanirim sorunum anlasilmadi
sorun su
vricidede goruldugu gibi
iki bilgi gidiyor birincisinde hersey sifirlaniyor
ondan sonra zaman girilebiliyor ve sonraa ikinci bilgiye gore alicida zaman baslamasi gerekirken
yildiz ile baslamis oluyor. o nedenle ben zaman girip bir sure beklesem  sonrasinda onaylatip zaman  baslamasi gerekirken 
beklenen sureyide hesapliyor ve buda bir sorun oluyor.16f688 ile ilgili bir sorunmu acaba cunku 16f688 ile yaptigim bir sabit bir zamanlayicidada ben baslatmadan diyelim bir dak. ayarlamis isem devreye enerji verir vermez zaman basliyor ve her bir dak.da role cekiyor. oysa ayarlanmis tmr0 kesmesini ben aktif ediyorum ve role cektikten sonra sifirliyorum ama sanki ona bakmadan  programi okuyor. bu simdiki devredede  hep sayiyor ben istedigim zamani girince  zaten sayilani ekleyip role cekiyor. benim istedigim zaman kadar beklemiyor.

Kişi kesinliklerle başlarsa gideceği yer kuşkulardır, ama kuşkularla başlayacak kadar doygun ise kesinliklere ulaşır.

toprak

Usart  ve timer0 kesmesini birlikte kullanarak bir turlu devremi istikrarli calistiramadim. Sorun kristal osilator olabilir mi diye duşünerek 4 MHz xt krıstal ile de devreyi yaptım. Aynı istikrarsizlik devam etti. 4Mhz iç osilator kullanmakla dış osilator kullanmak arasında hiç bir fark oluşmada. Hem 16F688 de hem de 16F628 de aynı sorun var.

Sorun şu. Alıcıya enerji verdiğim anda pic çıkış veriyor. Led yanmaması gerekirken yanıyor. Timer0 kesmesinin prescaler ayarını ne kadar değiştirsem de etkisiz kalıyor

Verıcı

@ DEVICE pic16F688 'islemci 16F688
@ DEVICE pic16F688, WDT_OFF 'Watch Dog timer kapali
@ DEVICE pic16F688, PWRT_ON 'Power on timer acik
@ DEVICE pic16F688, PROTECT_OFF 'Kod Protek kapali
@ DEVICE pic16F688, MCLR_OFF 'MCLR pini kullaniliyor.
@ DEVICE pic16F688, INTRC_OSC_NOCLKOUT  'Dahili osilator kullanilacak
@ DEVICE pic16F688, BOD_OFF

DEFINE  OSC 4
OSCCON=%01100101
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

CMCON0=7     
ADCON0=0
ADCON1=0
ANSEL=0
WPUA=0
TRISC=%00000111
PORTC=0
TRISA =%00000000
PORTA=0

VER1 VAR BYTE
VER2 VAR BYTE
SYMBOL UYANDIRMA=PORTA.4
SYMBOL LED=PORTC.3
SYMBOL BUTON1=PORTC.2
SYMBOL BUTON2=PORTC.1
SYMBOL BUTON3=PORTC.0


BASLA:
LED=0
IF BUTON1=0 THEN
VER1=11:VER2=72
UYANDIRMA=1
GOSUB GONDER
UYANDIRMA=0:LED=1:pause 1000:led=0
ENDIF

IF BUTON2=0 THEN
VER1=21:VER2=82
UYANDIRMA=1
GOSUB GONDER
UYANDIRMA=0:LED=1:pause 1000:led=0
ENDIF

IF BUTON3=0 THEN
VER1=31:VER2=92
UYANDIRMA=1
GOSUB GONDER
UYANDIRMA=0:LED=1:pause 1000:led=0
ENDIF
 

GOTO BASLA



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 ["R","E","D",VER1,VER2] 
HSEROUT ["R","E","D",VER1,VER2]
HSEROUT ["R","E","D",VER1,VER2] 
RETURN
END



Alıcı

@ DEVICE pic16F688 'islemci 16F688
@ DEVICE pic16F688, WDT_OFF 'Watch Dog timer kapali
@ DEVICE pic16F688, PWRT_ON 'Power on timer acik
@ DEVICE pic16F688, PROTECT_OFF 'Kod Protek kapali
@ DEVICE pic16F688, MCLR_OFF 'MCLR pini kullaniliyor.
@ DEVICE pic16F688, INTRC_OSC_NOCLKOUT  'Dahili osilator kullanilacak
@ DEVICE pic16F688, BOD_OFF

DEFINE  OSC 4
OSCCON=%01100101
DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
DEFINE HSER_TXSTA 24h ' Enable transmit, BRGH = 0  24tu
DEFINE HSER_SPBRG 25  '9600 baud @ 4mhz
DEFINE HSER_CLROERR 1

SYMBOL LED=PORTA.2

SYMBOL GIE  =INTCON.7   'genel interruptlarý açiyor
SYMBOL PEIE =INTCON.6   'peripheral interruptlarý açiyor
SYMBOL RCIE =PIE1.5     'USART Recive interrupt enable bit
SYMBOL RCIF =PIR1.5     'USART ALICI TAMPONU DOLU 1

SYMBOL T0IE =INTCON.5    'TMR0  interrupt enable bit
SYMBOL T0IF =INTCON.2    'TMR0  interrupt flag bit


 
OPTION_REG=%10000010    '1/64
CMCON0=7     
ADCON0=0
ADCON1=0
ANSEL=0
WPUA=0
TRISC=%00100000
PORTC=0
TRISA =%00000000
PORTA=0


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


RCIE=1
PEIE=1
GIE=1

T0IE=0

ON INTERRUPT GOTO KESME
CLEAR
pause 200

BASLA:
LED=0

IF US=1 THEN
    US=0
    IF  AL1=11 AND AL2=72 THEN
        LED=1:SART=1:PAUSE 1000:LED=0
    ENDIF
    IF SART=1 AND AL1=21 AND AL2=82 THEN
       LED=1:PAUSE 1000:LED=0:T0IE=1
    ENDIF
    IF SART=1 AND AL1=31 AND AL2=92 THEN
       LED=1:PAUSE 2000:LED=0
    ENDIF
    IF SART=1 AND AL1=51 AND AL2=112 THEN
       LED=1:PAUSE 1000:LED=0:SART=0
    ENDIF
ENDIF
PAUSEUS 1
GOTO BASLA

DISABLE
KESME:
GIE=0 'tüm interruptlari kapat yani INTCON.7=0


HSERIN 1,CIK,[WAIT("RED"),AL1,AL2 ]
TEMP=RCREG
US=1

CIK:
IF T0IE=1 THEN
      SAYAC=SAYAC+1         'kesme sayac?  1 sn= 61(sayac) x 256 (Tmr0) x 64 (bölme)
      IF SAYAC=488 then         '61 adet kesme olunca 1 sn. süre geçiyor.(999424 us)
         SAYAC=0               'sayaç s?f?rlan?yor
         SN=SN+1              'saniye de?eri bir art?r?l?yor
            IF SN=60 THEN        'saniye 60 olmu? ise 1 dakika süre geçti o halde
               SN=0              ' saniye s?f?rlan?yor
               DAK=DAK+1         ' dakika de?eri bir art?r?l?yor
               IF DAK>0 AND DAK=1 THEN
               INTCON.5=0:LED=1
               FOR I=0 TO 20
               PAUSE 100
               NEXT I
               LED=0:DAK=0:SN=0:SAYAC=0
                   
               ENDIF
             ENDIF
      ENDIF               
                             
'GOTO CIk   
ENDIF 
T0IF=0                 'kesme bayragi sifirlanacak
RCIF=0   
GIE=1      'Yani INTCON.7=1 kesmeleri açtik.

ENABLE
END

Kişi kesinliklerle başlarsa gideceği yer kuşkulardır, ama kuşkularla başlayacak kadar doygun ise kesinliklere ulaşır.

ete

Bir sürü kusur var programlarda. Bunları daha önce ikaz etmiştim ama hiç kulak asmamışsın.
Hem kendi bildiğini yapıyorsun hemde yeniden yardım istiyorsun bu hiç hoş değil. Öncelikle sana söylenenleri yapman gerekmezmi.

Yeniden ve son olarak kusurları açıklıyorum. Bunları yap yinede çalışmaz ise sistem buraya hemprogramın en son halini hemde simulasyon dosyasını koy bakayım.

Verici programda;
 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 ["R","E","D",VER1,VER2]
HSEROUT ["R","E","D",VER1,VER2]
HSEROUT ["R","E","D",VER1,VER2]
RETURN
END
şeklinde komutlar vermişsin. Komutları birden fazla vermekle fayda değil zarar sağlıyorsun.
Bu kodları aşağıdaki şekilde düzelt.
 GONDER:
HSEROUT [REP$AA\5,REP$00\5,REP$FF\5]'uyandirma sinyali preambl
HSEROUT ["R","E","D",VER1,VER2]
RETURN
END


Alıcıda;
Bir programda CLEAR komutunu kullanırsan bu değişkenlere verilmiş bütün değerleri sıfırlar.
Sen ne yapmışsın.
RCIE=1
PEIE=1
GIE=1
eşitlemelerini yaptıktan sonra CLEAR komutu kullanmışsın.
Madem Clear kullanacaksın değişkenlere değer vermeden önce kullanmalısın.

Bir programda kesme kullanılıyor ise kesinlikle PAUSE komutunu kullanmamalısın. Onun yerine döngü içinde PAUSEUS 1-5 arası bir değer kullanabilirsin. Sebebini belki önce izah etttim. Bir programda kesme oluşturacak bir olay meydana geldiği anda program o anda yürütmekte olduğu basic komutunu bitirdikten sonra ancak kesme etiketine atlar. Pause 2000 gibi bir komut işlenirken kesme oluşursa 2000 ms bekleme süresi bitmeden kesme etiketine gidilemez. Bu ise o anda bir bilgi geliyorsa o bilginin usart da kaybolmasına sebep olur. Bilgi kaçar gider sen alamazsın yani. Bunun yerine Pauseus şeklinde kısa komutlar kullanırsan komut biter bitmez program kesme etiketine atlayabilir. En fazla 1-5 us beklerki bu bilgi kaybına yol açmaz.

Kesme içinde nedense herkes GIE=0 'tüm interruptlari kapat yani INTCON.7=0 şeklinde komut kullanıyor. halbuki DISABLE zaten bu işi yapıyor. Yapılan bir iş için ayrıca bir komut kullanılması gerekmiyor.

Saat palslarını elde etmek için 1/64 bölücü ile sayac değerinin 61 olması beklenir. Sen bölme oranını 1/8 alarak işi tehlikeye sokmuşsun. Böylece sanırım sayac değeri 488 lere çıkmış Hiç gereği olmayan bir tercih. Daha sık kesme oluşturmak bir dezavantajdır. Mümkün olduğunce iki TMR0 kesmesi arasındaki mesafe yeterince uzun olmalıdır. Bu nedenle;
OPTION_REG=%10000101 şeklinde yazılmalı
kesme kısmında ise ;
IF SAYAC=488 then  yerine IF SAYAC=61 THEN  ..... yazılmalıdır.

USART dan bilgi beklenirken HSERIN 1,CIK,[WAIT("RED"),AL1,AL2 ] şeklinde komut içinde yer alan 1 değeri o bekleme için en fazla 1 ms süre tanındığını belirler. 1ms de ne gelirse gelsin alamazsın.  Hele senin gibi bir sürü komut tekarı yapılmış ise hiç alamazsın. Bu nedenle 1 değerini 5 yapmalısın.

Ne hikmetse kesme dığında direk pause komutlarını bol kepçeden kullanmışsın ama kesme içinde hiç gerekli olmadığı halde gecikme komutunu döngü şeklinde kullanmışsın.
Halbuki gecikmeleri döngü şeklinde yapma nedenimiz kesme etiketine hızlı bir şekilde gelebilmek içindir. Zaten kesme etiketinde isek o zaman gecikmeyi döngü şeklinde kullanmanın hiç bir mantığı yoktur. Ama asıl sorun kesme etiketi içinde pasue komutlarının kullanımından kaçınmamız gerektiğidir. Zira kesme içine girdnizmi mümkün olan en kısa sürede oradan çıkmak zorundasınız. Aksi halde muhtemel oluşacak kesmeleri kaçıracağınız anlamına gelir. Kesme içinde yapılacakları kesme dışına taşımak ve bunları yapmakiçin gerekirse bir işaretçi kullanmak gerekir.
Şunlara bir bakalım;
IF DAK>0 AND DAK=1 THEN
               INTCON.5=0:LED=1
               FOR I=0 TO 20
               PAUSE 100
               NEXT I

IF DAK>0 and DAK=1 demek anlamsız. DAK=1 olunca zaten sıfırdan büyük olamayacakmıdır? O halde şöyle yazmak daha doğru olurdu IF DAK=1 THEN
21 adet 100 ms lik gecikme demek 21*100 =2100 ms ve komut gecikmesi ile birlikte bu yaklaşık 2,5 saniyelik bir gecikme demektir. Bu okadar gereklimidir. ? Gerekli ise şöyle yapılamsı daha uygun olur.
IF DAK=1 then
   POZ=1
LED=0:DAK=0:SN=0:SAYAC=0
ENDIF
deyip kesmeden çıkılması gerekir.
Programın normal çalışma kısmında ise

IF POZ=1 then
   POZ=0
   INTCON.5=0:LED=1
   FOR I=0 TO 2500
               PAUSEUS 1
    NEXT I

şeklinde komut kullanmak daha doğru olacaktır.

TMR0 kesmesinin oluşup oluşmadığını anlamak için T0IF=1 olmuşmu bakmak gerekir. Haşbuki sen ne yapmışsın T0IE=1 ise demişsinki bu TMR0 kesme enable bitidirki sen zaten bunu programınbaşında 1 yaptın. O halde bu kısım hep yanlış çalışacaktır. T0IE ifadesini T0IF oalrak düzeltmen gerekiyor.

Hepsi bu kadar.

Ete


toprak

Hocam tüm uyarılarınızla programı ve devreyi yeniden deneyip en kısa zamanda sonucu bildireceğim.
Teşekkürler.
Kişi kesinliklerle başlarsa gideceği yer kuşkulardır, ama kuşkularla başlayacak kadar doygun ise kesinliklere ulaşır.

toprak

#8
Aşağıdaki şekilde denedim. Çalışmadı. Vericide ilk butona basınca alıcıdaki led yanıyor . Ve öylece kalıyor.
Ayrıca pauseus ıle 1mıkrosanıye zaman geçıyor. Ledi 1sn nasıl yaktıracagız pauseus komutuyla dongu kullanarak. çok fazla dongu degerı olması gerekmezmı. pauseus 5 olsa 2000 dongu olsa 10 mılısanıye olur.
@ DEVICE pic16F688 'islemci 16F688
@ DEVICE pic16F688, WDT_OFF 'Watch Dog timer kapali
@ DEVICE pic16F688, PWRT_ON 'Power on timer acik
@ DEVICE pic16F688, PROTECT_OFF 'Kod Protek kapali
@ DEVICE pic16F688, MCLR_OFF 'MCLR pini kullaniliyor.
@ DEVICE pic16F688, XT_OSC   'INTRC_OSC_NOCLKOUT  'Dahili osilator kullanilacak
@ DEVICE pic16F688, BOD_OFF

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

SYMBOL LED=PORTC.3
SYMBOL LAMBA=PORTA.0

SYMBOL GIE  =INTCON.7   'genel interruptlarý açiyor
SYMBOL PEIE =INTCON.6   'peripheral interruptlarý açiyor
SYMBOL RCIE =PIE1.5     'USART Recive interrupt enable bit
SYMBOL RCIF =PIR1.5     'USART ALICI TAMPONU DOLU 1

SYMBOL T0IE =INTCON.5    'TMR0  interrupt enable bit
SYMBOL T0IF =INTCON.2    'TMR0  interrupt flag bit CLEAR

OPTION_REG=%10000101    '1/64
CMCON0=7     
ADCON0=0
ADCON1=0
ANSEL=0
WPUA=0

TRISC=%00100000
PORTC=0
TRISA =%00000000
PORTA=0


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


RCIE=1
PEIE=1
GIE=1

T0IE=0

ON INTERRUPT GOTO KESME


BASLA:
LED=0:LAMBA=0
               
IF SURE=1 THEN
    SURE=0
    INTCON.5=0:LAMBA=1:LED=1
    FOR I=0 TO 2000
    PAUSEUS 1
    NEXT I
    LAMBA=0:LED=0
    ENDIF
   
IF US=1 THEN
    US=0
    IF  AL1=11 AND AL2=72 THEN
        LED=1:SART=1
        GOTO BEKLE
    ENDIF
    IF SART=1 AND AL1=21 AND AL2=82 THEN
       LED=1:T0IE=1
       GOTO BEKLE
    ENDIF
    IF SART=1 AND AL1=31 AND AL2=92 THEN
       LED=1:LAMBA=1
       GOTO BEKLE
    ENDIF
    IF SART=1 AND AL1=51 AND AL2=112 THEN
       LED=1:SART=0
       GOTO BEKLE
    ENDIF
    BEKLE:
    FOR I=0 TO 1000
    PAUSEUS 1
    NEXT I
PAUSEUS 1   
ENDIF

GOTO BASLA

DISABLE
KESME:
GIE=0 'tüm interruptlari kapat yani INTCON.7=0

HSERIN 5,CIK,[WAIT("RED"),AL1,AL2 ]
TEMP=RCREG
US=1

CIK:
IF T0IF=1 THEN
      SAYAC=SAYAC+1      'kesme sayac?  1 sn= 61(sayac) x 256 (Tmr0) x 64 (bölme)
      IF SAYAC=61 then      '61 adet kesme olunca 1 sn. süre geçiyor.(999424 us)
         SAYAC=0             'sayaç s?f?rlan?yor
         SN=SN+1            'saniye de?eri bir art?r?l?yor
            IF SN=60 THEN     'saniye 60 olmu? ise 1 dakika süre geçti o halde
               SN=0           ' saniye s?f?rlan?yor
               DAK=DAK+1       ' dakika de?eri bir art?r?l?yor
               IF DAK=3 THEN
               SURE=1
               LAMBA=0:LED=0:DAK=0:SN=0:SAYAC=0
                   
               ENDIF
             ENDIF
      ENDIF                   
ENDIF 
T0IF=0                 
RCIF=0   
GIE=1                  ' INTCON.7=1 kesmeleri açtik.
RESUME                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 
ENABLE
END







Alıcı



Verıcı
@ DEVICE pic16F688 'islemci 16F688
@ DEVICE pic16F688, WDT_OFF 'Watch Dog timer kapali
@ DEVICE pic16F688, PWRT_ON 'Power on timer acik
@ DEVICE pic16F688, PROTECT_OFF 'Kod Protek kapali
@ DEVICE pic16F688, MCLR_OFF 'MCLR pini kullaniliyor.
@ DEVICE pic16F688, XT_OSC 'Dahili osilator kullanilacak
@ DEVICE pic16F688, 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

VER1 VAR BYTE
VER2 VAR BYTE
I    VAR BYTE
SYMBOL UYANDIRMA=PORTA.2
SYMBOL LED=PORTC.3
SYMBOL BUTON1=PORTC.2
SYMBOL BUTON2=PORTC.1
SYMBOL BUTON3=PORTC.0
SYMBOL BUTON4=PORTA.1

CMCON0=7     
ADCON0=0
ADCON1=0
ANSEL=0
WPUA=0
TRISC=%00000111
PORTC=0
TRISA =%00000010
PORTA=0
                                                   


BASLA:
LED=0
IF BUTON1=0 THEN
VER1=11:VER2=72
UYANDIRMA=1
GOSUB GONDER
UYANDIRMA=0:LED=1
GOTO BEKLE
ENDIF

IF BUTON2=0 THEN
VER1=21:VER2=82
UYANDIRMA=1
GOSUB GONDER
UYANDIRMA=0:LED=1
GOTO BEKLE
ENDIF

IF BUTON3=0 THEN
VER1=31:VER2=92
UYANDIRMA=1
GOSUB GONDER
UYANDIRMA=0:LED=1
GOTO BEKLE
ENDIF

IF BUTON4=0 THEN
VER1=51:VER2=112
UYANDIRMA=1
GOSUB GONDER
UYANDIRMA=0:LED=1
GOTO BEKLE
ENDIF

GOTO BASLA

BEKLE:
FOR I=0 TO 100
PAUSE 5
NEXT I

GOTO BASLA



GONDER:
HSEROUT [REP$AA\5,REP$00\5,REP$FF\5]'uyandirma sinyali preambl
HSEROUT ["R","E","D",VER1,VER2] 
   
RETURN
END

Kişi kesinliklerle başlarsa gideceği yer kuşkulardır, ama kuşkularla başlayacak kadar doygun ise kesinliklere ulaşır.

ete

Denemeyi nerde yapıyorsun gerçek devremi simulasyonmu?
Ayrıca çalışmıyorsa simulasyon dahil programları yolla demiştim.
Devreyi önce simulasyonda çalıştırmak gerekir. Çalışıyorsa gerçek devreye geçersin.

Ete

ete

Çalışmaması normal. Bir programda İki ayrı kesme kaynağı var ise mantıklı davranmak adına bunalrın hangisine bağlı kesme oluştuğunu önce bulmak ve ona göre de oluşan kesmeye ait programı çalıştırma diğerini çalıştırmamak gerekir. Bunu düşünmen gerekir öyle değilmi. Peki sen ne yapmışsın;
KESME:
GIE=0 'tüm interruptlari kapat yani INTCON.7=0

HSERIN 5,CIK,[WAIT("RED"),AL1,AL2 ]
TEMP=RCREG
US=1

CIK:
IF T0IF=1 THEN
      SAYAC=SAYAC+1      'kesme sayac?  1 sn= 61(sayac) x 256 (Tmr0) x 64 (bölme)
      IF SAYAC=61 then      '61 adet kesme olunca 1 sn. süre geçiyor.(999424 us)
         SAYAC=0             'sayaç s?f?rlan?yor
         SN=SN+1            'saniye de?eri bir art?r?l?yor
            IF SN=60 THEN     'saniye 60 olmu? ise 1 dakika süre geçti o halde
               SN=0           ' saniye s?f?rlan?yor
               DAK=DAK+1       ' dakika de?eri bir art?r?l?yor
               IF DAK=3 THEN
               SURE=1
               LAMBA=0:LED=0:DAK=0:SN=0:SAYAC=0
                   
               ENDIF
             ENDIF
      ENDIF                   
ENDIF 
T0IF=0                 
RCIF=0   
GIE=1                  ' INTCON.7=1 kesmeleri açtik.
RESUME                                         
ENABLE

Bu kodlarda HESERIN komut satırı hangi kesme oluşursa oluşsun çalışmaya zorlanıyor. Bu mantıklımı sence? halbuki Usart kesmesi oluşmuş ise bu satır çalışmalı.
İki kesmeden birisi kontrol edilerek diğerine gerek kalmadan işi kolaylıkla halletmek mümkün . Bak bakalım aşağıdaki satırlar sana ne söylüyor?.
DISABLE
KESME:
GIE=0 'tüm interruptlari kapat yani INTCON.7=0
IF T0IF=1 THEN KESBIR    'TMR0 kesmesi oluşmuş ise  KESBIR etiketine git
HSERIN 5,CIK,[WAIT("RED"),AL1,AL2 ]  'USART kesmesi ise buradan devam et
TEMP=RCREG
US=1
RCIF=0  'USART kesme bayrağını burada sıfırla çünki kesme oluşmuş ise sıfırlanacak
GOTO CIK

KESBIR:
      SAYAC=SAYAC+1      'kesme sayac?  1 sn= 61(sayac) x 256 (Tmr0) x 64 (bölme)
      IF SAYAC=61 then      '61 adet kesme olunca 1 sn. süre geçiyor.(999424 us)
         SAYAC=0             'sayaç s?f?rlan?yor
         SN=SN+1            'saniye de?eri bir art?r?l?yor
            IF SN=60 THEN     'saniye 60 olmu? ise 1 dakika süre geçti o halde
               SN=0           ' saniye s?f?rlan?yor
               DAK=DAK+1       ' dakika de?eri bir art?r?l?yor
               IF DAK=3 THEN
               SURE=1
               LAMBA=0:LED=0:DAK=0:SN=0:SAYAC=0
             ENDIF         
       ENDIF
       T0IF=0  'TMR0 kesme bayrağınıda burada sıfırla   
CIK:               
GIE=1                  ' INTCON.7=1 kesmeleri açtik.
RESUME                                                         
ENABLE


Gecikme alt programını GOSUB ile gidilecek şekilde ayarlarsan istediğin gecikmelere bağlı olarak uygun süreler yaratabilirsin.
Mesela;
OnMilisn:
FOR I=0 to 2000
  PAUSEUS 1
Next
RETURN
Bu gecikmeyi kullanmak için GOSUB OnMilisn demen yeterlidir. Program oraya gider komutları çalıştırır ve Return komutunu görünce tekrar geldiği yere ve gelmesine sebep olan komutun bir alt satırına geçer.
Ayrıca bir tande 100 ms lik gecikme alt programı oluştır;
Yuzms:
For I=0 to 8000
  Pauseus 1
next
Return

Programı buraya Gosub Yuzms komutu ile yollarsan program orada bekler ve geri döner.
Verdiğim döngü değerleri gerçek değerler değildir. Biraz deneme yaparak uygun değerleri tespit edebilirsin.
Pauseus 1  normalde 1 mikrosaniyelik gecikme yaratır. Ancak bunu döngü ile birlikte kullanırsan döngünün komut gecikmeleride devreye girer ve gerçekte bekleme 1us den daha fazla olur. Mesela 0 to 2000 lik değer teorik hesaplamda 200us lik bir gecikme yapar gibi gözüksede gerçekte 10 ms dolaylarında bir gecikmeye sebep olur. Bu nedenle gerçek süreleri deneyerek bulabilirsin. Senin programıonda süreler çokda önemli değil görsel olarak tatmin olursan o senin işine yarayacak bir gecikme demektir.
Sonuçta benzer şekilde değişik gecikme rutinleri yaratarak istediğin gecikmeleri sağlayabilirsin.
Bir döngüde Pauseus 1 yerine Pauseus 5 kullan. Hatta alt alta birden fazla Pauseus 5 komutu kullanarak dngüsel süreyi dahada uzatabilirsin.
Mesela;
For I=0 to 65500
  Pauseus 5
  Pauseus 5
  Pauseus 5
  Pauseus 5
Next
gibi bir alt program sana epeyce uzun bir gecikme yaratabilir. Tek seferlik gecikme yaklaşık 20us ama komut gecikmeleri ile bu neredeyse 100us olabilir. Bunu 65500 defa çalıştırınca 6 550 000 us yada 6550ms veya 6,5 saniyelik bir gecikme sağlar.
Olaya kesme oluşturma açısından bakarsak en büyük gecikme süresi 5us olduğu için program her halukarda 5us içinde kesmeye atlayabilir. Buda bizim işimize yeterli bir süredir öyle değilmi.
Gosub ile gidilen alt programlardan mutlaka RETURN ile dönülmelidir. Program nereden geldiğini bilir ve oraya geri döner. Senin takip etmen gerekmez. Ama Return yerine Goto xxxx dersen program kilitlenir. Stack denilen ve gidilen adreslerin kaydının tutulduğu ara hafıza anında dolar ve program nerden geldiğini neryee gideceğini unutur ve şaşırıp kilitlenir.
Bir defa Gosub kullanıp gittiğin yerde yeniden bir gosub kullanabilirsin ama sayısı 3'ü geçmemelidir. Bazı işlemcilerde bu 5 veya daha fazlasına çıkabilir ama şimdilik sen 3 den fazla iç içe geçmiş Gosub Kullanma.
Başka bir şey çıkıncaya kadar diyeceklerim bunlardan ibaret. Yeniden çalışmaya devam et bakalım ne zaman başaracaksın.
Sona doğru gidiyoruz merak etme.

Ete

toprak

#11
Yukaridaki şekilde kesme yapınca tımer0 çalıştığı zaman usart kesmesı işler mi. Yani zamanı durdurabilirmiyiz.

Programı hem simülasyonda denedim hem de 4MHz XT kristal kullanılan gerçek devrede denedim
Simülasyonda açabiliyor yakabiliyor ve kapatabiliyorum
Fakat zaman saymıyor

Gerçekte ise hiçbirşey yapmıyor.
Bazen enerji verir vermez led ve lamba birlikte yanıyor.

Hocam gerçekten anlayamadım. Neden çalışmıyor.

Programların son hali

Alıcı
@ DEVICE pic16F688 'islemci 16F688
@ DEVICE pic16F688, WDT_OFF 'Watch Dog timer kapali
@ DEVICE pic16F688, PWRT_ON 'Power on timer acik
@ DEVICE pic16F688, PROTECT_OFF 'Kod Protek kapali
@ DEVICE pic16F688, MCLR_OFF 'MCLR pini kullaniliyor.
@ DEVICE pic16F688, XT_OSC   'INTRC_OSC_NOCLKOUT  'Dahili osilator kullanilacak
@ DEVICE pic16F688, BOD_OFF

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

SYMBOL LED=PORTC.3
SYMBOL LAMBA=PORTA.0

SYMBOL GIE  =INTCON.7   'genel interruptlarý açiyor
SYMBOL PEIE =INTCON.6   'peripheral interruptlarý açiyor
SYMBOL RCIE =PIE1.5     'USART Recive interrupt enable bit
SYMBOL RCIF =PIR1.5     'USART ALICI TAMPONU DOLU 1

SYMBOL T0IE =INTCON.5    'TMR0  interrupt enable bit
SYMBOL T0IF =INTCON.2    'TMR0  interrupt flag bit CLEAR

OPTION_REG=%10000101    '1/64
CMCON0=7     
ADCON0=0
ADCON1=0
ANSEL=0
WPUA=0

TRISC=%00100000
PORTC=0
TRISA =%00000000
PORTA=0


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


RCIE=1
PEIE=1
GIE=1

T0IE=0

ON INTERRUPT GOTO KESME

BASLA:
LED=0:LAMBA=0
               
IF SURE=1 THEN
    SURE=0
    INTCON.5=0:LAMBA=1:LED=1
    GOSUB BIRSN
    LAMBA=0:LED=0
    ENDIF
   
IF US=1 THEN
    US=0
    IF  AL1=11 AND AL2=72 THEN
        LED=1:SART=1
        GOSUB BIRSN
    ENDIF
    IF SART=1 AND AL1=21 AND AL2=82 THEN
       LED=1:T0IE=1
       GOSUB BIRSN
    ENDIF
    IF SART=1 AND AL1=31 AND AL2=92 THEN
       LED=1:LAMBA=1
       GOSUB BIRSN
    ENDIF
    IF SART=1 AND AL1=51 AND AL2=112 THEN
       LED=1:SART=0
       GOSUB BIRSN
    ENDIF   
ENDIF

GOTO BASLA
BIRSN:
    FOR I=0 TO 10000
    PAUSEUS 5
    NEXT
    RETURN
   
DISABLE
KESME:
GIE=0
                 'tüm interruptlari kapat  INTCON.7=0
IF T0IF=1 THEN KESBIR
HSERIN 5,CIK,[WAIT("RED"),AL1,AL2 ]
TEMP=RCREG
US=1
RCIF=0
GOTO CIK

KESBIR:

      SAYAC=SAYAC+1      'kesme sayac?  1 sn= 61(sayac) x 256 (Tmr0) x 64 (bölme)
      IF SAYAC=61 then      '61 adet kesme olunca 1 sn. süre geçiyor.(999424 us)
         SAYAC=0             'sayaç s?f?rlan?yor
         SN=SN+1            'saniye de?eri bir art?r?l?yor
            IF SN=60 THEN     'saniye 60 olmu? ise 1 dakika süre geçti o halde
               SN=0           ' saniye s?f?rlan?yor
               DAK=DAK+1       ' dakika de?eri bir art?r?l?yor
               IF DAK=1 THEN
               SURE=1
               LAMBA=0:LED=0:DAK=0:SN=0:SAYAC=0
               ENDIF
             ENDIF
      ENDIF                   
T0IF=0

CIK:                   
GIE=1                  ' INTCON.7=1 kesmeleri açtik.
RESUME                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   
ENABLE
END



verıcı
@ DEVICE pic16F688 'islemci 16F688
@ DEVICE pic16F688, WDT_OFF 'Watch Dog timer kapali
@ DEVICE pic16F688, PWRT_ON 'Power on timer acik
@ DEVICE pic16F688, PROTECT_OFF 'Kod Protek kapali
@ DEVICE pic16F688, MCLR_OFF 'MCLR pini kullaniliyor.
@ DEVICE pic16F688, XT_OSC 'Dahili osilator kullanilacak
@ DEVICE pic16F688, 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

VER1 VAR BYTE
VER2 VAR BYTE
I    VAR BYTE
SYMBOL UYANDIRMA=PORTA.2 
SYMBOL LED=PORTC.3
SYMBOL BUTON1=PORTC.2
SYMBOL BUTON2=PORTC.1
SYMBOL BUTON3=PORTC.0
SYMBOL BUTON4=PORTA.1

CMCON0=7     
ADCON0=0
ADCON1=0
ANSEL=0
WPUA=0
TRISC=%00000111
PORTC=0
TRISA =%00000010
PORTA=0
                                                   
 
BASLA:
LED=0
IF BUTON1=0 THEN
VER1=11:VER2=72
UYANDIRMA=1
GOSUB GONDER
UYANDIRMA=0:LED=1
GOSUB BEKLE
ENDIF

IF BUTON2=0 THEN
VER1=21:VER2=82
UYANDIRMA=1
GOSUB GONDER
UYANDIRMA=0:LED=1
GOSUB BEKLE
ENDIF

IF BUTON3=0 THEN
VER1=31:VER2=92
UYANDIRMA=1
GOSUB GONDER
UYANDIRMA=0:LED=1
GOSUB BEKLE
ENDIF

IF BUTON4=0 THEN
VER1=51:VER2=112
UYANDIRMA=1
GOSUB GONDER
UYANDIRMA=0:LED=1
GOSUB BEKLE
ENDIF

GOTO BASLA

BEKLE:
FOR I=0 TO 100
PAUSE 5
NEXT I
RETURN


GONDER:
HSEROUT [REP$AA\5,REP$00\5,REP$FF\5]
HSEROUT ["R","E","D",VER1,VER2] 
   
RETURN
END
Kişi kesinliklerle başlarsa gideceği yer kuşkulardır, ama kuşkularla başlayacak kadar doygun ise kesinliklere ulaşır.

ete

Programda çok fazla işaret biti kullanmışsın bütün sorun onlardan kaynaklanıyor.
Üşenmedim bir simulasyon devresi çizdim. Çalıştırdım. Hemen belirteyim Verici tarafı kusursuz çalışıyor.
Ama alıcı tarafında bir sürü şart var. Ben bile işin içinden çıkamadım.
Ne verildiğini ve ne alındığını görebiliyorum. Şartları kaldırırsam her şey sorunsuz çalışıyor.
Bu şart bitlerini doğru düzenlemek için bana açıklama vermen gerekiyor.
Kim ne olunca led yanacak , lamba yanacak yada saat çalışacak.
Mademki bir saat çalışıyor o zaman ledlerin yanıp sönmesi için o saatleri kullanabilirsin.
Sen açıklamanı verki bende ona göre düşüneyim.
Bana kalırsa programa bakarak açıklama verme.
Açıklamana Verici tarafındaki butonlardan başla.
Buton isimlerini esas alarak;
Buton1 e basılınca karşı tarafta ne olacak?
Buton2 ye basılınca karşıda ne olacak
Buton3 e basılınca karşıda ne olacak
Buton4 e basılınca karşıda ne olacak.

Başka şartlar varsa onlarıda açıkla.
Ete

toprak

Buton1 e basılınca alıcıda lambayı direkt veya zaman sonunda yakmak için şart sağlanmış olacak. Şart 1 olmazsa lambayı yakamayız.Buton 2 ve buton 3 bu şarta bağlı

Buton2 ye basınca (şart 1 iken) alıcıda zaman saymaya başlayacak . zaman sonunda lamba yanacak.

Buton3 e basınca(şart 1 iken) alıcıda lamba direkt yakılabilecek.

Buton4 e basınca alıcıdaki şart 0 olacak. Zaman durdurulabilecek. Tekrar buton1 e basılıncaya kadar buton2 ve buton3e bassak da işlem olmayacak.

Led her işlemde hem vericide hem alıcıda yakılıp söndürülüyor.
Kişi kesinliklerle başlarsa gideceği yer kuşkulardır, ama kuşkularla başlayacak kadar doygun ise kesinliklere ulaşır.

ete

#14
Aslında çözmüştüm. Neyse durum şu;
Buton numarasına göre sıra ile basılırsa sistem 2. butondan itibaren saat saymaya başlıyor.
Ancak programda bir eksiklik var. Buda her alış işleminden sonra AL1 ve AL2 değerlerine göre işlem yapılacak ancak işlemden sonra AL1 ve AL2 değerlerini sıfırlamak gerekiyor. Sıfırlamaz isen o veriyi yeni almış gibi yeniden işliyor program. Böylece aynı iş sürekli olarak yeniden yapılıyor. Bu nedenle sıfırlama komutunu yalnızca bir kere yazabilmek amacı ile onu BIRSN alt programının en sonuna yazmak gerekiyor.
Böylece sistem artık doğru çalışmaya başlayacaktır.
Programları ve simulasyon devresini ilişikte veriyorum. Çalıştırınca şayet Watch window çıkmaz ise İsis de yukarıda DEBUG seçeneğini seç ve açılan pencerede aşağıda watch Window seçeneğine tıkla. Böylece orada alınan verilen ve saat sayaclarını görebilirsin.

Ete

Edit: Son yazdığın şart açıklamalarına göre yine eksikler veya farklılıklar olduğunu görüyorum. Mesela Alıcı programda en başta ;
BASLA:
LED=0:LAMBA=0
satırları her durumda lambalar yanıyor ise söndürecektir. Buton3 e basılınca bu komut varken nasıl lamba yanık kalacak?
Ayrıca Buton4 saat sayma işini iptal etmesi gerek buna ait bir komut koyulmamış Yalnızca süre dolduğunda saat sayması iptal ediliyor. Programın mantığına hakim olmayınca neyin doğru olduğuna karar veremiyorum. Kendin bu sorunları gidermeye çalış. Yapamaz isen adım adım yardım iste.

Powered by EzPortal