One wire haberleşmesinde neden bekleme yapılıyor ?

Başlatan baran123, 01 Ocak 2015, 22:03:56

baran123

Ds18b20.c yi kurcalarken içindeki one wire komutları arasında bekleme olduğunu fark ettim bunun sebebi nedir merak ettim bekleme yapmassak problem oluşur mu ?

#define ONE_WIRE_PIN PIN_C0

void onewire_reset() 
{
   output_low(ONE_WIRE_PIN);
   delay_us(500); // örneğin bu satır ?
   output_float(ONE_WIRE_PIN);
   delay_us(500); 
   output_float(ONE_WIRE_PIN);
} 

void onewire_write(int data)
{
   int count;
   for (count=0; count<8; ++count)
   {
      output_low(ONE_WIRE_PIN);
      delay_us(2);
      output_bit(ONE_WIRE_PIN, shift_right(&data,1,0)); 
      delay_us(60);
      output_float(ONE_WIRE_PIN); 
      delay_us(2); 
   }
} 

int onewire_read()
{
   int count, data;
   for (count=0; count<8; ++count)
   {
      output_low(ONE_WIRE_PIN);
      delay_us(2);
      output_float(ONE_WIRE_PIN);
      delay_us(8);
      shift_right(&data,1,input(ONE_WIRE_PIN)); 
      delay_us(120);
   }
   return(data);
} 

float ds1820_read()
{
   static int1 ds_flag=0;
   int8 busy=0, temp1, temp2; 
   signed int16 temp3; 
   static float result; 
   
   if(ds_flag==0)
   {
      onewire_reset(); 
      onewire_write(0xCC); 
      onewire_write(0x44); 
      ds_flag=1;
   }
   
   else
   {
      busy = onewire_read(); 
      if(busy==0)return result;
   }
   
   ds_flag=0;
   onewire_reset(); 
   onewire_write(0xCC); 
   onewire_write(0xBE); 
   temp1 = onewire_read(); 
   temp2 = onewire_read(); 
   temp3 = make16(temp2, temp1); 
   
   result = (float) temp3 / 16.0;
   
   return(result); 
}

Kabil ATICI

Bu tür iletişimde kontrol zamanlamalar ile yapılıyor.( Asenkron haberleşme)

İstiyorsan o zamanlama değerlerini timer ile yapabilirsin. Sonuçta olacak iş yine o gecikmelerin sağlaması olarak.

Ds18b20 veri kağıdındaki zamanlama çizimleri incele...
ambar7

LukeSkywalker

#2
Baska bir konuda bu  kutuphanede bekleme olmuyor demissiniz ama nasil bekleme olmadigini tam anlamadim. Mesela ds_flag degiskeni ne zaman 1 olacak?

baran123

Evet beklemesiz kütüphane diye geçiyor ama beklemeler var yinede bu kafamı karıstırdı

Mucit23

Hayır bekleme olmuyor. Benzer bir mantığı bende kendi projemde kullanmıştım. Bekleme olduğunu düşündüğün yer neresi?

baran123

hocam delay_us var bir kaç yerde o kısımlarda bekleme olmuyor mu ?

Mucit23

Baran Ekrem o ayrı. Asenkron haberleşme yapısı gereği o delay lar olmak zorunda.

DS18B20 için Asıl bekleme sıcaklık dönüşümü esnasında yapılır. Normalde Sıcaklık dönüşümü için start verdikten sonra 12 bit çözünürlük için dönüşüm işlemi yaklaşık 700ms de tamamlanır. Normalde  Busy=1 olana kadar bekleme yapılırdı. Busy 1 olmuşsa dönüşüm tamamlanmış anlamına gelir ve sıcaklık okuması yapılırdı. Busy'nin 1 olması yakaşık 700ms boyunca sürdüğü için 700ms boyunca program çakılıp kalırdı. işte yukarıdaki kodlarda o 700mslik bekleme yapılmıyor.

baran123


sadogan

Başka bir işlevi de içerdeki kapasitorun dolmasına olanak tanımak.

LukeSkywalker

ds_flag ilk başta 0 değerini almış. Böylece hemen if şartına giriyor. İf şartında ds_flag=1 yapılıyor. else kısmına hiç uğramıyor. Hemen altta tekrar 0 yapılıyor. else içerisine ne ara girecek bu program?

Mucit23

Alıntı yapılan: LukeSkywalker - 02 Ocak 2015, 08:42:47
ds_flag ilk başta 0 değerini almış. Böylece hemen if şartına giriyor. İf şartında ds_flag=1 yapılıyor. else kısmına hiç uğramıyor. Hemen altta tekrar 0 yapılıyor. else içerisine ne ara girecek bu program?
@LukeSkywalker
ds_flag ilk basta 0 verilmemesi gerekiyor.  Orda bi hata olcak.

LukeSkywalker

#11
Bence bu kod hatalı. Algoritma değişmeli.

mesaj birleştirme:: 02 Ocak 2015, 12:24:35

#define ONE_WIRE_PIN PIN_C0

void onewire_reset()
{
   output_low(ONE_WIRE_PIN);
   delay_us(500); // örneğin bu satır ?
   output_float(ONE_WIRE_PIN);
   delay_us(500);
   output_float(ONE_WIRE_PIN);
}

void onewire_write(int data)
{
   int count;
   for (count=0; count<8; ++count)
   {
      output_low(ONE_WIRE_PIN);
      delay_us(2);
      output_bit(ONE_WIRE_PIN, shift_right(&data,1,0));
      delay_us(60);
      output_float(ONE_WIRE_PIN);
      delay_us(2);
   }
}

int onewire_read()
{
   int count, data;
   for (count=0; count<8; ++count)
   {
      output_low(ONE_WIRE_PIN);
      delay_us(2);
      output_float(ONE_WIRE_PIN);
      delay_us(8);
      shift_right(&data,1,input(ONE_WIRE_PIN));
      delay_us(120);
   }
   return(data);
}

float ds1820_read()
{
   static int1 ds_flag=1;
   int8 busy=0, temp1, temp2;
   signed int16 temp3;
   static float result;

   if(ds_flag==1)
   {
      onewire_reset();
      onewire_write(0xCC);
      onewire_write(0x44);
      ds_flag=0;
   }

   if(ds_flag==0)
   {
      busy = onewire_read();
      if(busy==0)return result;
      else ds_flag=1;
   }
   onewire_reset();
   onewire_write(0xCC);
   onewire_write(0xBE);
   temp1 = onewire_read();
   temp2 = onewire_read();
   temp3 = make16(temp2, temp1);

   result = (float) temp3 / 16.0;

   return(result);
}


Böyle olursa düzgün çalışır diye düşünüyorum.

baran123

@LukeSkywalker hocam denedim düzgü çalışıyor bir problem yok gibi

LukeSkywalker

Benim yazdığım kod mu diğeri mi düzgün çalışıyor?
İlk senin verdiğin kodlarda sıcaklık değerlerinde ani sıçramalar falan meydana gelir.

baran123

Evet normalde ani sıcramalar oluyor du sürekli alarm kullandım mı çok sorun yaratıyordu sizin verdiğiniz kodlar gayet stabil teşekkürler.