Haberler:

Foruma Resim Yükleme ve Boyut Sınırlaması ( ! )  https://bit.ly/2GMFb8H

Ana Menü

Stm32F4 ile ds18b20 sorunu

Başlatan EMP_Otto, 04 Ekim 2013, 11:31:31

EMP_Otto

Merhaba arkadaslar.Bu aralar onewire protokolünü öğrenmeye çalısıyorum.Ds18b20 sicaklik sensörüyle sıcaklik okumaya calısıyorum ama bir türlü doğru sonuc elde edemedim.Kullandıgım kodlar aşagıda acaba nerde hata yapıyorum.

ds18b20.c
#define giris 0
#define cikis 1
#define data_pini GPIO_Pin_10
#define data_portu GPIOD
/*
 * ROM Command
Read ROM------------[33H]
Match ROM-----------[55H]
Skip ROM------------[CCH]
Search ROM----------[F0H]
Alarm search--------[ECH]

 Function Command
Write Scratchpad----[4EH]
Read Scratchpad-----[BEH]
Copy Scratchpad-----[48H]
Convert Temperature-[44H]
Recall EPROM--------[B8H]
Read Power supply---[B4H]
*/
//-----------------------------------------------------------------------------------//
uint32_t sayac;
void delay_ms(uint32_t delay)
{
SysTick_Config(SystemCoreClock/1000);// 1 ms
sayac=0;
while(sayac!=delay);

}

void SysTick_Handler(void)
{
sayac++;
}
void delay_us(uint32_t delay)
{
	SysTick_Config(SystemCoreClock/1000000);//1 us elde etmek icin
        sayac=0;
	while(sayac!= delay);
	
}

//-------------------------------------------------------------------------------------//

GPIO_InitTypeDef pin;

void pin_konum(int veri)
{
	if(veri) // cikis
	{
     pin.GPIO_Mode=GPIO_Mode_OUT;
     GPIO_Init(data_portu,&pin);
	}
	if(!veri) // giris
	{
	pin.GPIO_Mode=GPIO_Mode_IN;
	GPIO_Init(data_portu,&pin);
	}
}

void ds18b20_pin_init()
{   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD,ENABLE);
	pin.GPIO_Mode=GPIO_Mode_OUT;
	pin.GPIO_OType=GPIO_OType_PP;
	pin.GPIO_PuPd=GPIO_PuPd_NOPULL;
	pin.GPIO_Speed=GPIO_Speed_100MHz;
	pin.GPIO_Pin=GPIO_Pin_10;  //Data pini
	GPIO_Init(GPIOD,&pin);
}
void output_high()
{
GPIO_SetBits(data_portu,data_pini);

}
void output_low()
{
GPIO_ResetBits(data_portu,data_pini);
}
//////////////////////////////////////////////////////////////////////////////////
int  onewire_ready()
{      int sonuc;
	// ds18b20_pin_init();
	   pin_konum(cikis);
	   output_low();
       delay_us(480);
       pin_konum(giris);
       delay_us(70);
       sonuc=(!GPIO_ReadInputDataBit(GPIOD,data_pini));  //1 dönerse hatta cihaz var 0 dönerse hatta cihaz yok
       delay_us(400);
return sonuc;
}
////////////////////////////////////////////////////////////////////////////////////
void onewire_write(uint16_t data)
{
	int i=0;
	char bit=1;
	for(i=0;i<8;i++)
	{
      if(data & bit) // Bit degeri 1 ise= 1 yazmak icin
      {
       pin_konum(cikis);
       output_low();
       delay_us(10);
       pin_konum(giris);
       delay_us(60); //pull up yukselmesi icin bekle

      }
      else         // Bit degeri 0 ise =0 yazmak icin
      {
    	  pin_konum(cikis);
    	  output_low();
    	  delay_us(60);
    	  pin_konum(giris);
    	  delay_us(10);// pull up yukselmesi icin bekle
      }
      bit=bit<<1;
	}
}

char  onewire_read_bit()
{
	char sonuc;
	pin_konum(cikis);
	output_low();
	delay_us(10);
	pin_konum(giris);
	delay_us(5);
    sonuc=(GPIO_ReadInputDataBit(data_portu,data_pini));
    delay_us(50);
   return sonuc;
}

uint16_t  onewire_read()
{
 char data[9];
 int i=0;
 for(i=0;i<9;i++)
 {
	 data[i]=onewire_read_bit();
 }
 data[8]=0;
return data;
}
float ds18b20_read()
{       float sicak;
        float onda=0;
	    uint8_t lsb,msb;
	    float result;
        onewire_ready();
	    onewire_write(0xCC);//Skip rom
	    onewire_write(0x44);//Convert
        onewire_ready();
	    onewire_write(0xCC);//Skip rom
	    onewire_write(0xBE);//Read Scratchpad
	    lsb = onewire_read();//ilk düsük degerlikli bitler okunur
        msb=onewire_read();

        sicak=(msb<<4)+(lsb>>4);
        sicak=sicak/16;
        if(lsb & 0x08) onda =0.500;
        if(lsb & 0x04) onda+=0.250;
        if(lsb & 0x02) onda+=0.125;
        if(lsb & 0x01) onda+=0.0625;
        sicak=sicak+onda;
        return msb;
}
void ds18b20_resolution(int resolution)
{
	switch (resolution)
	    {
	        case 9: resolution = 0x1F; //9 bit
	            break;
	        case 10: resolution = 0x5F; //10 bit
	            break;
	        case 11: resolution = 0x3F; //11 bit
	            break;
	        case 12: resolution = 0x7F; //12 bit
	            break;
	        default: resolution = 0x7F; //12 bit
	    }

	    onewire_ready();
	    onewire_write(0xCC);//Skip rom
	    onewire_write(0x4E);
	    onewire_write(resolution);
}

