Seri İletişim ve TMR0 Kesmesi Sorunu

Başlatan erdemefe, 29 Ekim 2012, 02:42:03

erdemefe

Arkadaşlar 2 adet F628 kullanarak -50 ile 99.9 derece arasında çalışan kablosuz bir termometre projesi yaptım devre simulasyonda da gerçekte de çalışıyor fakat geliştirmeye çalıştıkça sorunlar çıkıyor. Devrede 5 tane 74hc575 ile 5 tane display sürdüm vericide DS18B20 kullandım seri iletişimide USART ile hallettim. Şimdi devreye 2. bir kablolu sensör eklemek istiyorum 5 sn kablosuz sensör 5 sn kablolu sensörden gelen bilgiyi ekrana yazması için ilk olarak saniye palslerini yakalamak için TMR0 kesmesi kullanmak istedim fakat benim hesapladığım 1 saniye hem gerçekte hem simulasyonda 7 saniyeye denk geliyor hesabım ise şu şekilde 1/64 TMR0 için bölme oranı 1uS*64*255=16,32mS yapıyor 1000mS/16,32mS=61 yapıyor her 61 kesmede snyi 1 artırıyorum fakat gerçekte de simulasyonda da 7-8 saniye sürüyor. 2. bir sorun da HSERIN 2000,ERROR,[WAIT ("EFE"),ISI.LOWBYTE,ISI.HIGHBYTE,ISARETB] komutu ile alakalı, sıcaklık bilgisi 2 SN boyunca ERROR etiketine gitsin istiyorum (ERROR etiketinde ekrana error yazacak) simulasyonda aynen oluyor fakat gerçekte vericinin beslemesini kestiğimde en son ne bilgi gelmişse orada çakılıp kalıyor hatta vericiyi çalıştırmadan alıcıyı açtığımda displaylerde hiçbirşey yazmıyor

'****************************************************************
'*  Name    : UNTITLED.BAS                                      *
'*  Author  : ERDEM EFE                                         *
'*  Notice  : Copyright (c) 2012 [select VIEW...EDITOR OPTIONS] *
'*          : All Rights Reserved                               *
'*  Date    : 10/29/2012                                        *
'*  Version : 1.0                                               *
'*  Notes   :                                                   *
'*          :                                                   *
'****************************************************************
'@ DEVICE PIC16F628A                      'işlemci 16F628                               
'@ DEVICE PIC16F628A, WDT_ON              'Watch Dog timer açık
'@ DEVICE PIC16F628A, PWRT_ON             'Power on timer açık
'@ DEVICE PIC16F628A, PROTECT_OFF         'Kod Protek kapalı
'@ DEVICE PIC16F628A, MCLR_OFF            'MCLR pini kullanılMIYOR.
'@ DEVICE PIC16F628A, INTRC_OSC_NOCLKOUT  'Dahili osilatör kullanılacak
'-------------------------------------------------------------------------------
DEFINE OSC 4                ' OSILATOR 4Mhz
DEFINE HSER_BAUD 2400       ' 2400 BAUD
INCLUDE "modedefs.bas"      ' SERI ILETISIM DAHIL ET
'-------------------------------------------------------------------------------
TRISA=%00000001             ' PORTA.0 GIRIS DIGERLERI CIKIS
TRISB=%00000000             ' B PORTLARI CIKIS
CMCON=7                     ' COMPARATOR IPTAL
OPTION_REG=%10000000        ' PULLUP DIRECLERI IPTAL
INTCON=%00000000            ' KESME YOK
'-------------------------------------------------------------------------------
SYMBOL DQ=PORTA.0           ' DS18B20 PINI
'-------------------------------------------------------------------------------
ISI     VAR WORD
HAM     VAR WORD
TEMP    VAR WORD
BUSY    VAR WORD                 
ISARET  VAR HAM.BIT11
'-------------------------------------------------------------------------------
PORTA=0
PORTB=0
'-------------------------------------------------------------------------------
BASLA:

           OWOUT   DQ, 1, [$CC, $44]' ISI değerini oku
