avatar_Adem AYDIN

Kesme Role On/Off Süresi

Başlatan Adem AYDIN, 14 Mayıs 2017, 19:49:34

Adem AYDIN

Herkese Merhaba, Programda Herhangi Bir Rolenin Kaç sn On/Off (Aktif/Pasif) Olacağını Yaptım. Ancak Bunun Dakika ve Saat İçinde Yapmak İstiyorum Birkaç Şey Yapmaya Çalıştım Ama Dakika ve Saat'in Pasiflik (Off) Süresini Yapamadım. Dakika ve Saat İçin On/Off (Aktif/Pasif) Sürelerini Nasıl Belirleyebilirim? Yardımcı Olur Musunuz?


'Bu Program Kesme İle Rolelerin Ne Kadar Süre Çalıştığını Ölçmektedir

@ DEVICE PIC16F628A                          'İşlemci 16F628A
@ 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_OFF                'MCLR Pini Kullanılmıyor
@ DEVICE PIC16F628A, INTRC_OSC_NOCLKOUT      'Dahili Osilatör Kullanılacak

CMCON=7             'Karşılaştırıcıları Kapatır.
VRCON=0             'Referans Voltaj Girişini Kapatır.

        TRISA=0   :PORTA=0              'A Portunun Tamamını Çıkış Yap ve Sıfırla
        TRISB=$0F :PORTB=0              'B Portunun B.0, B.1, B.2 ve B.3 Pinilerini Giriş Yap ve Sıfırla

        DEFINE LCD_RSREG PORTA          'LCD Register Select Bacağı PORTA'ya Bağlı
        DEFINE LCD_RSBIT 6              'LCD Register Select Bacağı PORTA.6'ya Bağlı
        DEFINE LCD_EREG  PORTA          'LCD Enable Bacağı PORTA'ya Bağlı
        DEFINE LCD_EBIT  7              'LCD Enable Bacağı PORTA.7'ye Bağlı
        DEFINE LCD_DREG  PORTA          'LCD Data Bacakları PORTA'ya Bağlı
        DEFINE LCD_DBIT  0              'LCD Data Bacakları PORTA.0'dan Başlıyor (0/4)
        DEFINE LCD_BITS  4              'LCD'ye 4 Bit Bağlı (4/8)
        DEFINE LCD_LINES 2              'LCD 2 Satırdan Oluşuyor

        ON INTERRUPT GOTO KESME         'Kesme Olursa KESME'ye Git
        OPTION_REG=%10000101            'Dahili Pull-up Dirençleri İptal ve Bölme Oranı 1/64
        INTCON=%10100000          'Kesmeler Aktif ve TMR0 Kesmesi Aktif
       
        SAYAC VAR BYTE                  'SAYAC'ı 8 Bit Olarak Ata (Kesme Sayacı)
        SN VAR BYTE[5]                  'SN'yi   8 Bit Olarak Ata (Saniye)
        DK VAR BYTE[5]                  'DK'yi   8 Bit Olarak Ata (Dakika)
        SA VAR BYTE[5]                  'SA'yı   8 Bit Olarak Ata (Saat)
       
        AE VAR BYTE
        OF VAR BYTE
        EPORTB VAR BYTE
        EESKI VAR BYTE
        EDURUM VAR BYTE
        ER VAR BYTE
       
        DURUM VAR BYTE                  'DURUM'u 8 Bit Olarak Ata
        ESKI VAR BYTE                   'ESKI'yi 8 Bit Olarak Ata
        R VAR BYTE                      'R'yi    8 Bit Olarak Ata (Role)
        X VAR WORD                      'X'i    16 Bit Olarak Ata
        CLEAR                           'Tüm Değerleri Sıfırla (Atanan Değerler)
       
        LCDOUT $FE,1                    'LCD Ekranını Sil
        PAUSE 200                       'LCD Ekranının Açılmasına Gereken Süre
