Haberler:

Forum kuralları güncellendi LÜTFEN  okuyunuz:  https://bit.ly/2IjR3ME

Ana Menü

ds18b20 rom adresi okumak

Başlatan antiteror, 07 Ocak 2010, 01:29:18

antiteror

arkadaşlar ds18b20 lerin pic basicde rom adreslerini nasıl okutacağız sitede araştırdım açık olarak bulamadım. ben 4 tane sensörü aynı hatta bağlamak istiyorum ingilizce bi kaç site linki buldum forumda ama bendede ingizce yok bi türlü çözemedim yardım ederseniz çok sevinirim
teşekkürler

ete

Basitçe rom kodu okuma aşağıdaki şekilde yapılabilir.

Ete

@ DEVICE pic16F877A 'islemci 16F877A
@ DEVICE pic16F877A, WDT_OFF 'Watch Dog timer kapali
@ DEVICE pic16F877A, PWRT_ON 'Power on timer acik
@ DEVICE pic16F877A, PROTECT_OFF 'Kod koruma kapali
@ DEVICE Pic16F877A, XT_OSC
'***********LCD Tanımlamaları***************************************************
DEFINE LCD_DREG     PORTB
DEFINE LCD_DBIT         4
DEFINE LCD_EREG     PORTB
DEFINE LCD_EBIT         1
DEFINE LCD_RWREG    PORTB
DEFINE LCD_RWBIT        2
DEFINE LCD_RSREG    PORTB
DEFINE LCD_RSBIT        3
DEFINE LCD_BITS         4
DEFINE LCD_LINES        2       

CMCON=7                      'CCP iptal hepsi giriş çıkış
OPTION_REG.7=0
TrisA=0
TrisB=0
PortA=0
PortB=0   
DEFINE  OSC 4           ' 4 MHz oscillator
DQ      VAR PortA.0       ' io pini "DS18B202nin "DQ" ucu"
ID      VAR BYTE[8]     ' 64-bit ROM kodu

Basla:
    PAUSE 500           ' 0.5 saniye
'***********LCD yi Kullanıma Hazır Hale Getir***********************************
LOW PORTB.2 'RW bacağı ekrana yazmaya imkan vermek için LOW yapıldı.
lcdout $FE,1
PAUSE 200   ' LCD nin kullanıma hazır hale gelebilmesi için gerekli süre
lcdout $FE,1 
   
cevrim
    OWOUT DQ, 1, [$33]  'ROM komutu

dongu:
    OWIN DQ, 0, [STR ID\8] '64-bit ROM bilgis 8-byte veri dizisi ile "ID"
    lcdout $FE,$80,"Aile Kodu = ",HEX2 ID[0],"h"
    lcdout $FE,$C0,HEX2 ID[1],HEX2 ID[2],HEX2 ID[3],HEX2 ID[4],HEX2 ID[5],HEX2 ID[6],"h"
    lcdout $FE,$94,"Ceksum = ",HEX2 ID[7],"h"

ID_Device:
    IF ID[0] = $5 THEN
        lcdout $FE,$D4, "Donanim = Sivic     "
    ENDIF
    IF (ID[0] = $28) OR (ID[0] = $22) THEN
       lcdout $FE,$D4, "Donanim = ISI Sensoru"
    ENDIF
   IF ID[0] = $01 THEN
       lcdout $FE,$D4, "Donanim = Seri No#   "
    ENDIF
   PAUSE 10000       
    GOTO cevrim
   
    END
Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

antiteror

ete hocam çok sağolun bu yazdığınız programı çalıştıramadım. isiste 1 tane 877a porta nın 0.bitine ds18b20 bağladım 4.7k lık direncini taktım.
2 satırlık lcd de sadece
Aile Kodu = 00h
000000000000h yazıyor
başka hiç bi değer okunmuyor. bağlantımda mı yanlışlık var? çok teşekkürler

ete