BEKLE:
           OWIN    DQ, 4, [BUSY]    ' Busy değerini oku
           IF      Busy = 0 THEN Bekle    ' hala meşgulmü? , evet ise goto Bekle..!
           OWOUT   DQ, 1, [$CC, $BE]' scratchpad memory oku
           OWIN    DQ, 2, [HAM.Lowbyte, HAM.Highbyte]' İki byte oku ve okumayı bitir.
           GOSUB   Hesapla
    GOSUB GONDER
    GOTO BASLA
     
HESAPLA:                 ' Ham değerden Santigrat derece hesabı
IF ISARET=1 THEN
    TEMP=($FFFF - HAM+1)*625
    ISI = DIV32 100
    GOTO GEC
Endif
TEMP = 625 * HAM '
ISI = DIV32 100 ' Div32 hassas derece hesabı için 32 bit bölme yapıyoruz.
GEC:
ISI=ISI/10

    RETURN
   


GONDER:
    hserout [REP$AA\5,REP$00\5,REP$FF\5]
    HSERout [("E"),("F"),("E"),ISI.LOWBYTE,ISI.HIGHBYTE,ISARET]
    HSERout [("E"),("F"),("E"),ISI.LOWBYTE,ISI.HIGHBYTE,ISARET]
    HSERout [("E"),("F"),("E"),ISI.LOWBYTE,ISI.HIGHBYTE,ISARET]
    HSERout [("E"),("F"),("E"),ISI.LOWBYTE,ISI.HIGHBYTE,ISARET]
    HSERout [("E"),("F"),("E"),ISI.LOWBYTE,ISI.HIGHBYTE,ISARET]
    RETURN
    END


'****************************************************************
'*  Name    : UNTITLED.BAS                                      *
'*  Author  : ERDEM EFE                                         *
'*  Notice  : Copyright (c) 2012 [select VIEW...EDITOR OPTIONS] *
'*          : All Rights Reserved                               *
'*  Date    : 10/29/2012                                        *
'*  Version : 1.0                                               *
'*  Notes   :                                                   *
'*          :                                                   *
'****************************************************************
'@ DEVICE PIC16F628A                      'işlemci 16F628                               
'@ DEVICE PIC16F628A, WDT_ON              'Watch Dog timer açık
'@ DEVICE PIC16F628A, PWRT_ON             'Power on timer açık
'@ DEVICE PIC16F628A, PROTECT_OFF         'Kod Protek kapalı
'@ DEVICE PIC16F628A, MCLR_OFF            'MCLR pini kullanılMIYOR.
'@ DEVICE PIC16F628A, INTRC_OSC_NOCLKOUT  'Dahili osilatör kullanılacak
'-------------------------------------------------------------------------------
DEFINE OSC 4                ' OSILATOR 4Mhz
DEFINE HSER_BAUD 2400       ' 2400 BAUD
INCLUDE "modedefs.bas"      ' SERI ILETISIM DAHIL ET
'-------------------------------------------------------------------------------
TRISA=%00000000             ' A PORTLARI CIKIS
TRISB=%00000010             ' PORTB.1 GİRİŞ
CMCON=7                     ' COMPARATOR IPTAL
OPTION_REG=%10000101        ' PULLUP IPTAL 1/64 BÖLME ORANI 16.32msDE BIR KESME
INTCON=%10100000            ' TMR0 KESMESI AKTIF
'------------------------------------------------------------------------------
symbol CLK=PORTA.0          ' 74HC595 CLOCK PINI=SH-CP
'symbol CLK=PORTA.7         ' 74HC595 CLOCK PINI=SH-CP
SYMBOL LD=PORTA.1           ' 74HC595 LATCH PINI=ST-CP
'SYMBOL LD=PORTA.6          ' 74HC595 LATCH PINI=ST-CP
SYMBOL DT=PORTB.7           ' 74HC595 DATA PINI=DS
SYMBOL DQ=PORTA.2           ' DS18B20 DATA PINI
'-------------------------------------------------------------------------------
SAYI        VAR WORD
X           VAR BYTE
ISI         var WORD
ISARETB     VAR BIT
SAYAC       VAR WORD
FLAG        VAR BIT
SN          VAR BYTE
'-------------------------------------------------------------------------------
PORTA=0
PORTB=0
FLAG=0
TMR0=0
SAYAC=0
'-------------------------------------------------------------------------------
on interrupt goto KESME
'-------------------------------------------------------------------------------
BASLA:

