Aynı Hatta birden Fazla DS18B20

Başlatan muhittin_kaplan, 25 Ocak 2013, 22:25:33

haydarpasamikro

1-wire protokolünde search rom komutu ile işinizi çözebilirsiniz.
Mikro Dünyası.Haydarpaşa Teknik ve Endüstri Meslek Lisesi Mikrodenetleyici Atl. Şefi

muhittin_kaplan

Anlayamadığım bir nokta var.
0x55 değerini gönderdikten sonra pini input moda sokup dinlemeyecekmiyim ?(hani ID yi gönderecek ya bana)

haydarpasamikro

search rom komutunu akış diyagramında anlatıyor.
Mikro Dünyası.Haydarpaşa Teknik ve Endüstri Meslek Lisesi Mikrodenetleyici Atl. Şefi

muhittin_kaplan

Şöyle sorayım.
Yeni Aldığım bir DS18b20 nin ROM kodunu nasıl öğrenirim ?

haydarpasamikro

ReadROM(33h) ile 8byte id okunur(family+id+crc)
Mikro Dünyası.Haydarpaşa Teknik ve Endüstri Meslek Lisesi Mikrodenetleyici Atl. Şefi

muhittin_kaplan

Yanlış Anlamıyorum değil mi
0x33 gönderip dinlemeye geçeceğim ve 64 bit alacağım.

iyildirim

onewire.c

#include "p30f4011.h"


#define OW_RD         PORTFbits.RF2
#define OW_WR         LATFbits.LATF2
#define OW_TR         TRISFbits.TRISF2

union intChar { signed int iVal; unsigned char cVal[2]; } ;


void delayUs(unsigned int mc)
{
    while(mc--)
    {
    __asm__ volatile ("repeat #15");    //IŞLEMCI HIZINA GÖRE DÜZENLENMELİ
    __asm__ volatile ("nop");
    }
}

void delayMs(unsigned int ms)
{
    while(ms--)
    {
        delayUs(1000);
    }
}


unsigned int OW_Reset()
{
    unsigned char rd;
    OW_WR = 0;
    OW_TR    = 0;
    delayUs(720);

    OW_TR = 1;
    delayUs(70);
    
    rd = OW_RD;        //// 0 - hazır, 1 - hazır değil

    delayUs(480);
    return rd;
    
}


void OW_Write(char data)
{
    unsigned char i, j;
    
    j = 1;
    for (i=0; i<8; i++)
    {

        OW_WR = 0;
        OW_TR = 0;
        delayUs(2);

        if ((data & j))
        {
            OW_WR = 1;
        }
        delayUs(60);
        OW_TR = 1;
        delayUs(2);
        j = j<<1;
    }
}