BASLA:
        LCDOUT $FE,$84,DEC2 SA[0],":",DEC2 DK[0],":",DEC2 SN[0]
        'LCD'nin 1 Satırına SA[0]'ı, DK[0]'ı ve SN[0]'ı 2 Basamaklı Olarak Yaz DK[0]'ın 2 Yanına : Yaz
        LCDOUT $FE,$C0,"ROLE=",#R,"  ",DEC2 SA[R],":",DEC2 DK[R],":",DEC2 SN[R]
        '2. Satırına ROLE= ve Desimal Olarak R'yi Yaz SA[R]'yi, DK[R]'yi ve SN[R]'yi 2 Basamaklı Olarak Yaz DK[R]'nin 2 Yanına : Yaz
       
        DURUM=PORTB & 15 '%1111         'DURUM=PORTB & 15 (PORTB'nin İlk 4 Bitinden Hangi 1 İse Onu DURUM'a Eşitle)
        IF DURUM>0 THEN PORTB=DURUM     'DURUM 0'dan Büyük İse DURUM'u PORTB'ye Eşitle
        ESKI=PORTB | DURUM*16           'PORTB veya DURUMU'un 16 Katını ESKI'ye Eşitle
       
        R=NCD ESKI  'ESKI'nin En Yüksek Bitinin Yerini R'ye Eşitle (1-16)(örn1. %0101 1000=7, örn2. %1000 0100=8, örn3. %8765 4321)
        R=((R>0) & %1)*(R-4)            '(R 0'dan Büyük İse ve 1 İse) Çarp (R-4 İle) (IF R>0 THEN R=R-4 İşlemini Yapar)
        PORTB=ESKI                      'ESKI'yi PORTB'ye Eşitle

        FOR X=0 TO 2000                 'Aşağıda Belirtilen İşlemleri 2001 kere Tekrarla
        PAUSEUS 10                      '10 Mikro sn Bekle
        NEXT X                          'X'i Bir Arttır ve İşlemleri Yap (2000 Oluncaya Kadar)
        GOTO BASLA                      'BASLA'ya Git

DISABLE                                 'Yeniden Kesme Olmaşmasını Önle
KESME:
        SAYAC=SAYAC+1                   'SAYAC'ı Bir Arttır (Kesme Sayacı  1 sn= 61(Sayac) x 256 (Tmr0) x 64 (Bölme))
        IF SAYAC=61 THEN                'SAYAC=61 İse (61 Defa Kesme Olunca 1 sn Süre Geçiyor (999424 us))
        SAYAC=0 :SN[0]=SN[0]+1          'SAYAC'ı Sıfırla ve SN[0]'ı Bir Arttır
        IF R!=0 THEN SN[R]=SN[R]+1      'R, 0'a Eşit Değil İse SN[R]'yi Bir Arttır
        'IF R!=0 THEN DK[R]=DK[R]+1
        IF OF=1 THEN AE=AE+1
       
        IF AE=2 THEN                    'AE=2 İse (2 sn Pasif İçin)
        AE=0 :OF=2
        ENDIF                           'İşlemler Belirlendi
        ENDIF                           'İşlemler Belirlendi
       
        IF OF=2 THEN
        PORTB=EPORTB :ESKI=EESKI    :DURUM=EDURUM :R=ER :OF=0 'Değerleri Geri Eşitlemek İçin
        ENDIF
       
        IF OF=0 THEN
        EPORTB=PORTB :EESKI=ESKI    :EDURUM=DURUM :ER=R       'Değerleri Korumak İçin
        ENDIF

        IF SN[0]=60 THEN                'SN[0]=60 İse (1 Dakika Süre Geçti)
        SN[0]=0 :DK[0]=DK[0]+1          'SN[0]'ı Sıfırla ve DK[0]'ı Bir Arttır
        IF DK[0]=60 THEN                'DK[0]=60 İse (1 Saat Süre Geçti)
        DK[0]=0 :SA[0]=SA[0]+1          'DK[0]'ı Sıfırla ve SA[0]'ı Bir Arttır
        IF SA[0]=24 THEN SA[0]=0        'SA[0]=24 İse SA[0]'ı Sıfırla (1 Gün Süre Geçti)
        ENDIF                           'İşlemler Belirlendi
        ENDIF                           'İşlemler Belirlendi

        IF R!=0 AND SN[R]=26 THEN       'R!=0 ve SN[R]=26 İse (25 sn'yi Görebilmek İçin 25+1)
        SN[R]=0 :DURUM=0
        ESKI=0 :PORTB=0
        OF=1   :R=0
        ':DK[R]=DK[R]+1                  'DK[R]'yi Bir Arttır
        ENDIF                           'İşlemler Belirlendi
       
        IF r!=0 AND DK[R]=26 THEN       'R!=0 ve DK[R]=26 İse (25 DK'yi Görebilmek İçin 25+1)
        DK[R]=0 :DURUM=0
        ESKI=0  :PORTB=0
        OF=1    :R=0
        ':SA[R]=SA[R]+1                  'SA[R]'yi Bir Arttır
        ENDIF                           'İşlemler Belirlendi
       
        'IF SA[R]=24 THEN SA[R]=0        'SA[R]=24 İse SA[R]'yi Sıfırla (1 Gün Süre Geçti)
       
        INTCON.2=0                      'Kesmeleri Sıfırla (Kesmeden Çıkmak ve Yeniden Kesme Yapabilmek İçin)
        RESUME                          'Kaldığı Yere Dön
    ENABLE                          'Kesmeler Yeniden Aktif
    END                             'Programı Bitir
ALLAH 'ın Dini Galip Gelmesi İçin (Malınızla ve Canınızla) Çalışın.

ete