HSERIN 2000,ERROR,[WAIT ("EFE"),ISI.LOWBYTE,ISI.HIGHBYTE,ISARETB]   'SICAKLIĞI VE İŞARET BİTİNİ AL

IF FLAG=0 THEN              'FLAG 0 IKEN 
ISI=ISI                     'SICAKLIK OKUNAN SICAKLIK
ELSE                        'FLAG 1 İKEN
ISI=367                     'SICAKLIK 367 (36.7 DERECE) (DENEME AMAÇLI OLARAK)
ENDIF

IF ISARETB=0 THEN           'SICAKLIK POZİTİFSE
        IF ISI>999 THEN     '99.9 DERECEDEN BÜYÜKSE
        ISI=999             '99.9 DERECE ÇÜNKÜ 3 HANE KULLANIYORUZ
        GOTO HOT            'EKRANA HOT YAZ
        ENDIF
GOTO ARTI                   'POZİTİF SICAKLIK YAZMA ETIKETİNE GİT
ENDIF

IF ISARETB=1 THEN           'İŞARET NEGATİFSE
    IF ISI>500 THEN         '50.0 DERECEDEN BÜYÜKSE
    ISI=500                 '50.0 DERECE
    GOTO COLD               'EKRANA COLDD YAZ
    ENDIF
