ds18b20 sıcaklık ölçme

Başlatan cihanogluts, 30 Temmuz 2015, 03:58:33

cihanogluts

merhaba arkadaşlar ds 18b20 ile sıcaklık ölçmek istiyorum ve sıcaklığı ölçüyorum fakat okuma süresi fazla olduğundan programda bulunan menu tuşuna bastığımda hemn menuye girmiyor. bende menü için bi kesme oluşturup program bütün işini bırakıp menüye girsin istedim ama beceremedim. varmı bu kemenin bi tedavisi.yoksa başka ne yaparsam menüye tuşa bastığım anda girebilirim

''@ DEVICE PIC16f877A 
'@ DEVICE PIC16f877A, WDT_ON 'Watch Dog timer açık
'@ DEVICE PIC16f877A, PWRT_ON 'Power on timer açık
'@ DEVICE PIC16f877A, PROTECT_OFF 'Kod Protek kapalı
'@ DEVICE PIC16f877A, MCLR_ON 'MCLR pini kullanılıyor.
'@ DEVICE PIC16f877A, XT_OSC 'Dahili osilatör kullanılacak


DEFINE OSC 4
CMCON=7 '*************************************
ADCON1= 7
ON INTERRUPT GOTO KESME
OPTION_REG.6=0
INTCON=%10010000
OPTION_REG.7=0
TRISA=%00000000
TRISB=%00000001
TRISC=%00000000
TRISD=%00000000
TRISE=%00000000
PORTA=0
PORTB=0
PORTC=0
PORTD=0
PORTE=0

DEFINE  LCD_DREG        PORTB
DEFINE  LCD_DBIT        4
DEFINE  LCD_RSREG       PORTB
DEFINE  LCD_RSBIT       1
DEFINE  LCD_RWREG       PORTB
DEFINE  LCD_RWBIT       2
DEFINE  LCD_EREG        PORTB
DEFINE  LCD_EBIT        3

DEFINE      loader_used 1   ' Boot-Loader is being used

Comm_Pin    VAR   PortA.0     ' One-wire Data-Pin "DQ" on PortC.0
Busy        VAR   BIT         ' Busy Status-Bit
R_Temp      VAR   WORD        ' RAW Temperature readings
TempC       VAR   WORD        ' Temp in deg C
Cold_Bit    VAR   R_Temp.Bit11' Sign-Bit for ± Temp. 1 = Below 0 deg C
Real_Cold   CON   1           ' Define Real_Cold = 1
baud        CON   16468       ' N9600 for serial LCD
Deg         CON   223         ' Data to display Deg ° symbol
Sign        VAR   BYTE        ' ± sign for temp display
Dummy       VAR   BYTE        ' Dummy for Div32
GIR         var   BIT         'menü ye girilecek

lcdout $fe,1  '**********************************************************
PAUSE 200     '***********************************************************

Start_Convert:
    OWOUT   Comm_Pin, 1, [$CC, $44]' Skip ROM search & do temp conversion
'    pause 750 '**************************************************************
Wait_Up:
    OWIN Comm_Pin, 4, [Busy]    ' Read busy-bit
    IF GIR=1 THEN MENU
    IF Busy = 0 THEN
      goto Wait_Up  ' Still busy..?, Wait_Up..!
    endif
    OWOUT   Comm_Pin, 1, [$CC, $BE]' Skip ROM search & read scratchpad memory
    OWIN    Comm_Pin, 2, [R_Temp.Lowbyte, R_Temp.Highbyte]' Read two bytes / end comms
    GOSUB   Convert_Temp
    portd=255
    GOTO    Start_Convert
   
Convert_Temp:                 ' +32.0 to +257 F
    IF Cold_Bit = Real_Cold THEN negatif ' If Cold_Bit = 1, it's below "0" deg C
    Sign  = "+"
    Dummy = 625 * R_Temp      ' Multiply to load internal registers with 32-bit value
    TempC = DIV32 10          ' Use Div32 value to calculate precise deg C
    Dummy = 1125 * R_Temp
    TempC  = (R_Temp & $0FF0) >> 4 ' Mask middle 8-bits, shift into lower byte
    lcdout $fe,2," ISI = ",Sign,DEC TempC,Deg,"C    "
    RETURN

