
Projeyi Hazırlayan: Şenol KAHRAMAN Dosyalar at89c51-ds1621-termometre Emeği geçen Kişilere Teşekkürler
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.
tüm devre yaklaşık olarak 30 YTL ye mal oldu.
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.

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.

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ı
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.

Ş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.
Termometre Programı
/******************************************************/ /* Uygulama Adı : Termometre Uygulaması */ /* Dosya Adı : Termometre */ /* Tarih : Nisan 2005 */ /* Hedef İşlemci: MCS-51 */ /* */ /******************************************************/ // Başlık dosyaları //----------------------------------------------------------------------- #include <89c51rd2.H> #include#include #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; // Put 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&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); }
Yazar: gevv Tarih: 17/10/2008 Etiketler: AT89C51, atmel, DS1621, haberleşme Protokolü, I2C, lcd, Sıcaklık Sensörü, Termometre
Yorumlar