AT89C51DS1621 Sıcaklık Sensörlü Termometre devresi

Projeyi Hazırlayan: Şenol KAHRAMAN Dosyalar at89c51-ds1621-termometre Emeği geçen Kişilere Teşekkürler

Devrenin Çalışması
DS1621 ısı sensörü kullanılarak yapılan dijital termometre devresini anlatacak olursam. Devrenin çalışması basit olarak şöyle; Isı algılayıcısından alınan sayısal değer , seri haberleşme protokolü olan I2C yardımıyla mikrodenetleyiciye gönderiliyor ve mikrodenetleyicide bu değeri LCD ye basıyor.Biraz daha açacak olursam mikrodenetleyici sensörden aldığı 16 bitlik datayı içerisinde yorumlayarak LCD ye aktarıyor.

Dallas firmasının üretmiş olduğu DS1621 sensörü, +125 ile –55 derece arasında ölçüm yapabiliyor. Sensörün kullanıcı tarafından belirlenen yüksek ve alçak ısı değerlerini haber vermesi için iki adet register bulunuyor. Ortamdan algılanan ısı mikrodenetleyiciye 16 bit olarak aktarılıyor, yazılan programa göre de yorumlanarak LCD ye gönderiliyor.

Mikrodenetleyici ile DS1621 entegresi arasındaki iletişimi I2C seri haberleşme protokolü sağlıyor.I2C protokolünde ana görevi gören mikrodenetleyici,uydu olarak adlandırılan ısı sensörleri ile RxD ve TxD seri haberleşme hatları üzerinden iletişim kuruyor.DS1621 entegresinde SDA ucu mikrodenetleyicinin P3_0 ucu ile veri alım ve gönderimi için kullanılırken DS1621 in SCL ucu mikrodenetleyicinin P3_1 ucu ile gerekli olan saat darbesini oluşturmak için kullanılıyor.

Devrede Kullanılan Malzemeler ve Fiyatları

  • AT89C51 : 3 YTL
  • 16×2 LCD : 8 YTL
  • 2 adet DS1621 entegresi : 12 YTL
  • 12 mhz kristal+8.2kdirenç+10mf kondansatör : 1 YTL
  • 7805 regülatör : 50 kuruÅŸ

tüm devre yaklaşık olarak 30 YTL ye mal oldu.

Dallas 1621 Isı Algılayıcısı Hakkında Bilgi
DS1621’in ölçüm aralığı -55ºC ile +125ºC arasındadır. Bu entegre 0.5’lik bir hassasiyetle ölçüm yapmaktadır. Ölçülen değerler iki baytlık değer olarak mikrodenetleyiciye gönderiliyor.

ds1621 üst bayt alt bayt sıcaklık
Tablo 1. Okunan alt ve üst baytların desimal karşılıkları

Ölçüm değerleri Tablo 1’de görülmektedir. Alt baytın 7. bitinin 1 olması, 0,5’lik ondalığı ifade etmektedir. Üst baytın 7. biti 0 ise, sıcaklığın 0’dan büyük veya eşit olduğu, 7. bit 1 ise sıcaklığın 0’ın altında olduğu anlamına gelir. Bu durumda üst baytın komplementi alınıp 1 eklenerek sonuç hesaplanmaktadır.

DS1621 entegresi ve pin görünüşü
ds1621 pin bağlantı açılımı bilgileri

Mikrodenetleyici ile DS1621 entegresi I2C seri iletişim yöntemiyle haberleşmektedir. Şekil 3’deki devre şemasında görüldüğü gibi entegre, SData ve SClock olmak üzere pull up yapılmış iki kablo ile mikrodenetleyici’ye bağlanmıştır. Ayrıca bu entegrenin 3 bitlik adres pinleri bulunmaktadır. A0, A1 ve A2 pinleri adres belirlemede kullanılır. Bu adresleme sayesinde birden fazla sıcaklık entegresini (DS1621’de en fazla 8 ) aynı hat üzerinden bağlamak mümkündür.

Devrenin açık şeması
atmel at89c51 dc1621 termometre devre şeması

I2C Entegreler arası seri haberleşme Protokolü Hakkında Bilgi
Bu yöntemde her bir clock ile karşı tarafa 1 bit bilgi gönderilir veya alınır. Bu bitler 1 baytlık paketler halinde adres veya komut olarak gönderilir, datalar alınır. Şekil 4’deki görüntü, simülasyon programıyla elde edilmiştir.

i2c spy adres komut data
Şekil 4. I2C adres, komut ve dataların akışı.

Program kodumuz genel olarak alt programlardan oluşmaktadır. Böylece daha basit ve anlaşılır olması sağlanmıştır. mikrodenetleyicimizin portlarının kurulumu, LCD’nin kurulumu ve DS1621’in kurulumunun ardından belirli aralıklarla sıcaklık değeri okunuyor ve LCD’de gösteriliyor .

Åžekil 4’de de görüldüğü gibi ilk olarak gönderilen ‘10010001′ adres bilgisidir. Böylece birden fazla DS1621 baÄŸlı sistemde adresi 000 olarak ayarlanan entegrenin dikkati çekilmiÅŸ olacaktır. Bizim devremizde sıcaklık entegremizin A0-A2 uçları topraÄŸa baÄŸlı olduÄŸundan, gönderilen komut ile bu entegre ilgilenecektir. EÄŸer devremizde 3 tane sıcaklık entegresi bulunuyor olsaydı, 3. entegreye komut göndereceÄŸimiz durumda adres bilgimiz ‘10010101’ ÅŸeklinde olacaktı.