1 tane DS18B20 bağlarsanız çalışmaz. En azından 2 tane aynı data hattına bağlanmalıdır diyecektim ama rom kodunun okunması için teker teker bağlanmaları gerekir. Önce birini daha sonra onu devre dışı bırakıp diğerini okumak gerekiyor.
Muhtemelen isis ile simulasyonda bunu deniyorsun. Bende deniyorum aynı sonucu alıyorum. Daha önce bunu çalıştırdığımdan eminim. O programları da silmişim önemsiz diye. Ama farklı bir şey yapıldığını sanmıyorum.
64 bitlik rom kodunu okumak için önce alete $33 kontrol kodunu yolluyorsun ardından  8 ayrı byte olarak bu kodları okuyorsun. İlk gelen Aİle kodu (DS18B20 için $28)  oluyor peşinden gelen 6 adet byte ise seri numarası oluyor. En sonda da CRC hesaplama kodu geliyor.
Ama nedendir bilinmez isis sürekli bu kodları $FF olarak veriyor. Bu nedenle gerçek devrede denemek gerekir.

Ete


Ete
Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

antiteror

şu şekilde çizdim yine olmadı ete hocam
yaptığım şekli ile ekteki dosyaya ekledim
ds18b20.rar


ete

Sorunu anladım. Yalnızca tek okuma yaparsan okuyamıyor.  Bunun sebebide DQ pininin giriş pini olarak ayarlanmamasından kaynaklanıyor.
Bu nedenle Şayet Programda yer alan,
TrisA=0    komutunu,
TRISA=%00010000
şeklinde değiştirirsen ilk verdiğim kod da çalışacaktır.

ete
Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

antiteror

@ DEVICE pic16F877A 'islemci 16F877A 
@ DEVICE pic16F877A, WDT_OFF 'Watch Dog timer kapali 
@ DEVICE pic16F877A, PWRT_ON 'Power on timer acik 
@ DEVICE pic16F877A, PROTECT_OFF 'Kod koruma kapali 
@ DEVICE Pic16F877A, XT_OSC 
'***********LCD Tanımlamaları*************************************************** 
DEFINE LCD_DREG     PORTB 
DEFINE LCD_DBIT         4 
DEFINE LCD_EREG     PORTB 
DEFINE LCD_EBIT         1 
DEFINE LCD_RWREG    PORTB 
DEFINE LCD_RWBIT        2 
DEFINE LCD_RSREG    PORTB 
DEFINE LCD_RSBIT        3 
DEFINE LCD_BITS         4 
DEFINE LCD_LINES        2        

CMCON=7                      'CCP iptal hepsi giriş çıkış
ADCON1 = 7 
OPTION_REG.7=0 
TRISA=%00000000
TrisB=0
Trisc=%00000001
Trisd=0
Trise=0 
PortA=0 
PortB=0    
DEFINE  OSC 4           ' 4 MHz oscillator 
DQ      VAR Portc.0       ' io pini "DS18B202nin "DQ" ucu" 
ID      VAR BYTE[8]     ' 64-bit ROM kodu 

Basla: 
    PAUSE 500           ' 0.5 saniye 
'***********LCD yi Kullanıma Hazır Hale Getir*********************************** 
LOW PORTB.2 'RW bacağı ekrana yazmaya imkan vermek için LOW yapıldı. 
lcdout $FE,1 
PAUSE 200   ' LCD nin kullanıma hazır hale gelebilmesi için gerekli süre 
lcdout $FE,1 
    
cevrim 
    OWOUT DQ, 1, [$33]  'ROM komutu 

dongu: 
    OWIN DQ, 0, [STR ID\8] '64-bit ROM bilgis 8-byte veri dizisi ile "ID" 
    lcdout $FE,$80,"Aile Kodu = ",HEX2 ID[0],"h" 
    lcdout $FE,$C0,HEX2 ID[1],HEX2 ID[2],HEX2 ID[3],HEX2 ID[4],HEX2 ID[5],HEX2 ID[6],"h" 
    lcdout $FE,$94,"Ceksum = ",HEX2 ID[7],"h" 

ID_Device: 
    IF ID[0] = $5 THEN 
        lcdout $FE,$D4, "Donanim = Sivic     " 
    ENDIF 
    IF (ID[0] = $28) OR (ID[0] = $22) THEN 
       lcdout $FE,$D4, "Donanim = ISI Sensoru" 
    ENDIF 
   IF ID[0] = $01 THEN 
       lcdout $FE,$D4, "Donanim = Seri No#   " 
    ENDIF 
   PAUSE 1000        
    GOTO cevrim 
    
    END

kodu bu şekilde yazınca çalıştı. devrede 2 tane ds kullandım bunların ayrı ayrı rom kodlarını okuyup ayrı ayrı sensörlerde ısı çevrimini nasıl yapıcam hesaplama olarak değilde ham değerleri ayrı ayrı nasıl okutabilirim yol gösterirseniz sevinirim teşekkürler