GOTO EKSI                   'NEGATİF SICAKLIK YAZMA ETİKETİNE GİT
ENDIF
'-------------------------------------------------------------------------------
ARTI:
x=11          : gosub al                                'C İŞARETİNİ AL
IF FLAG=1 THEN                                          'FLAG 1 IKEN
SAYI.BIT7=1                                             'NOKTAYI YAK
ENDIF                                                   ' C ISARETI(FLAG 1 IKEN C HARFININ NOKTASI YANSIN)
gosub yaz                                               
x=10          : gosub al : gosub yaz                    ' DERECE ISARETI
x=ISI dig 0   : gosub al : GOSUB YAZ                    ' ISI VIRGULDEN SONRASI
x=ISI dig 1   : gosub al : SAYI.BIT7=1: GOSUB YAZ       ' NOKTA
IF ISI>99 THEN                                           
x=ISI dig 2   
gosub al : GOSUB YAZ
ELSE
SAYI=0 : gosub yaz : ENDIF ' SICAKLIK 9.9 DERECEN KÜÇÜKSE 1. DISPLAY SÖNSÜN
PULSOUT LD,1
GOTO BASLA
'-------------------------------------------------------------------------------
EKSI:
x=11          : gosub al : gosub yaz                    ' C ISARETI
x=10          : gosub al : gosub yaz                    ' DERECE ISARETI
IF ISI<100 THEN                                         ' ISI 100DEN KÜÇÜKSE (10.0'DAN)
x=ISI dig 0   : gosub al : GOSUB YAZ                    ' ISI VIRGULDEN SONRASI
x=ISI dig 1   : gosub al : SAYI.BIT7=1: GOSUB YAZ       'NOKTA ve ISININ TAM KISMI
ENDIF
IF ISI>99 THEn                                          'ISI 99'DAN BÜYÜKSE (9.9'DAN)
x=ISI dig 1   : gosub al : GOSUB YAZ                    'BİRLER BASAMAĞI
x=ISI dig 2   : gosub al : GOSUB YAZ                    'ONLAR BASAMAGI
ENDIF
X=12          : gosub al : GOSUB YAZ                    ' - ISARETI
PULSOUT LD,1
GOTO BASLA 
'-------------------------------------------------------------------------------
HOT:
SAYI=0                   : GOSUB YAZ                    ' BOS
SAYI=0                   : GOSUB YAZ                    ' BOS
X=16          : gosub al : gosub yaz                    ' t HARFI
X=15          : gosub al : gosub yaz                    ' o HARFI
X=17          : gosub al : gosub yaz                    ' h HARFI
PULSOUT LD,1
GOTO BASLA
'-------------------------------------------------------------------------------
COLD:
SAYI=0                   : GOSUB YAZ                    ' BOS
X=18          : gosub al : gosub yaz                    ' d HARFI
X=19          : gosub al : gosub yaz                    ' l HARFI
X=15          : gosub al : gosub yaz                    ' o HARFI
X=20          : gosub al : gosub yaz                    ' c HARFI
PULSOUT LD,1
GOTO BASLA
'-------------------------------------------------------------------------------
ERROR:
X=14          : gosub al : gosub yaz                    ' r HARFI
X=15          : gosub al : gosub yaz                    ' o HARFI
X=14          : gosub al : gosub yaz                    ' r HARFI
X=14          : gosub al : gosub yaz                    ' r HARFI
X=13          : gosub al : gosub yaz                    ' E HARFI
PULSOUT LD,1
GOTO BASLA
'-------------------------------------------------------------------------------
AL:   
LOOKUP X,[63,6,91,79,102,109,125,7,127,111,99,57,64,121,80,92,120,116,94,48,88],SAYI
         '0 ,1,2 ,3 , 4 , 5 , 6 ,7, 8 , 9 ,o ,C ,- , E ,r ,o , t , h ,d ,  , c
RETURN     
'-------------------------------------------------------------------------------
YAZ:
shiftout dt,clk,1,[sayi] : RETURN       '74HC595LERE VERIYI YAZ
'-------------------------------------------------------------------------------

DISABLE                     'KESME İÇİNDE KESME OLUŞMASIN
KESME:
SAYAC=SAYAC+1               'SAYACI ARTIR, HER ARTMASI 16.32ms

IF SAYAC >=61 THEN          'SAYAC 61 OLDUYSA 995ms YAKLAŞIK 1SN
SAYAC=0                     'SAYACI SIFIRLA
SN=SN+1                     'SANİYEYİ 1 ARTIR
    IF SN=5 THEN            'SANİYE 5 OLDUYSA
    SN=0                    'SANIYEYİ SIFIRLA
    TOGGLE FLAG             'FLAG 1 DEN 0 0DAN 1 OLSUN
    ENDIF
ENDIF
   
INTCON.2=0                  'TMR0 FLAGİ SIFIRLA
RESUME                      'GELDİĞİN YERE GİT
ENABLE                      'KESMELER AKTIF
'-------------------------------------------------------------------------------
END

ete

Bu tür programlarda USART kesmesi kullanılmaz ise program zorunlu olarak her çevrimde HESERIN komutunu çalıştırır.
Bu durumda oraya yerleştirilen 2000 timeout değeri işleme konur ve program orada 2 sn süre ise çakılır kalır. Buda kesme oluşumunda soruna sebep olur.
Hem neden error yazdırma gereğini duyuyorsun. ?
Ben olsam USART kesmesi kullanırdım böylece programı gereksiz meşgul etmezdim. Verici sıcaklık bilgisi yollayınca alır ekrana verirdim.

SN sayacı kesme kısmında sıfırlanırsa değişikliği diğer taraf nasıl agılayacak? bu rasıda mantık olarak yanlış.
Yapılması gerekenler şunlar;
BASLA satırından sonrakiler
1. HSERIN 5,ERROR,[WAIT ("EFE"),ISI.LOWBYTE,ISI.HIGHBYTE,ISARETB]   'SICAKLIĞI VE İŞARET BİTİNİ AL
    HATA=0

2. IF SN>4 then
ISI=367                     'SICAKLIK 367 (36.7 DERECE) (DENEME AMAÇLI OLARAK)
If sn=10 then sn=0
ENDIF

3.Kesme kısmında
IF SAYAC >=61 THEN          'SAYAC 61 OLDUYSA 995ms YAKLAŞIK 1SN
SAYAC=0                     'SAYACI SIFIRLA
SN=SN+1                     'SANİYEYİ 1 ARTIR
ENDIF

4. ERROR kısmında baş tarafa şunları ilave et.
HATA=HATA+1 , if hata <200 THEN BASLA
HATA=0

Böylece hata sayacı hataları sayar şayet 200 dan fazla ise gerçekten veri gelmiyor demektir ve hata mesajını verir. Değilse çalışmaya devam eder.

Ete



erdemefe

hocam cevabınız için çok teşekkür ederim peki usart kesmesi nedir nasıl çalışır avantajı nedir bunlardan bahsedebilrimisiniz. eğer daha verimli birşey olacaksa USART kesmesi kullanırım

ete

Kesme nin ne olduğunu biliyorsun sanırım. Usart kesmesi de seri porta bir veri geldiği zaman kesme oluşması sonucu işlemcinin gidip o veriyi okumasıdır. Böylece programın hemen başına heserin diye bir komutmkoymazsın. Kesme kısmına bu komutu koyarsın. Böylece programın boşuna gelmeyecek olan verileri beklemez kendi işine bakar.
Örnekler sitede var. Biraz eşele bakalım.
Ete

erdemefe

#4
Hocam şimdilik error etiketine gitmekten vazgeçtim veri alırken saniyeyi saydırmaya çalışıyorum hem USART hem de TMR0 kesmesini kullanmaya çalıştım usart çalışırken TMR0'ın çalıştığına ait bir ummare bulamadım. yaptığım değişiklikler


DEFINE HSER_BAUD 2400       ' 2400 BAUD
DEFINE HSER_RCSTA 90h
DEFINE HSER_CLROERR 1
OPTION_REG=%10000101        ' PULLUP IPTAL 1/64 BÖLME ORANI 16.32msDE BIR KESME
INTCON=%11100000            ' TMR0 KESMESI AKTIF ÇEVRESEL KESMELER AKTİF
SYMBOL RCIE =PIE1.5     'USART ENABLE
SYMBOL RCIF =PIR1.5     'USART FLAG
SYMBOL T0IF=INTCON.2    'TMR0 FLAG BIT
on INTERRUPT GOTO KESME
RCIE=1

DISABLE
KESME:
IF RCIF=0 THEN GOTO TMR00
HSERIN [WAIT ("EFE"),ISI.LOWBYTE,ISI.HIGHBYTE,ISARETB]   'SICAKLIĞI VE İŞARET BİTİNİ AL
GOTO KESME_CIK

TMR00:
IF T0IF=0 THEN GOTO KESME_CIK
SAYAC=SAYAC+1
    IF SAYAC=61 THEN
    SAYAC=0
    SN=SN+1
        IF SN=2 THEN
        TOGGLE FLAG
        FLAG=PORTB.5
        SN=0
        ENDIF
    ENDIF


GOTO KESME_CIK

KESME_CIK:
RCIF=0
T0IF=0
RESUME
ENABLE

END


Hocam burada her 2 sn'de bir kendi oluşturduğum flag bitini yani RB5'i set reset etmeye çalıştım

ete

İlişikte benim yaptığım tadilata bağlı olarak sistemin çalışmasını ve isis de "watch window" da hem INTCON hemde SN değerini izleyerek kesme oluştuğunu gözlemleyebilirsin.
Bu programlar senin istediğin gibi çalışıyor işte.

Ete

erdemefe

#6
Hocam yardımlarınız için çok teşekkür ederim vizeler yüzünden bir süre proje ile ilgilenemdim bu ara müsait oldum biraz daha uğraştım bu arada hocamla görüştüm bu projeyi 2. dönem bitirme projesi olarak yapacağım.

Devreye 2. kablolu bir sensörü ekledim kablolu sensörden gelen ısı ve işaret bilgilerini ISIA ve ISARETA değişkenlerinde tuttum, kablosuz sensörden gelen bilgileri de ISIB ve ISARETB değişkenlerinde tutup ekrana yazdırdım bir FLAG biti tanımlayıp bit 0 iken ekrana yazılacak ısı bilgisini ISIA ve ISARETA'dan 1 iken ISIB ve ISARETB'den gelmesini sağladım. ekranda yazdırılırken hangi sensörden bilgi geldiğini anlamak amacıyla kablosuz sensörden gelen bilgi yazdırılırken en sağdaki C segmentinin noktasını yaktım.

Sorun belli saniye FLAG bitini 1 belli saniye 0 yapmak kaldı. Onuda sağolasınız attığınız mailde yanıtladınız. bende SNA değişkenini tanımlayıp içine saniye cinsinden FLAG'ın 0 olma süresini (ISIA'nın ekranda kalma süresi) SNB değişkenine de FLAG'ın 1 olma süresini (ISIB'nin ekranda kalma süresi) yazmak istedim ilgili kodu BASLA etiketinin sonuna yazdım. Sanırım çalışıyor