Adresin hemen ardından komut baytı gönderilmektedir. Bu bayt, okunacak bilginin alt bayt mı, üst bayt mı olduğunu belirliyor. Hemen ardından tekrar adres baytı, bu sefer bilgiyi oku emrini veriyor. Ardından ölçülen değer okunarak bir kaydedicide tutuluyor. Aşağıda alt ve üst baytların okunması için gerekli adres, komut ve data akışları görülmektedir.

  • 10010001 › 000 olarak adreslenmiÅŸ olan entegreye yaz
  • 10101010 › komut yaz (son ölçülen deÄŸeri oku)
  • 10010000 › 000 olarak adreslenmiÅŸ olan entegreden oku
  • 00010010 › Üst bayt olarak gelen bilgi (18)
  • 10001000 › Alt bayt olarak gelen bilgi (.5)

Termometre Programı

#include <89c51rd2.H>
#include <STDIO.H>
#include <math.h>
#define SDATA P3_0
#define SCLK  P3_1
//-----------------------------------------------------------------------
//LCD FONKSIYONLARI
//-----------------------------------------------------------------------
void gecikme(long int sure)//gecikme rutini
{
long int i;
for (i=1;i<=sure;i++)
{;}
}
void datakomut(int komut)//LCD komut rutini
  {
  P2_0=0;
  P2_1=0;
  P2_2=1;
  P1=komut;
  P2_2=0;
  gecikme(1000);
  }
void dataveri(char veri[],long int hiz)  //LCD yazma rutini
{
int i;
while(veri[i]!=0)
  {
  P2_0=1;
  P2_1=0;
  P2_2=1;
  P1=veri[i];
  P2_2=0;
  i++;
  gecikme(hiz);
  }
}
void LcdAc()  //LCD kurma rutini
  {
int baslangic[]={12,52,4},t;
  for(t=0;t<3;t++)
  datakomut(baslangic[t]);
  }
//------------------------------------------------------------------------
// I2C Fonksiyonlari
//------------------------------------------------------------------------
void i2c_start (void)
{
  SDATA = 1;  // veri hattini 1 yap
  SCLK = 1;  // clock hattini 1 yap
  SDATA =0;  // data hattini 0 yap (START SIGNAL)
  SCLK =0;  // clock hattini 0 yap
}

void i2c_stop (void)
{
  unsigned char input_var;

  SCLK =0;// clock hattini 0 yap
  SDATA =0;// data hattini 0 yap
  SCLK =1;// clock hattini 1 yap
  SDATA =1;// data hattini 1 yap (STOP SIGNAL)
  input_var = SDATA;// port pin into HiZ
}

void i2c_write (unsigned char output_data)
{
  unsigned char index;

  for(index = 0; index < 8; index++)// I2C yoluna 8 bit gönder
{
SDATA=((output_data&amp;amp;amp;0x80)?1:0);
output_data  <<= 1;// byte i bir bit kaydir
SCLK =1; // veriyi I2C yoluna saatle
SCLK =0;
  }

  index=SDATA;  // veri pinini okuma moduna koy
  SCLK =1;   // I2C yolundan ACK yi saatle
  SCLK =0;
}
unsigned char i2c_read (void)
{
  unsigned char index, input_data;
 index = SDATA;  // veri pinini okuma moduna sok

  input_data = 0x00;
  for(index = 0; index < 8; index++)// I2C yoluna 8 bit gönder
  {
input_data <<= 1; // byte i 1 bit kaydir
SCLK =1;   // I2C   yoluna veriyi saatle
input_data |= SDATA;   // I2C yolundan veriyi al
SCLK =0;
  }
   return input_data;
}
float basla1(void)
  {
  float deger=0;
  int alinan1=0;
  int alinan2=0;
  i2c_start();i2c_write(0x90);i2c_write(0x22);i2c_stop();
  i2c_start();i2c_write(0x90);i2c_write(0xee);i2c_stop();
  i2c_start();i2c_write(0x90);i2c_write(0xaa);i2c_start();i2c_write(0x91);alinan1=i2c_read();i2c_start();i2c_write(0x91);alinan2=i2c_read();i2c_stop();
  if(alinan1 >=0x80) alinan1-=0xff+1;
  if(alinan2==0x80)  deger=alinan1+0.5;
  else
  deger=alinan1;
  gecikme(200);
  return deger;
  }
float basla2(void)

{
  float deger2=0;
  int alinan3=0;
  int alinan4=0;
  i2c_start();i2c_write(0x92);i2c_write(0x22);i2c_stop();
  i2c_start();i2c_write(0x92);i2c_write(0xee);i2c_stop();
  i2c_start();i2c_write(0x92);i2c_write(0xaa);i2c_start();i2c_write(0x93);alinan3=i2c_read();i2c_start();i2c_write(0x93);alinan4=i2c_read();i2c_stop();
  if(alinan3 >=0x80) alinan3-=0xff+1;
  if(alinan4==0x80)  deger2=alinan3+0.5;
  else
  deger2=alinan3;
  gecikme(20);
  return deger2;
  }
char d[40];
void main (void)
{
  float derece1;
  float derece2;
  LcdAc();
derece1=basla1();
derece2=basla2();
datakomut(1);
sprintf(d,"%1.1f'C  %1.1f'C",derece1,derece2);
dataveri(d,1000);
gecikme(2000);

}