ds18b20 sıcaklık sensörü ile ısı okuma

Başlatan tomi, 02 Nisan 2021, 12:21:32

tomi

Merhaba arkadaşlar,
Daha önce asm kodları ile yazdığım ve kullandığım ds18b20 sıcaklık sensörü ile olan proğramı xc8 kodlarına dönüştürmek istedim fakat c de yeniyim,zamanlamalar ds18b20 çok önemli o yuzden xc8 e dönüştürüken birebir çalışan asm kodlarına sadık kaldım fakat bir türlü çalışmadı .Proteus lcd ekranda 25,5 derece sabit olarak gösteriyor yani sensörden okuma yapmıyor.
   Data alma ve göndermede çok kullanışlı oldugu için CARRY bitini kullandım.Sanırım hatam fonksiyon tiplerinde , tecrübe sahibi arkadaşlardan yardım beklerim...KODLAR aşağıda...

/*18f4520 ds18B20  sıcaklık okumak
 * 23.03.2021
 * 
 */
#include <xc.h>
#include <stdint.h>
#include <stdio.h>  // printf için gerekli c standart giriş
//çıkış kütüphanesi

#include "LCD1_lib.h"
#include "LCD1_lib.c"

#define _XTAL_FREQ 4000000

#define tris_sda2 TRISDbits.TRISD2  //ds18b20 için
#define sda2 PORTDbits.RD2          //ds18b20 için

unsigned char sayac=0,c,veri,isi_low,isi_high,sonuc_8bit; 
int i;  

//-----ds18b20 RESET BASI-------------------------------------------  
void ds18b20_reset(void)
{
  unsigned int SAYAA;   
//......................................çıkışı low yapacaz tek hat protokolü geregi
    tris_sda2=0;
    sda2=0;
// ......................................161usn gecikme 
    __delay_us(300);  //161
//........................................giriş yapacaz tek hat protokolü geregi
    tris_sda2=1;
// ........................................16usn gecikme
    __delay_us(70);  //16

    tris_sda2=1;    // port d2 giriş
    SAYAA=0;
    if (sda2==0) 
    {   
        SAYAA++ ;
 //.........................................81usn gecikme
    __delay_us(300);  //81   
    }
    {
//.........................................1usn gecikme
    __delay_us(300);  //1
    }
 //.........................................81usn gecikme
    
    if (SAYAA==0) __delay_us(3);
    if (SAYAA!=0) __delay_us(4);

//ds18b20 RESET SONU------------------------------------------- 
}


//--------ds18b20 DATA GONDER 8 BİT BASI------------------------------------
 
void data_gon_ds18b20(unsigned char veri)
{
  __delay_us(6);
   for (i=0;i<8;i++)
   {
  //.......................................çıkışı low yapacaz tek hat protokolü geregi     
    tris_sda2=0;
    sda2=0;
  //...................................... 3usn gecikmeye girecek  
    __delay_us(5);  //3 
    
      CARRY=0;                            //; care bitini =0 yapıyoruz
    
    asm("rrcf _veri,F");              //; veri_saat tı care ye kaydırıyoruz
    if (CARRY==1)
//.........................................c=1 ise çıkışı=1 yapacaz( data gonderdik)
    {
       tris_sda2=0;
       sda2=1;
       __delay_us(17);    //17  
    }
    else
//.........................................c=0 ise çıkışı=0 yapacaz( data gonderdik)
    {
       tris_sda2=0;
       sda2=0; 
       __delay_us(17);    //17    
    }
//...........................................çıkışı hing yapacaz protokol geregi
       tris_sda2=0;
       sda2=1;    
//............................................17usn gecikme
       __delay_us(17);    //17   
   }
   if (i==7) __delay_us(3);  
    
}
//--------ds18b20 DATA GONDER 8 BİT SONU---------------------------------------  

//--------ds18b20 DATA AL 8 BİT BASI------------------------------------------- 
 
unsigned char data_al_ds18b20(void)

{ 
     __delay_us(6);
    for (i=0;i<8;i++)
    {
// ..........................................çıkışı low yapacaz tek hat protokolü geregi
        tris_sda2=0;
        sda2=0;
// ..........................................6usn gecikme	
        __delay_us(5);  //6
//...........................................çıkışı hing yapacaz tek hat protokolü geregi      
        tris_sda2=1;   // portd.2 giriş
        __delay_us(5); //5
        
        if (sda2==0)      //; data ölçme kısmı
        {
          CARRY=0;  //; C biti=0 yaptık 
         
        asm("rrcf _veri,F");  
 //..........................................33usn gecikme	
          __delay_us(33);  //33       
        }
        else
        {
           CARRY=1;  //; C biti=1 yaptık
          asm("rrcf _veri,F") ;  //veri_saat=(veri_saat>>1);
 //..........................................33usn gecikme	
          __delay_us(33);  //33         
        }
        
    }
    if (i==7) __delay_us(3); 
   
    return (veri);  
}
//--------ds18b20 DATA AL 8 BİT SONU------------------------------------------- 


//--------ds18b20 kur BASI-------------
  

void ds18b20_kur(void)

{ 
    //*************************************************************          
           ds18b20_reset();
    data_gon_ds18b20(0xCC);  //;hafızaya işlem kodunu gönder
    __delay_ms(1);
 //*************************************************************   
    data_gon_ds18b20(0x44);  //;ısı ölçümünü başlat
    __delay_ms(65);  //(65))
 //*************************************************************     
            ds18b20_reset();
    data_gon_ds18b20(0xCC);  //;hafızaya işlem kodunu gönder
    __delay_ms(1);
//*************************************************************     
     data_gon_ds18b20(0xBE);  //;schart registerinde ısıyı oku	
    __delay_ms(65);  //(65))
 //*************************************************************  
      
//--------ds18b20 kur SONU-------------
}