SNA ve SNB değişkenlerinin içeriğini butonlar yardımı ile ayarlamak istiyorum (0-30 arasında) MODE butonuna bastığımda SNA yı (AYAR1 etiketine giderek) tekrar bastığımda SNByi (AYAR2 etiketine giderek) tekrar bastığımda normal çalışmaya dönmesini (BASLA etiketine giderek) istiyorum fakat bir türlü ayarlayamadım. Ayar menülerine gidiyor fakat menüde kalmıyor hemen başa dönüyor. Aynı zamanda bu ayar menülerinde iken tüm ekranın yanıp sönmesini istiyorum ama buna da bir hal çare bulamadım.

Bu sorunu da aştıktan sonra birde termostat özelliği eklemesi kaldı orası basit gibi görünüyor halledebileceğimi düşünüyorum.

Biraz uzun yazdım fakat başkasının yazdığı programın işleyişinin anlaşılmasının zor olduğunu düşündüğümden çok detaya girdim hatam varsa affola.

Yeni dosyaları ekliyorum.

Hocam unutmadan sorayım "Watch Window" içerisine program içinden bir değişkeni nasıl ekliyoruz

ete

Watch window'a sağ tıkla açılan pencerede ikinci sırada yer alan ;
Add Items (by Adress) seçeneğini seç
Yeniden açılan pencerede;
Memory default olarak Pic Data Memory olarak seçili geliyor oraya dokunma
Name kısmına değişken adını, adress kısmınada verdiğin değişken adresini ver. Bu işlemleri program PAUSE modunda iken yap.
Altta yer alan değişken tipi ve formatı uygun şekilde seçtikten sonra şlem tamamdır.