ete

Ahmet,
O komut kullanılmış idi görmedinherhalde.

AYnı data hattına bağlı birden fazla sensörü okumak için yapılması gereken işlem sırası şöyledir.
1. Önce sensörler teker teker bağlanarak Rom kodları okunup bir yerlere kayıt edilmelidir. Sonra hangi romkoduna sahip sensör okunacak ise önce matchrom kodu ($55) ardından rom kodu yollanır. Ardından da standart sıcaklık okuma işlemi yerine getirilir.
Daha sonra aynı işlemler diğer sensör için yapılarak aynı data hattına bağlı birden fazla sensör okunmuş olur.

Aşağıdaki örnek sana yol gösterecektir.
Program uzadığı için yalnızca basla satırından sonrakileri yazdım.

Ete

Basla:
    PAUSE 500           ' 0.5 saniye
'***********LCD yi Kullanıma Hazır Hale Getir***********************************
LOW PORTB.2 'RW bacağı ekrana yazmaya imkan vermek için LOW yapıldı.
lcdout $FE,1
PAUSE 200   ' LCD nin kullanıma hazır hale gelebilmesi için gerekli süre
lcdout $FE,1
   
Cevrim:
    OWOUT DQ, 1, [$33]  'ROM komutu

Dongu:
    OWIN DQ, 0, [STR ID\8] '64-bit ROM bilgis 8-byte veri dizisi ile "ID"
    lcdout $FE,$80,"Aile Kodu = ",HEX2 ID[0],"h"
    lcdout $FE,$C0,HEX2 ID[1],HEX2 ID[2],HEX2 ID[3],HEX2 ID[4],HEX2 ID[5],HEX2 ID[6],"h"
    lcdout $FE,$94,"Ceksum = ",HEX2 ID[7],"h"

ID_Device:

    IF ID[0] = $5 THEN
        lcdout $FE,$D4, "Donanim = Sivic     "
    ENDIF
    IF (ID[0] = $28) OR (ID[0] = $22) THEN
       lcdout $FE,$D4, "Donanim = ISI Sensoru"
    ENDIF
    IF ID[0] = $01 THEN
       lcdout $FE,$D4, "Donanim = Seri No#   "
    ENDIF
    PAUSE 100       
'    GOTO cevrim
    
    OWOUT DQ, 1, [$55]  'Match ROM komutu
    OWOUT DQ, 1, [STR ID\8]   'rom kodunu ver
    OWOUT   DQ, 1, [$CC, $44]' ISI değerini oku