//-------ds18b20 den alınan 16 bit veriyi 8 bit yapma BASI----------
   unsigned char olc_data_8bit_yap(unsigned char isi_low,unsigned char isi_high) //; 16 bit ds18b20 den alınan degeri 8 bit yapacak

/*
 * ; burada  d'16' degeri---> 1 dereceye denk geliyor
; formül--> ısı degeri=x/16 olacak.Yani sonuçta ölçülen degeri d'16' bölecez.
; ölçülen degerler: isi_hing ve isi_low   dır.
; 16 ya bolmek için sadece sayıyı 4 defa saga kaydıracaz
; veya kaydırmayada gerek yok direkt son 4 biti ilk 4 bite aktaracaz
; Not her saga kaydırmada degeri 2 ye bolmuş ve aynı zamanda
; her sola kaydırmadada 2 ile çarpmış oluyoruz.
 */
{   
  
   isi_low=(isi_low&0xF0)>>4 ; 
   isi_low=(isi_low&0x0F);
   
   isi_high=(isi_high&0x0F)<<4;
   isi_high=(isi_high&0xF0);
   
    isi_low=(isi_high)|(isi_low);  // 8 BİT VERİ isi_low A YUKLENDİ 
    sonuc_8bit=isi_low;
    return sonuc_8bit ;
}  
 //-------ds18b20 den alınan 16 bit veriyi 8 bit yapma SONU----------  
   
    void main(void) 
{
        
    ADCON1=0x0F; // hepsi dijital çıkış oldu
    
    TRISA=0b00000000; TRISC=0b00000000;
    TRISB=0b00000000; TRISD=0b00000000;
    TRISEbits.RE0=0;  TRISEbits.RE2=0;
    TRISEbits.RE1=0;
       
    PORTA=0x00; PORTC=0x00; PORTE=0x00;
    PORTB=0x00; PORTD=0x00; PORTD=0x00;

          lcd_kur(); 
  
       
        
          while(1)
       {
          
          lcd_gotoxy(1,1);
          lcd_yaz("    SICAKLIK    ");
          
 
                     ds18b20_kur();
           data_al_ds18b20();
                   isi_low=veri;            //ilk 8 bit alındı
           data_al_ds18b20();
                   isi_high=veri;           // 2. 8 bit alındı
                   
                  olc_data_8bit_yap(isi_low,isi_high); // 16 bit 8 bit dönüşecek
                  k=sonuc_8bit;
            
 //--------------------------------------------------------                  
                lcd_gotoxy(2,3);

           lcd_yuzlerhane_gon(k);
           lcd_onlarhane_gon(k);         
           c=',';
           lcd_veri_gon(c);
           lcd_birlerhane_gon(k);
 //--------------------------------------------------------              
           c=0b11011111;                              // derece karakteri için
           lcd_veri_gon(c);
           
            lcd_gotoxy(2,10);
            lcd_yaz("DERECE");
      
     
       }
      
 }     
       

tomi

Merhaba arkadaşlar,
 sorunu çözdüm, okuyan ilgilenen herkese teşekkür ederim.

OG

FORUMU İLGİLENDİREN KONULARA ÖM İLE CEVAP VERİLMEZ.

tomi

#3
hiç kimse nasıl yaptın diye sormadı ama ben yine de söyleyeyim .Yukarıda vermiş olduğum kodlar doğru sadece data alma ve data gönderme fonksiyonlarının başına __delay_us(6); , 6 mikro saniye gecikme koydum çalıştı.
    Eğer kullanmak isteyen arkadaşım varsa kodları bu şekilde kullanabilir.
not: yukarıdaki kodlara ilave komutu ekledim.

Sozuak

#4
Herkes spesifik bir konu/durum ile ilgili bilgi sahibi olmayabilir. Cevap gelmedi diye posta koyar gibi hallettim hoşçakalın demek biraz ön yargılı yaklaşmak gibi.
Forumlarda her sorulan soruya bir cevap gelir diye zorunluluk yok, hem gönüllülük esas hem de bilen birisi konu gerilere düşse görmeyebiliyor zira her konuyu sırayla gezen  ve hiçbirini atlamayan insanlar nadirdir.

Küsmek yerine değer oluşturacak paylaşımları karşılıksız yapmaya başlarsanız çok daha güzel olur. Buradaki sakinlerin yaptığı da budur, sadece size denk gelmemiş.  Ben de zamanında benzer hataya düştüm ama insanların aslında öyle olmadıklarını fark edince hemen geri adım attım. Aslında alıngan olduğum zamanlar/konular olabiliyor bu biraz kişilik biraz yaş ile alakalı.

OG

+
kendi yazdığım eski bir kodda bir şeyler yapmak istesem
bazen yarım saat incelemme gerekiyor, ne yapmışım diye

size yardımcı olacak birisinin, o an, sizin yazdığınızı incelemeye vakti olmayabilir
FORUMU İLGİLENDİREN KONULARA ÖM İLE CEVAP VERİLMEZ.

Yuunus

kendi actigim konudaki sordugum soruya cevap vermisligim coktur bu forumda, benim isim hallolmustur artik ama ayni sorunla karsilasan baska birine ipucu olabilir.Birde su sorun var kendimde yapmisimdir bunu, carsaf gibi kodu incelemek gercekten insani zorluyor hele birde cogu kutuphanenin kodlari ise, sorun olusan durum nere ise tam olarak orayi soru olarak sorarsak daha cabuk cevap alabiliriz, yoksa benimde cevap verilmeyen bir suru konu acmisligim var, hatirliyorun birkac tanesi uzunca kod parcasiydi.

tomi

 çok haklısınız, aklın yolu bir..
teşekkür ediyorum yorumlarınız için...