Ete

erdemefe

#8
Peki hocam değişkenin adresini nereden bileceğim ?
Şu ayar menüsü hakkında varmı söyleyecek birşeyleriniz?

ete

Yazdığın programında değişken adreslerini sen belirleyeceksin.
SAYI VAR BYTE 56  gibi. Burada 56 değişkenin adresidir.

SAYI    VAR BYTE 56
RAKAM VAR BYTE 57
SAYAC VAR WORD 58
KES     VAR WORD 60
dikkat edersen Byte cinsinden değişkenler 1 bytelık adres alıyor. Word değişkenleri ise 2 byte uzunluğunda yer alıyor. Buna dikkat etmen gerekir.
Ben genelde 56 nolu adresten başlatırım değişkenleri . Derleme sonucu oluşan ASM dosyasına bakarsanız orada adresleri vermektedir. Genelde START_ADRESS+00  , START_ADRESS+$10  gibi ifadelerle adresleri tarif eder.
START_ADRESS pek çok işlemci için $20 adresidir. Yani 32 nolu adrestir bu. 56 ya kadar işlemci kendi registerlerini yerleştirir sonrasını ben kendi değişknelerime veririm. Böylece onları isis de izlemek kolaylaşır.
Sen adres vermez isen o otomatik adresleme yapar. O adresleri dediğim gibi ASM dosyasını açarak görebilirsin.
Ayar menüsü konusunda çok şey verdim şimdiye kadar. Siteyi araştır. Örnek programları incele. Artık bunun üzerinde konuşmak bile yersiz. Yapılacak iş basit.
Mevcut saat değerini ekrana vereceksin. Sonra sırası ile saat ayarını yaptırıp sec tuşu ile dakika ayarına atlayacaksın. Sonra yapacak isen sn ayarını değilse tarih ayarına geçeceksin sonunda ayarları RTC ye yazdırıp programa geçeceksin.
Ete

erdemefe

sağolun hocam ayar bölümünü falan da hallettim fakat yine bir sorun var ben saniye palslerini tutturduğumu zannediyordum fakat tutturamamışım nerden anladın derseniz 1/64 bölme oranında dahili 4mhz osilatör ile 61 kesmede 1 sn artırmıştım fakat her saniye değişiminde pir pini toggle ederek oraya osiloskop bağladığımda gördüm ki benim 1sn olmuş 3.2 sn civarı bende 61 kesme yerine 30 kesmede bir artırınca osiloskopda ekdeki resimdeki gibi palsler yakaladım ama görüyorum ki bu aralıklar da eşit değil bunun nedeni nedir hocam?