negatif:                      ' Display full range -C to -F conversion
    Sign   = "-"            ' Display - symbol for negative temp
    Dummy  = 640 * ~R_Temp+1' Multiply to load internal registers with 32-bit value
    TempC  = DIV32 10000
    lcdout $fe,2, " ISI = ",Sign,DEC TempC ,Deg,"C "
    RETURN
GOTO Start_Convert   

MENU:
LCDOUT $FE,$80, "FAN => YUKARI"
LCDOUT $FE,$C0,"POMPA =>ASAGI BAS"
GIR=0
MENU_BIR:
'IF YUKARI=0 THEN 
'     buraya yukarı yuşuna basılınca ne yapılması gerekiyor sa onu yazman gerekir.
' endif
'IF ASAGI=0 then
'    burayada aşağı tuşuna basılınca ne yapılması gerekiyor ise onu yazman gerekir.
'endif
IF GIR=1 THEN  'MENUDEN ÇIKIŞ İÇİN TEKRAR MENU TUUNA BASILMAYI SEÇİYORUZ.
   GIR=0
   GOTO Start_Convert   'YANİ TEKRAR MENU TUŞUNA BASMIŞ İSEM PROGRAMI EN BAŞA YONLENDİR
ENDIF
goto menu_BiR


DISABLE       
KESME:
   GIR=1
   LCDOUT $FE,1 
' PAUSE 100 '****************************************************
INTCON.1=0
Resume
Enable


bo da portd.0 daki butonla kesme oluşturmaya çalıştım gördüğünüz üzere. eğer bu kesme ile yapılmaz diyorsanız neyle yapılır lütfen acill yardım. şimdiden teşekkürler

ete

Elbette bu iş en güzel PORTB.0 kesmesi ile yapılır. PortB.0 kesmesi demek MENU ye giriş tuşunun PORTB.0 pininde bağlı olması demektir.
Sende nerede bağlı? PortB.0 pinine bir tus bağlamamışsın. HAdi diyelimki oraya bir menu tusu bağladık. Şimdi programına dönelim.
Eksikler şunlar;
- 16F877A işlemci kullanıyorsun A portunda komparatör var bunu iptal etmen gerekiyor baş tarafa CMCON=7 komutunu ilave etmelisin.
- Açılışta LCDOUT $FE,1 komutunu verip 200 ms de gecikme vermen gerekiyor ki LCD kendine gelebilsin.
- Kesme kullanınca bütün pause lerden programı arındırman gerekiyor hepsini kaldırman en doğrusu
- Diyelimki Menu tuşuna bastın ve program otomatikman kesme etiketine gitti ne yapacak orada;?
   GOTO MENU komutu ile MENU etiketine gidecek ekrana bir şeyler yazıp orada kesilecek program. Kodların gerisi nerede? Onları yazmamışsın. Her neyse bir defa kesme içinden programı başka bir yere aktarmak yanlış. Kesme içinde yapabileceğin tek şey GIR diye bir bit değişkeni tanımlayıp onu kesme içinde SET etmen. Sonrada ana program kısmında IF GIR=1 ise GOTO MENU demen en güzeli.
Kesme içindeki o lüzumsuz bir pause 100 komutunu da kaldırman gerekecek.
Ana program bölümünde en büyük oyalanma nederede oluyor sence ELbette ssensör okumasının tamamlandığı kısımda orayada bir pause 750 koymuşsun. Bu kesme olmadığı durumlarda doğru ancak kesme olunca programda onu da kaldıracaksın. Onun yerine if GIR=1 then MENU  şeklinde bir satır ilave etmen yeterli olacaktır.
Menu etiketi altında LCDOUT satırı ekranı temizleme komutu ile geliyor.
LCDOUT $FE,1, "FAN => YUKARI"  şeklinde bu da ekranı sürekli silerek çalışacağı için göze hoş gözükmeyen bir imaj yaratır.
Onun yerine kesme içinde bir kereliğine,
LCDOUT $FE,1
komutunu vermen ve Menü etiketinde o satırıda,
LCDOUT $FE,$80, "FAN => YUKARI"
şeklinde yazman her şeyi düzeltecektir.
Bütün bunları yapınca programın menu tuşuna basar basmaz MENU etiketine gidecektir.
Peki orada ne yapacak işin bu kısmı eksik işte.
Bir defa Menu etiketini şöyle yazman gerek.
MENU:
LCDOUT $FE,$80, "FAN => YUKARI"
LCDOUT $FE,$C0,"POMPA =>ASAGI BAS"
GIR=0
MENU_BIR:
'IF YUKARI=0 THEN 
'     buraya yukarı yuşuna basılınca ne yapılması gerekiyor sa onu yazman gerekir.
' endif
'IF ASAGI=0 then
'    burayada aşağı tuşuna basılınca ne yapılması gerekiyor ise onu yazman gerekir.
'endif
IF GIR=1 THEN  'MENUDEN ÇIKIŞ İÇİN TEKRAR MENU TUUNA BASILMAYI SEÇİYORUZ.
   GIR=0
   GOTO Start_Convert   'YANİ TEKRAR MENU TUŞUNA BASMIŞ İSEM PROGRAMI EN BAŞA YONLENDİR