unsigned char OW_Read()
{
    unsigned char i, j, rd;
    
    rd = 0; 
    j = 1;
    for (i=0; i<8; i++)
    {
        OW_WR = 0;
        OW_TR = 0;  
        delayUs(2);
        
        OW_TR = 1;
        delayUs(;
        
        if (OW_RD == 1) 
            rd |= j;
            
        delayUs(120);
        j = j<<1;    
    }
    return rd;
}


void ds1820_Init()
{
    while(OW_Reset());

    OW_Write(0xCC);    // SKIP ROM
    OW_Write(0x4E);    // WRITE SCRATCHPAD 
    
    OW_Write(125);        //ALARM HIGH 
    OW_Write(-55);        //ALARM LOW
    OW_Write(0b01100000);    // 12 BIT     750ms
//    OW_Write(0b01000000);    // 11 BIT     375ms
//    OW_Write(0b00100000);    // 10 BIT     186ms
//    OW_Write(0b00000000);    //  9 BIT     94ms
    
    
    while(OW_Reset());
    OW_Write(0xCC);    // SKIP ROM
    OW_Write(0x48);    // COPY SCRATCHPAD TO EEPROM  (SAVE)

}

void ds1820_Read_ID(unsigned char *sArr)
{
    
    unsigned char i;
    
    while(OW_Reset());

    OW_Write(0x33);        //READ ROM
    for (i=0; i<8;i++)
    {
        (*sArr) = OW_Read();
        *sArr++;
    }
    
}

void ds1820_Read_Config(unsigned char *sArr)
{
    
    unsigned char i;
    
    while(OW_Reset());
    
    OW_Write(0xCC);        //SKIP ROM  
    OW_Write(0xBE);        //READ SCRATCHPAD 
                                //DS18B20 Power On da  12 bit
    (*sArr) = OW_Read();    //boş okuma 
    (*sArr) = OW_Read();    
    
    for (i=0; i<3;i++)
    {
        (*sArr) = OW_Read();
        *sArr++;
    }
    
}


signed int ds1820_Read_Temp()
{
    
    union intChar tmpVal;
    
    while(OW_Reset());
    
    OW_Write(0xCC);        // SKIP ROM
    OW_Write(0x44);        // START CONVERT 


    delayMs(750);            // Bekleme süresi çözünürlüğe göre ayarlanmalı.. sırasıyla 12,11,10,9 bit için  750, 375, 188 , 95ms 
    
    while(OW_Reset());
    
    OW_Write(0xCC);        //SKIP ROM  
    OW_Write(0xBE);        //READ SCRATCHPAD 
    
    
    tmpVal.cVal[0] = OW_Read();    //READ SCRATCHPAD  Sadece ilk 2 byte taki sıcaklık bilgisini okuyoruz. 
    tmpVal.cVal[1] = OW_Read();

    return (tmpVal.iVal);    // Bu değer çözünürlüğe göre sırasıyla 12,11,10,9 bit için  16, 8, 4 veya 2 ye bölünmeli

    
}

void ds1820_Request_Temp()
{
    
    while(OW_Reset());
    
    OW_Write(0xCC);        // SKIP ROM
    OW_Write(0x44);        // START CONVERT 

}

signed int ds1820_Read_Requested_Temp()
{
    
    union intChar tmpVal;
    
    
    while(OW_Reset());
    
    OW_Write(0xCC);        //SKIP ROM  
    OW_Write(0xBE);        //READ SCRATCHPAD 
    
    
    tmpVal.cVal[0] = OW_Read();    //READ SCRATCHPAD  Sadece ilk 2 byte taki sıcaklık bilgisini okuyoruz. 
    tmpVal.cVal[1] = OW_Read();

    return (tmpVal.iVal);    // Bu değer çözünürlüğe göre sırasıyla 12,11,10,9 bit için  16, 8, 4 veya 2 ye bölünmeli

    
}


main de...
    unsigned char sArr[10];        //DS18B20 ID si için 

    ds1820_Read_ID(&sArr[0]);
    sprintf((char *)&outBuf[0],"DS1820 ID : %02X %02X %02X %02X %02X %02X %02X %02X \r\n\r\n", sArr[0], sArr[1], sArr[2], sArr[3], sArr[4], sArr[5], sArr[6], sArr[7]);
    send_String1(outBuf);

    
    ds1820_Request_Temp();    //Okuma için Ölçümü başlatıyoruz

    // bekleme veya  iş yapalım...
    
    sicaklik = ds1820_Read_Requested_Temp();    //Başlatılmış ölçüm sonucunu okuyoruz. 
            
    sprintf((char *)&outBuf[0],"DS1820 TEMP:%07i%04u \r\n",  (int)(((long)sicaklik*10)>>16), 0);
    
    send_String1(outBuf);


ID ile okuma için hazırda örnek kod yok ama 0x55 ve 8 Byte ID gönderilip okunuyor. Okuma kısmı aynı şekilde..

haydarpasamikro

Aynen öyle. 64 adet sıralı 1-bit okuma slotu kullancağız. Hattı slave aygıtın çektiği seviye bit seviyesidir.
Mikro Dünyası.Haydarpaşa Teknik ve Endüstri Meslek Lisesi Mikrodenetleyici Atl. Şefi

muhittin_kaplan

@iyıldırım
hocam okuyorum sanırım sizin verdiğiniz kodlardaki void ds1820_Read_ID(unsigned char *sArr) fonksiyonunu aldım.Tek bir sensörden okuma yapabiliyorum. ama ROM koduna Ulaşamıyordum.
Şimdi Okuduğum Rom Kodu Üzerinde Çalışayım Biraz.

iyildirim

#24
Hocam denemedim ama söyle bir şey olmalı..
onewire.c ye eklenecek..
void ds1820_Request_TempID(unsigned char *pID )
{
    unsigned char i;
    
    while(OW_Reset());
    
    OW_Write(0x55);   
    for (i=0;i<8;i++)
    {
        OW_Write(*pID);
        *pID++;
    }
    OW_Write(0x44);        // START CONVERT 
}


main' de de şeklinde çağrılmalı..
    unsigned char sArr[10];        //DS18B20 ID si için 

    ds1820_Read_ID(&sArr[0]);
    sprintf((char *)&outBuf[0],"DS1820 ID : %02X %02X %02X %02X %02X %02X %02X %02X \r\n\r\n", sArr[0], sArr[1], sArr[2], sArr[3], sArr[4], sArr[5], sArr[6], sArr[7]);
    send_String1(outBuf);

    ds1820_Request_TempID(&sArr[0])
//    ds1820_Request_Temp();    //Okuma için Ölçümü başlatıyoruz

    // bekleme veya  iş yapalım...
    
    sicaklik = ds1820_Read_Requested_Temp();    //Başlatılmış ölçüm sonucunu okuyoruz. 
            
    sprintf((char *)&outBuf[0],"DS1820 TEMP:%07i%04u \r\n",  (int)(((long)sicaklik*10)>>16), 0);
    
    send_String1(outBuf);

muhittin_kaplan

Hocam Anladığım Daha Önce Ulaştığımız Rom Kodunu 0x55 ile iletip "Sensörün AHa Bu benim Ozman Çevrime Başlayayım -0x44-"  demesini sağlıyoruz.

(
Bu arada Kod yazma Mantığınız Bana Neden Ters Geliyor. Fonksiyona Parametre yerine Pointer gönderip dönüş değerini alıyorsunuz. Ben VB den kalma alışkanlıkla
deger=fonksiyon(parametre) yapıyorum.
Siz ise
fonksiyon(&parametre) yapıyorsunuz. Bir ara bu çalışmanın yararlarını anlatırsanız sevinirim

)

iyildirim

Alıntı yapılan: muhittin_kaplan - 28 Ocak 2013, 00:36:24
Hocam Anladığım Daha Önce Ulaştığımız Rom Kodunu 0x55 ile iletip "Sensörün AHa Bu benim Ozman Çevrime Başlayayım -0x44-"  demesini sağlıyoruz.

(
Bu arada Kod yazma Mantığınız Bana Neden Ters Geliyor. Fonksiyona Parametre yerine Pointer gönderip dönüş değerini alıyorsunuz. Ben VB den kalma alışkanlıkla
deger=fonksiyon(parametre) yapıyorum.
Siz ise
fonksiyon(&parametre) yapıyorsunuz. Bir ara bu çalışmanın yararlarını anlatırsanız sevinirim

)

Hocam,
Sıcaklık okuma için dediğiniz doğru.  Çevrime başladıktan sonra da okunan çözünürlüğe uygun zaman beklenip hazır değer okunuyor..
Zamanında datasheet de birde searchrom diye bir komut gözüme çarpmıştı ama elimde bir tane 1820 olduğundan detayına bakmamıştım.
Belki de birden fazla 18b20 hatta iken de ROM kodları alınabiliyordur.


Bende VB ile uzun yıllar geçirdim.. Zamanla o kadar çok yazılmış hazır kod oldu ki kendime ait bazı ufak tefek işlerimi hala .NET olmayan VB ile yazıyorum..

VB de fonksiyona gönderdiğiniz değerler fonksiyon içerisinde değişiyorsa, fonksiyonun çağrıldığı yerde gönderdiğimiz parametreleri değerleri değişmiş olarak görürüz.. O yüzden fonksiyon(&param1, &param2, &param3, ...)  şeklindeki yazım VB 'ye daha uygun aslında..

C de  fonksiyon tek bir değer döndürecekse ben de deger=fonksiyon(parametre)  şeklinde kullanıyorum..
fonksiyon(&parametre) şeklindeki yazımı C de array vs. döndürürken veya fonksiyon(&param1, &param2, &param3, ...) şeklinde birden fazla parametrenin  değerinin fonksiyon içerisinde değişmesini istediğimde kullanıyorum.. Çağırdığım yerde parametreyi değeri değişmiş görmek istemezsem ve parametre bir array değilse, pointer yerine değişkenin değerini parametre olarak kullanıyorum.. VB deki byref, byval gibi..

Fazla kalabalık olduğunda, fazla parametre varsa, struct yapıp pointerini göndermek de bir yöntem..
Tercihlerin bir kısmı zorunluluk bir kısmı da dediğiniz gibi kullanım alışkanlığı..