hem de alıcı ile vericinin arasındaki bağlantıyı kesince hiç kesme oluşmuyor

Mucit23

@ Erdemefe,
Bu konuda simülasyon pek gerçekçi sonuç vermiyor. Gerçekte denemelisin
Bir ulusu yok etmenin En iyi yolu o ulusun dilini yok etmektir.

www.arectron.com/

erdemefe

@Mucit23 devre zaten kurulu gerçekte de deniyorum aynı sonuç var seri iletişim girince bir türlü TMR0 kesmesi tutmuyor.

ete

Programın kesme bölümü biraz hatalı gibi. Beraber inceleyelim.
DISABLE
KESME:
IF RCIF=0 THEN GOTO TMR00
HSERIN [WAIT ("EFE"),ISIB.LOWBYTE,ISIB.HIGHBYTE,ISARETB]   'SICAKLIĞI VE İŞARET BİTİNİ AL
GOTO KESME_CIK

TMR00:
IF T0IF=0 THEN GOTO KESME_CIK
SAYAC=SAYAC+1
    IF SAYAC=30 THEN
    SAYAC=0
    SN=SN+1
    toggle PORTB.5
    ENDIF

GOTO KESME_CIK

KESME_CIK:
RCIF=0
T0IF=0
RESUME
ENABLE

END

Birincisi Şayet TMR0 kesmesi oluşmuş ise bunu USART kesme bayrağı ile tespit etmemelisin. Direk TMR0 kesme bayrağı ile algılamalısın.
IF RCIF=0 THEN GOTO TMR00 yerine  IF TOIF=1 then TMR00 yazman daha doğru olur.

Elinde iki tane kesme kaynağı var. Ama sen kesme bayraklarını çıkışta sıfırlıyorsun. Bu ne demek, USART kesmesi oluşu TMR0 bayarığınıda sıfırlıyorsun. Bu oluşan kesmeyi iptal etmek anlamına geliyor. O halde yapılması gereken her bayrağı kendi kesme bölümünde sıfırlamalısın ve oluşabilecek ikinci kesmeyide dikkate almak zorundasın. Örnek veriyorum.
USART kesmesi oluştuğunda TMR0 kesmeside oluşmuş olabilir. Bu durumda hangisi önce işleniyorsa oradan çıkarken diğer kesme bayrağıda set edilmiş ise onuda işleyip çıkmalısın kesmeden. Aksi halde kesmelerin bazılarını atlamış olursun. Sorunun burada.
Yapılacak iş TMR0 kesme bayrağını onunla ilgli bölümde sıfırla. USART bayrağınıda kendi bölümünde sıfırla. Zaten USART bayrak sıfırlaman hatalı. RCIF direk yazılabilen bir register değildir. Yani RCIF=0 yazdığın zaman bu işleme alınamaz. RCIF ancak  TEMP=RCREG  şeklinde sıfırlanır. Yani RCREG registerinin içini boşalttığın zaman otomatikman RCIF de sıfırlanır. Bu programda senin USART kesmende çalışmıyor olması gerekir. Yada yalnızca bir kere çalışır.

Ete

erdemefe

hocam hemen dediklerinizi uyguladım. biraz daha düzeldi durum mesela alıcı ile vericinin bağlantısını kestiğimde tam 1sn tutturuyorum fakat bağlantıyı yaptığımda 1sn oluyor 1.3 sn USART devreye girince olay karışıyor.

KESME:

IF T0IF=1 THEN TMR00
IF RCIF=1 THEN RCI

TMR00:

    SAYAC=SAYAC+1
        IF SAYAC=61 THEN
        SAYAC=0
        SN=SN+1
        toggle PORTB.5
        ENDIF
T0IF=0
GOTO KESME_CIK

RCI:
HSERIN [WAIT ("EFE"),ISIB.LOWBYTE,ISIB.HIGHBYTE,ISARETB]   'SICAKLIĞI VE İŞARET BİTİNİ AL
GOTO KESME_CIK
TEMP=RCREG
KESME_CIK:
RESUME
ENABLE

END

Powered by EzPortal