ENDIF
goto menu_BIR


Bütün bunları yaparsan programın istediğin gibi çalıştığını göreceksin.
Bu arada yazdığın kodları olması gerekenlerle değiştirdim. Orayada bakıp neler yaptığımı görebilirsin. Anlattıklarımı uyguladım sadece.

Ete

cihanogluts

Evet abi program tam istediğim gibi oldu. eline sağlık

cihanogluts

Abi dediğin gibi her şeyi yaptım oldu. Şimdi bi röle ekleyip saniye ile kontrol yapmam lazım ama bu programın gidişatını bozmadan olması lazım. Röle mesela 5sn çalışmak 5dk duracak ve böyle devam edecek. Bu 5 dk lık durmayı ben veriyorum ama program tamamen dışıdır nasıl yapmam lazımdı program hiç aksamasın

POWER

#4
bence en basit yöntem:proğramda kesme kullanılmış zaten,kesme içerisinde bir sayaç çalıştırıp buradan elde edeceğin süre ilede roleyi istediğin sürede açıp yada kapatabilirsin.

ete

#5
TMR0 veya TMR1 kesmesi ile yapılabilir ancak.
Global kesme ile RB0 kesmesi açık zaten. Birde TMR0 kesmesi aktive edilir.
Her 50 ms de bir kesme oluşacak şekilde ;
OPTION_REG=%00000111 değerini vereceksin . Bu her 1/256 komut çevriminde bir kesme oluşturacaktır.
Programın başında TMR0=60 değerini vereceksin.
INTCON=%10110000 değerini vereceksin
KES isimli bir byte değişkeni tanımlayacaksın (KES  VAR BYTE)
Programın kesme kısmında;
DISABLE
KESME:
          IF INTCON.2=1 then
             INTCON.2=0
             KES=KES+1
             IF KES=100 then
                KES=0
                TOGGLE ROLE
             ENDIF
             TMR0=60
             GOTO CIK
          ENDIF
   GIR=1
   LCDOUT $FE,1 
   INTCON.1=0
CIK:
Resume
Enable

şeklinde ekleme yaparsan sistem çalışır hale gelecektir.

TMR0 Kesme süresini 50 ms de bir yaptım. Bu mümkün olduğunca uzun olmalı ve sensör okumasını etkilememelidir.
Bu şekilde bir dene bakalım şayet sensör okuması TMR0 kesmelerinden etkilenirse okumada soun olacaktır. Duruma göre ne yapacağımıza karar veririz.

Bu arada OPTION registerine iki ayrı satırda değer vermiştik önceden. Bunları silip yeni verdiğim tek komutu kullanacaksın.
Aynı şekilde  INTCON registerinin eski değerini silip yenisini vereceksin.

Hepsi bu
Ete

cihanogluts

abi böyle bişey yapsam olmazmı saniye dk sayıcı arkada çaılşşın her 5 dk da bir 5 saniye çalışsın role. role portc.4 olsun.
ama bunun tetikleme kesmesi nerden yapılabilir. herhangi bi port high ise bu kesme başlasın gibi bi komut verebilirmiyiz.
ayrıca bu yazdığım çalışmadı



KESME:
     IF INTCON.2=1 then
     INTCON.2=0
      sayac=sayac+1
      if sayac=62 then
        sayac=0
        sn=sn+1       
        if sn=60 then
        sn=0
        dk=dk+1
        if dk=5 then
        dk=0
       
        if dk=0 and sn=>0 and sn=<5 then
        portc.4=1
        else
        portc.4=0
        endif
        endif       
      endif
      endif
      endif
 
   GIR=1   
' PAUSE 100 '****************************************************
INTCON.1=0
cik:
Resume
Enable


Powered by EzPortal