#1
Kod olarak verdiğin programın düzgün olanını verirmisin. Ekinde verdiğin ile bu bir birinden farklı o yüzden hangisi doğru karar veremedim.
Her bir röle için önce bir AKTIF isimli değişken kullanılmalı. Aktif.1=1 ise röle 1 aktif, değilse pasif olmalıdır. Benzer şekilde Aktif.2=1 ise Role-2 aktif değilse pasif olmalıdır. Bu şekilde program kimin aktif kimin pasif olduğunu kolaylıkla anlayacaktır.
Daha sonra bir dizi değişkeni kullanılarak süreler bu değişkenle saydırılmalıdır. Örnek olarak;
- AKTIF_SAAT(1) 1 nolu sğrenin aktif olduğu saat süresini saysın.
- AKTIF_DAK(1) 1 nolu rölenin aktif olduğu dak süresini saysın.
- AKTIF_SN (1) 1 nolu rölenin aktif olduğu saniye süresini saysın.
- PASIF_SAAT(1) 1 nolu rölenin pasif olduğu süreyi saat olarak saysın
- PASIF_DAK(1) 1 nolu rölenin pasif olduğu dakikaları saysın
- PASIF_SN(1) 1 nolu rölenin pasif olduğu saniyeleri saysın.
Bu iş sanıldığı kadar kolay bir iş değil.
Her bir değişken tanımlanırken yanına index değeri verilecek bu değerde 5 olarak verilmeli (1 den itibaren kullandığımz için)
Yani AKTIF_SAAT VAR BYTE[5] şeklinde tanımlanmalı.
Gelelim saydırma işine.
Her saniye değiştiğinde (Kesme içinde);
IF SAYAC=61 THEN   (1 sn doldu demek oluyor
FOR I=1 to 4
    IF AKTIF.0[I]=1 THEN
        AKTIF_SN[I]=AKTIF_SN[I]+1
        IF AKTIF_SN[I]=60 then
            AKTIF_SAN[I]=0
            AKTIF_DAK[I]=AKTIF_DAK[I]+1
            IF AKTIF_DAK[I]=60 THEN
                AKTIF_DAK[I]=0
                AKTIF_SAAT[I]=AKTIF_SAAT[I]+1
            ENDIF
         ENDIF
     ELSE
         PASIF_SN[I]=PASIF_SN[I]+1
         IF PASIF_SN[I)=60 THEN
             PASIF_SN[I]=0
             PASIF_DAK[I]=PASIF_DAK[I]+1
             IF PASIF_DAK[I]=60 THEN
                 PASIF_DAK[I]=0
                 PASIF_SAAT[I]=PASIF_SAAT[I]+1
             ENDIF
          ENDIF
       ENDIF
NEXT
ENDIF

Şeklinde bir kod kullanılarak bütün süreler saydırılır.
Sonra ana program kısmında saydırılan bu süreler seçilen röleye bağlı olarak ekrana yazdırılır.
Ancak bu yöntemle bu işin yapılması çok zor. Çok fazla kod saat kısmında işlenmek zorunda buda epeyce bir komut gecikmesi yaratır. Bu sistemin sağlıklı çalışması anak bir RTC kullanılarak mümkün olabilir diye düşünüyorum.

Ete

Adem AYDIN

Hocam kodu yeniledim, sizin dediğiniz şekilde değiştirmeyi düşünüyorum. Ne tür rtc kullanmalıyım, veri okuması nasıl yapılıyor? Rtc ile yapınca kesme işlemi yapmalı mıyım?
ALLAH 'ın Dini Galip Gelmesi İçin (Malınızla ve Canınızla) Çalışın.

ete

RTC (Real Time Clock) entegresi programın yapacağı saniye artışı dakika artışı ve saat artışı gibi işlemleri kendi halledeceği için bir sürü kod dan kurtarır seni. Yukarıda verdiğim kodların bir kısmını yine kullanacaksın ama kod gecikmesi yaşamayacaksın çünki RTC bağımsız olarak zamanı kendisi ilerletecektir.
Genelde kullandığımız RTC ler DS1302 , DS1307 dir. Bu ikisinden birini kullanabilirsin. DS1302 SPI , DS1307 ise I2C haberleşir. Biraz daha iyidir 1307 onu tavsiye ederim.
Kod örneği için saat projelerine bakabilirsin benim.O konuya girersen sonlara doğru 1307 için verdiğim kod örnekleride var görebilirsin.

Kesme kullanmaya gerek yok. Yalnızca programa biraz ayarlama yap ve mantıken 1 sn dolmadan RTC yi okumaya çalışma. Çünki oradaki bilgi her sn yede bir değişecek. Yada en azından 500 ms geçtikten sonra okumaya çalış. Ard arda sık yapılan okumalar RTC in kendi işini yapmasını engeller.
Ete

elektromanyaq

daha önce yapılmış bi projenin kodlarında değişiklik yapmıştım bi arkadaşım istemişti işini görür sanırım

Powered by EzPortal