Bekle:
       OWIN    DQ, 0, [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, 0, [HAM.Lowbyte, HAM.Highbyte]' İki byte oku ve okumayı bitir.
Hesapla:                 ' Ham değerden Santigrat derece hesabı
    Sign  = "+"
    IF SIGN_BITI = NEGAT_ISI THEN
       Sign   = "-"  
       ham=($ffff-ham)+1
    endif
    
GEC:
    ISI = HAM*10/16
    ISI1=ISI/10
    ISI2 = (ISI //10)

LCDOUT $fe,$d4,"ISI=",dec2 ISI1,",",dec2 ISI2,"           "
    pause 2000     
    GOTO cevrim     
   
    END
Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

antiteror

şöyle bişeyler yaptım
3 tane buton var 1. buton ds'leri  kaydetmek için.
sırasıyla kaydetmek için siviçler var
diğer 2 tanesi ise ds18b20 lerin sıcaklıklarını ekranda görmek için
1. butona basınca 1 ds'nin rom bilgileri ve sıcaklığı okunuyor ve ekrana yazılıyor
2. butona basınca 2 ds'nin rom bilgileri ve sıcaklığı okunuyor ve ekrana yazılıyor olması gerekiyor
rom bilgileri oluyor ama sıcaklık düzgün çıkmıyor
belkide rom bilgilerini düzgün gönderip sensörleri okutamıyorum
hesaplama kısmını ete hocamın ders_9 daki 16f628li DS18B20 dosyasından aldım.
şemayı proteus 7.6 ile çizdim. ekteki dosyada herşey var
ek bişey sormak istiyorum 20x4 lük bir lcd de yada fark etmez, sadece satırı silmek istiyorsak nasıl bir komut göndermek gerekiyor?
ds18b20_ver1.rar

@ DEVICE pic16F877A 'islemci 16F877A 
@ DEVICE pic16F877A, WDT_OFF 'Watch Dog timer kapali 
@ DEVICE pic16F877A, PWRT_ON 'Power on timer acik 
@ DEVICE pic16F877A, PROTECT_OFF 'Kod koruma kapali 
@ DEVICE Pic16F877A, XT_OSC 
'***********LCD Tanımlamaları*************************************************** 
DEFINE LCD_DREG     PORTB 
DEFINE LCD_DBIT         4 
DEFINE LCD_EREG     PORTB 
DEFINE LCD_EBIT         1 
DEFINE LCD_RWREG    PORTB 
DEFINE LCD_RWBIT        2 
DEFINE LCD_RSREG    PORTB 
DEFINE LCD_RSBIT        3 
DEFINE LCD_BITS         4 
DEFINE LCD_LINES        2        
DEFINE  OSC 4           ' 4 MHz oscillator 
CMCON=7                      'CCP iptal hepsi giriş çıkış 
ADCON1 = 7 
OPTION_REG.7=0 
TRISA=%00000000 
TrisB=0 
Trisc=%00001111 
Trisd=0 
Trise=0 
PortA=0 
PortB=0    

kaydet  var portc.1
veri    var portc.2
veri1   var portc.3
DQ      VAR Portc.0       ' io pini "DS18B202nin "DQ" ucu" 
ID      VAR BYTE[8]     ' 64-bit ROM kodu 
ID1     var byte[8]
Busy        VAR BIT         ' Busy Status-Bit
HAM         VAR	WORD        ' Sensör HAM okuma değeri
ISI         VAR WORD        ' Hesaplanmış ISI değeri
Float       VAR WORD        ' Holds remainder for + temp C display
X           VAR WORD       
ISARET_BITI   VAR HAM.Bit11   '   +/- sıcaklık İşaret biti,  1 = olursa eksi sıcaklık
EKSI_ISI   CON 1           ' Sıfır altında isaret biti=1  oluyor kontrol için
DERECE     CON 223         ' ° işareti
ISARET     VAR BYTE        '  ISI değeri için  +/-  işaret
TEMP        VAR BYTE       ' Div32 bit hesap için geçici değişken
Busy1        VAR BIT         ' Busy Status-Bit
HAM1         VAR	WORD        ' Sensör HAM okuma değeri
ISI1         VAR WORD        ' Hesaplanmış ISI değeri
Float1       VAR WORD        ' Holds remainder for + temp C display
X1           VAR WORD       
ISARET_BITI1   VAR HAM1.Bit11   '   +/- sıcaklık İşaret biti,  1 = olursa eksi sıcaklık
EKSI_ISI1   CON 1           ' Sıfır altında isaret biti=1  oluyor kontrol için
DERECE1     CON 223         ' ° işareti
ISARET1     VAR BYTE        '  ISI değeri için  +/-  işaret
TEMP1        VAR BYTE       ' Div32 bit hesap için geçici değişken
clear
LOW PORTB.2 'RW bacağı ekrana yazmaya imkan vermek için LOW yapıldı. 
lcdout $FE,1 
PAUSE 500   ' LCD nin kullanıma hazır hale gelebilmesi için gerekli süre  
    
cevrim: 
    OWOUT DQ, 1, [$33]  'ROM komutu 
    OWIN DQ, 0, [STR ID\8] '64-bit ROM bilgis 8-byte veri dizisi ile "ID" 
    lcdout $FE,$80,"Aile Kodu = ",HEX2 ID[0],"h" 
    lcdout $FE,$C0,HEX2 ID[1],HEX2 ID[2],HEX2 ID[3],HEX2 ID[4],HEX2 ID[5],HEX2 ID[6],"h" 
    lcdout $FE,$94,"Ceksum = ",HEX2 ID[7],"h" 
    if  kaydet=1    then    cevrim
    while   kaydet=0
    wend
    lcdout $FE,$d4,"1.SEN. Kayit Edildi."
    pause 1000
    lcdout $FE,$d4,"                    "
dongu:
    if  kaydet=1    then    dongu
    while   kaydet=0
    wend
cevrim1:
    OWOUT DQ, 1, [$33]  'ROM komutu 
    OWIN DQ, 0, [STR ID1\8] '64-bit ROM bilgis 8-byte veri dizisi ile "ID" 
    lcdout $FE,$80,"Aile Kodu = ",HEX2 ID1[0],"h" 
    lcdout $FE,$C0,HEX2 ID1[1],HEX2 ID1[2],HEX2 ID1[3],HEX2 ID1[4],HEX2 ID1[5],HEX2 ID1[6],"h" 
    lcdout $FE,$94,"Ceksum = ",HEX2 ID1[7],"h" 
    lcdout $FE,$d4,"2.SEN. Kayit Edildi."
    pause 1000
    lcdout $FE,$d4,"                    "
ce:
    if veri=0 then ce1
    while   veri=0
    wend
    if veri1=0 then ce2
    while   veri1=0 
    wend
    goto ce
ce1:
    lcdout $FE,$80,"Aile Kodu = ",HEX2 ID[0],"h" 
    lcdout $FE,$C0,HEX2 ID[1],HEX2 ID[2],HEX2 ID[3],HEX2 ID[4],HEX2 ID[5],HEX2 ID[6],"h" 
    lcdout $FE,$94,"Ceksum = ",HEX2 ID[7],"h"
    OWOUT DQ, 1, [$55,$28,$B1,$FE,$22,$00,$00,$00,$5D,$44]  'Match ROM komutu 
    OWOUT DQ, 1, [STR ID\8]   'rom kodunu ver 
    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.
    
Hesapla:                 ' Ham değerden Santigrat derece hesabı
    ISARET  = "+"
    IF ISARET_BITI = EKSI_ISI THEN
       ISARET   = "-"  
       temp=($ffff-ham+1)*625
       ISI  = DIV32 10 
       GOTO GEC   
    endif
    TEMP = 625 * HAM        ' 
    ISI = DIV32 10          ' Div32 hassas derece hesabı için 32 bit bölme yapıyoruz.
GEC:
    FLOAT = (ISI //1000)/100
    ISI=ISI/1000
    LCDOUT $FE,$d4,ISARET,DEC ISI,".",DEC1 (Float)," ",Derece,"C " '2. satırda ısı
    goto ce
ce2: 
    lcdout $FE,$80,"Aile Kodu = ",HEX2 ID1[0],"h" 
    lcdout $FE,$C0,HEX2 ID1[1],HEX2 ID1[2],HEX2 ID1[3],HEX2 ID1[4],HEX2 ID1[5],HEX2 ID1[6],"h" 
    lcdout $FE,$94,"Ceksum = ",HEX2 ID1[7],"h"
    OWOUT DQ, 1, [$55,$28,$B1,$FE,$22,$00,$00,$00,$5D,$44]  'Match ROM komutu 
    OWOUT DQ, 1, [STR ID1\8]   'rom kodunu ver 
    OWOUT   DQ, 1, [$CC, $44]' ISI değerini oku 

Bekle1:
           OWIN    DQ, 4, [Busy1]    ' Busy değerini oku
           IF      Busy1 = 0 THEN Bekle1    ' hala meşgulmü? , evet ise goto Bekle..!
           OWOUT   DQ, 1, [$CC, $BE]' scratchpad memory oku
           OWIN    DQ, 2, [HAM1.Lowbyte, HAM1.Highbyte]' İki byte oku ve okumayı bitir.
    
Hesapla1:                 ' Ham değerden Santigrat derece hesabı
    ISARET1  = "+"
    IF ISARET_BITI1 = EKSI_ISI1 THEN
       ISARET1   = "-"  
       temp1=($ffff-ham1+1)*625
       ISI1  = DIV32 10 
       GOTO GEC1   
    endif
    TEMP1 = 625 * HAM1        ' 
    ISI1 = DIV32 10          ' Div32 hassas derece hesabı için 32 bit bölme yapıyoruz.
GEC1:
    FLOAT1 = (ISI1 //1000)/100
    ISI1=ISI1/1000
    LCDOUT $FE,$d4,ISARET1,DEC ISI1,".",DEC1 (Float1)," ",Derece1,"C " '2. satırda ısı 
    GOTO ce 
    END

ete

Antiteror,

Sana yazdığım en son mesajı hiç değerlendirmemişsin maalesef.

İyice oku o mesajı ve verdiğim kodu da incele istersen.
Çok basit bir şey çok karmaşık hale getirmişsin.
Tek sıcaklık okuma rutini olması gerekir. Alt programla halletmeye çalış.

Ete
Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

ete

Antiteror,

Aynı data hattına bağlı sensörleri okuma işlemi deveye hendek atlatma yöntemine benziyor.
Bence bayağı zahmetli bir iş. Boşta pin var ise en iyisi her sensörü bir başka data pinine bağlamak. Ama boşta pin yoksa bu metod kullanılabilir.

Sistemin prensibi;
- Önceden yukarıda açıklandığı ve seninde çalıştırdığın şekilde sensörün 8 byte lık rom bilgisini (AileKodu+Serial No+CRC) okuyup bir yere kayıt ediyorsun.
- Sonra her sıcaklık okumasında bu rom kodlarını kullanman gerekiyor.
örnek vermek gerekir ise;
Önceden rom kodu okunmuş bir sensörden sıcaklık okumak için önce Match Rom komutu olan $55 veriliyor, ardından 8 byte lık rom kodu veriliyor ve en sonda ise KOnvert komutu olan $44 verilerek Data hattının LOW olması bekleniyor. Bu açıkladıklarıma ait komut örneği şöyle olacak;
 OWOut DQ, 1, [$55, $28, $31, $c5, $b8, $00, $00, $00, $B9, $44] '
Bekle:
       While not DQ:Wend

Daha sonra yine matchROM ($55) ve ardından 8 bytelık rom kodu ve peşinden $BE Scratch Pad hafızası okunuyor.
       OWOut DQ, 1,  [$55, $28, $31, $c5, $b8, $00, $00, $00, $B9, $BE]

Ardından SCratchPad hafızasından Ham sıcaklık değeri 2 byte olarak aşağıdaki şekilde okunuyor.
       OWIn DQ, 0, [HAM.Byte0, HAM.Byte1]
Bundan sonraki işlemler standart sıcaklık hesaplama kısmını içeriyor onları yazmıyorum.

Aynı hatta bağlı olan diğer sensör veya sensörler için aynı yöntem kullanılarak bütün sensörler okunabiliyor.

Artık gerisini halledersin sanırım.

Ete
Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

antiteror

boşta pin var ama biraz daha uğraşayım belki yapabilirim yapamazsamda başka uca takarım yapcak bişey yok. çok teşekkür ederim yardımlarınız için

ete

Senin devrene göre çalışan bir program veriyorum.

Dene bakalım.

Önce anahtarlar açılıp sensörlerin romkodları teker teker okutulmalıdır. Daha sonra SEC butonu (üstteki olan) basılıp sıcaklık okuma kısmına geçilmektedir.
Burada alttaki iki butondan hangisine basarsan ona ait sıcaklık okunup ekrana verilmektedir. İlk okumada +85 gözükebilir yeniden okut sonrakiler doğru gelecektir.

Ete

@ DEVICE pic16F877A 'islemci 16F877A 
@ DEVICE pic16F877A, WDT_OFF 'Watch Dog timer kapali 
@ DEVICE pic16F877A, PWRT_ON 'Power on timer acik 
@ DEVICE pic16F877A, PROTECT_OFF 'Kod koruma kapali 
@ DEVICE Pic16F877A, XT_OSC 
'***********LCD Tanımlamaları*************************************************** 
DEFINE LCD_DREG     PORTB 
DEFINE LCD_DBIT         4 
DEFINE LCD_EREG     PORTB 
DEFINE LCD_EBIT         1 
DEFINE LCD_RWREG    PORTB 
DEFINE LCD_RWBIT        2 
DEFINE LCD_RSREG    PORTB 
DEFINE LCD_RSBIT        3 
DEFINE LCD_BITS         4 
DEFINE LCD_LINES        2        
DEFINE  OSC 4           ' 4 MHz oscillator 
CMCON=7                      'CCP iptal hepsi giriş çıkış 
ADCON1 = 7 
OPTION_REG.7=0 
TRISA=%00000000 
TrisB=0 
Trisc=%00001111 
Trisd=0 
Trise=0 
PortA=0 
PortB=0    

SEC  var portc.1
veri    var portc.2
veri1   var portc.3
DQ      VAR Portc.0       ' io pini "DS18B202nin "DQ" ucu" 
ID      VAR BYTE[8]     ' 64-bit ROM kodu 
Busy        VAR BIT         ' Busy Status-Bit
HAM         VAR	WORD        ' Sensör HAM okuma değeri
ISI         VAR WORD        ' Hesaplanmış ISI değeri
Float       VAR WORD        ' Holds remainder for + temp C display
X           VAR WORD       
ISARET_BITI   VAR HAM.Bit11   '   +/- sıcaklık İşaret biti,  1 = olursa eksi sıcaklık
EKSI_ISI   CON 1           ' Sıfır altında isaret biti=1  oluyor kontrol için
DERECE     CON 223         ' ° işareti
ISARET     VAR BYTE        '  ISI değeri için  +/-  işaret
TEMP        VAR BYTE       ' Div32 bit hesap için geçici değişken

     

I            VAR BYTE
clear
LOW PORTB.2 'RW bacağı ekrana yazmaya imkan vermek için LOW yapıldı. 
lcdout $FE,1 
PAUSE 500   ' LCD nin kullanıma hazır hale gelebilmesi için gerekli süre  
'------------------ikinci program-------------------------------------------
ROMOKU:       
    OWOUT DQ, 1, [$33]  'ROM komutu 
    OWIN DQ, 0, [STR ID\8] '64-bit ROM bilgis 8-byte veri dizisi ile "ID" 
    lcdout $FE,$80,"Aile Kodu = ",HEX2 ID[0],"h" 
    lcdout $FE,$C0,HEX2 ID[1],HEX2 ID[2],HEX2 ID[3],HEX2 ID[4],HEX2 ID[5],HEX2 ID[6],"h" 
    lcdout $FE,$94,"Ceksum = ",HEX2 ID[7],"h" 
    if  VERI=0 THEN
      FOR I=0 TO 7
         WRITE I,ID(I):PAUSE 10
      NEXT     
      lcdout $FE,$d4,"1.SEN. Kayit Edildi."  
      PAUSE 1000
    ENDIF
    IF VERI1=0 THEN
       FOR I=0 TO 7
          WRITE (I+10),ID(I):PAUSE 10
       NEXT
       lcdout $FE,$d4,"2.SEN. Kayit Edildi."
       pause 1000
    ENDIF  
    LCDOUT $FE,$D4,REP 32\20

    IF SEC=0 THEN 
      GOTO ISIOKU
    ENDIF  
      
    GOTO ROMOKU

ISIOKU:
       LCDOUT $FE,2,"  ISI  OKUMA    "
       IF VERI=0 THEN
          FOR I=0 TO 7
            READ I, ID(I)
          NEXT
         GOTO CIK
       ENDIF
       
       IF VERI1=0 THEN
          FOR I=0 TO 7
            READ (I+10),ID(I)
          NEXT
       ENDIF
     
CIK:        
       if veri=1 and veri1=1 then isioku 
'       OWOut DQ, 1, [$55, STR ID\8, $4E, $FF, $FF, $7F] ' Init Sensor 
'       OWOut DQ, 1, [$55, STR ID\8, $48] 
'       OWOut DQ, 1, [$55, STR ID\8, $B8]
'       OWOut DQ, 1, [$55, STR ID\8, $BE]        
'       OWIN DQ, 0, [HAM.Lowbyte, HAM.Highbyte]  
         
       lcdout $FE,$80,"Aile Kodu = ",HEX2 ID[0],"h" 
       lcdout $FE,$C0,HEX2 ID[1],HEX2 ID[2],HEX2 ID[3],HEX2 ID[4],HEX2 ID[5],HEX2 ID[6],"h" 
       lcdout $FE,$94,"Ceksum = ",HEX2 ID[7],"h" 
       GOSUB ROMVER 
       GOSUB HESAPLA 
atla:             
         
          LCDOUT $FE,$d4,ISARET,DEC ISI,".",DEC1 (Float)," ",Derece,"C " '2. satırda ısı
          PAUSE 1000
          GOTO ISIOKU
ROMVER:                 
          OWOUT DQ, 1, [$55,str ID\8,$44]  'Match ROM komutu
          
          While not DQ:wend
          OWOUT DQ, 1, [$55,STR ID\8,$BE ]  'Match ROM komutu       
          OWIN  DQ, 0, [HAM.Lowbyte, HAM.Highbyte]' İki byte oku ve okumayı bitir. 
       
Hesapla:                 ' Ham değerden Santigrat derece hesabı
    ISARET  = "+"
    IF ISARET_BITI = EKSI_ISI THEN
       ISARET   = "-" 
       HAM=($ffff-ham)+1
    endif
   
GEC:
    ISI = (HAM+1)*10/16
    FLOAT = (ISI //10)
    ISI=ISI/10
    RETURN

    END
Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

antiteror

süpersiniz ete hocam dün sabahtan beri bunu yapmaya çalışıyordum.
bu yazdığınız programda picin eepromuna yazılıyor ordan tekrar okuyor elektrik kesilse bile bi daha romları kayıt etmeye gerek kalmıyor. yardımlarınız için çok teşekkür ederim. aynı bu mantıkla 1 wire ile çalışan her şeyin kontrolünü yapabiliriz değilmi?
bir kaç şey daha sormak istiyorum yukardaki kodda neden ilk başta 85 derece gösteriyor? aşşağıdaki iki satırda REP 32\20 ne demek ve onun altındaki satırda [$55,STR ID\8,$BE ] burdaki STR ID ne işlemi yapıyor
LCDOUT $FE,$D4,REP 32\20
OWOUT DQ, 1, [$55,STR ID\8,$BE ]

ete

Alıntı Yapaynı bu mantıkla 1 wire ile çalışan her şeyin kontrolünü yapabiliriz değilmi?
bir kaç şey daha sormak istiyorum yukardaki kodda neden ilk başta 85 derece gösteriyor? aşşağıdaki iki satırda REP 32\20 ne demek ve onun altındaki satırda [$55,STR ID\8,$BE ] burdaki STR ID ne işlemi yapıyor
Kod:

Evet aynı bu mantık ile her türlü 1-wire elemanın kontrolünü yapabilirsin.

Sistem ilk  çlçümde mutlaka 85 gösteriyor. Bunu önleyemedim. Sebebinide bulamadım Bulsam çözümünü de bulacaktım. Enteresandır. Birinici değil ikincide okuyor. Ama ondan sonrakiler doğru geliyor. Sıcaklığı sensörden değiştir yine ikincide doğru değer yerine geliyor. Bunu önlemek için ekana vermeden iki defa sıcaklık okuma komutu vermeme rağmen ilk değer mutlaka yine 85 geliyor. Bir başka program daha yazmıştım . Onda sistem doğru çalışıyor. Aslında bu şekilde bir sorun olmasın diye sensörlerin programın başında bir kere açılması (intialize) edilmeleri gerekiyor. Bunu yapınca diğer program tek seferde okuyor ama bu okumuyor. Aralarında bir komut farklılığı da yok. Sebebini anlamış değilim. Bulursam burada yazarım. Diğer program kodları çok karmaşık bir sürü başka işlerde yaptığı için buraya koymadım. Ama emin ol okuma kodları aynı.
Var bir sebebi ama henüz bulamadım. Muhtemelen 1-wire protokolü ile ilgli bir sorun ama araştırıyorum.

REP 32\20 şu anlama geliyor. "REP" ingilizce REPEAT yani tekrarla kelimesinden gelen bir komut. Neyi tekrarlayacak bir sonraki karekteri. Oda 32 yani "space" boşluk karekteridir. \20 ise kaç defa tekrarlanacağını belirliyor. 20 defa. Bu komut ekranın ilgili satırına 20 adet boşluk karekteri yazar. yani o satırı siler (20 karekter/satır LCD ler içindir.)
"STR ID\8" ifadesi ise dizi değişkenleri için kullanılan bir komuttur. STR ve ardından gelen ifade ID bir dizi değişkenini tanımlıyor. Programın başında ID VAR BYTE[8] şeklinde bir dizi değişkeni tanımlamış idik.
Buradaki komut "STR ID\8" bu dizi elemanlarını verir.
Komutun açık karşılığı tam tamına şöyledir;
ID(0),ID(1),ID(2),ID(3),ID(4),ID(5),ID(6),ID(7)
bukadar kod yazmak yerine STR ID yani string ID yani ID Dizisi diyorsun ve \8 ibareside dizinin kaç elamanını sıradan vereceksin onu belirliyor. Burada 8 veridiğine göre sıfır dahil 7 ye kadar toplam 8 eleman verilmiş oluyor.

Umarım anlaşılmıştır.
Ete
Bilgi hazinedir paylaştıkça büyür.            http://etepic.com