main.c

#include "stm32f4xx_gpio.h"
#include "stm32f4xx_rcc.h"


void pin_config()
{
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD,ENABLE);
GPIO_InitTypeDef pin;
pin.GPIO_Mode=GPIO_Mode_OUT;
pin.GPIO_Speed=GPIO_Speed_50MHz;
pin.GPIO_Pin=GPIO_Pin_15;
GPIO_Init(GPIOD,&pin);
}
int main(void)
{  pin_config();
   ds18b20_pin_init();
   ds18b20_resolution(12);
  float sicaklik;

    while(1)
    {
       if(onewire_ready())
       {
          sicaklik=ds18b20_read();
          GPIO_ResetBits(GPIOD,GPIO_Pin_15);

       }
       else
       {
          GPIO_SetBits(GPIOD,GPIO_Pin_15);
       }

    }

}

maini eklemeyi unutmusum
Sormak istediğim bir şey daha var  ;D Read scratchpad komutunu verdiğimde bana 9 bitlik bir deger gelecek değil mi?(Crc dahil 9 bit )

The data transfer starts with the least significant bit of byte 0 and continues through the scratchpad until the 9th byte (byte 8 – CRC) is
read.(Datasheet  10 sayfa )

https://www.picproje.org/index.php/topic,36356.msg261769.html#msg261769     @mcan hocam onewire_read fonksiyonuyla 8 bit okuyor ama ??Nasıl oluyorda dogru calısıyor.
Bu işler zordur,özveri ister...

EMP_Otto

Arkadaslar amacım bir yerler hazır kodları bulup calıstırıp ds18b20 yi calıstırdım demek değil.OneWire protokolünü ögrenmek istiyorum.Forumdaki neredeyse tüm örneklere baktım ama işe yaramadı.Bir türlü doğru düzgün okuyamıyorum.
Yaptıklarımı adım adım yazıyorum;

1-Reset palsi gönderiyorum.Palse cevap gelirse ikinci adıma geçiyorum.
2-Skip rom komutu gönderiyorum.(Tek cihaz bağlı oldugu icin sorun olmuyor.)
3-Convert komutu gönderiyorum.
4-Sensörü okumak istediğimde reset palsi gönderiyorum.palse cevap gelirse Read Scratchpad komutunu gönderip hemen onewire_read komutu ile 9 bitlik veri okuyorum.(8. bit crc oldugu için data[8]=0 diyerek crc yi kullanmıyorum şimdilik)Ard arda iki kez okuma yapıyorum ama sacma sacma degerler okuyorum.

*Sensöre reset pulse gönderince cvp geliyor.Acaba zamanlamada mı bir sıkıntı var.Ama zamanlamada sıkıntı olsa  daha önce 16x2 lcd calısmazdı.Ondada aynı zamanlama kodlarını kuıllandım.

Yardımcı olursanız cok sevinirim.Kolay gelsin...
Bu işler zordur,özveri ister...

EMP_Otto

Yok mu yardımcı olabilecek arkadaş :'( :'(
Bu işler zordur,özveri ister...


EMP_Otto

#4
@MC_Skywalker   baktımda hocam  kodları indiremedi.Yine de cok sagolun .

Merhaba arkadaslar.Yazdığım kodlardaki sıkıntıyı bir türlü çözemedim.Daha önce forumda yazılmıs örneklerden birini denedim.delay olarak kendi yazdıgım kodları kullandım ve calıstı ;D Delay fonksiyonu doğru calısıyor yani.Kullanmak isteyenler kullanbilirler.

Acaba ben nerde hata yapıyorum bir türlü anlamadım gitti.
Arkadaslar OneWire protokolünde mantık basitmiş
1-ilk olarak reset palsi gönderiyoruz eger cevap gelirse ikinci adıma geciyoruz
2-Önce rom komutu gönderiyoruz(Ben skip rom komutunu kullandım (0xCC))
3-Sonra Fonksiyon komutu gönderiyoruz.Convert komutu(0x44) göndererek ortam sıcaklıgının cevrilerek th tl registerlerine yazılmasını istiyoruz.
Eğer ds18b20 yi 12 bit olarak kullanıyorsanız convert işlemi max 750 ms sürüyormus.(DataSeeet öyle diyor).
4-Sensörün sıcaklık cevrimini bitirdiğini düşünerek okumaya geciyoruz.(Bu arada convert komutu gönderdikten sonra 750 ms den önce okursanız bir önceki sıcaklık degerini okursunuz.)(0xCC)Skip rom komutu gönderiyoruz.(Bu komut 2. maddede belirtiğim rom komutu gönderme işini iptal ediyor.Yani direk olrak fonksiyon komutu göndereceğimi söylüyorum sensöre.)(0xBE) read scratchpad komutuyla 9 byte lık veri okuyorum.

Kafamı karıstıran noktalardan biride buydu.9 byte ı 9 bit diye okumuşum  ;D
Yani siz read scratchpad(0xBE) komutu verince sensör size datasheet 6. sayfadaki memory mapdaki degerlerin hepsini gönderiyor.Ama biz şimdilik sicaklık degerini okumak istedğimiz için ilk iki BYTE ı okuyoruz.Unutmadan ds18b20 ile iletişimde ilk olrak düşük değerlikli bitler gönderilir.Sensörde bize bilgi gönderirken ilk olarak düşük değerlikten başlayarak gönderir.
Bu işler zordur,özveri ister...