Elektronik / Mikrodenetleyici Projeleri/

AT89C51 ve DS1621 Sıcaklık Sensörlü Termometre

Sponsorlu Bağlantılar

Termo metre devresinin ç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ı

/******************************************************/
/* 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);
		
}

Projeyi Hazırlayan: Şenol KAHRAMAN Dosyalar AT89C51 ve DS1621 Sıcaklık Sensörlü Termometre

Dosya indirme LINK listesi (HTML formatında) link-3399.zip şifre-pass: 320volt.com

Emeği geçen Kişilere Teşekkürler

Sponsorlu Bağlantılar
  • gökhan

    hocam ben bu işte yeni sayılırım hani teorik bilgi var ama pratiğe yeni yeni döküyorum.yazdığınız kodu .hex e dönüştürdükten sonra 89c51 e atamıyorum sanırım boyutu 11K gibi ve boyutu yüksek geliyor.Ne yapmam lazım?

  • Okay

    İyi günler, bu devreyi yapmak istiyorum ancak devre isis de çalışmıyor..DS1 ve DS2 için creavite model hatası alıyorum yardımcı olursanız sevinirim teşekkürler…

  • mustafa

    merhaba şenol hocam ben bir sıcalık ölçme devresi yapmak istiyorum fakat ölçeceğim sıcaklık değerleri -50 ile +400 arası bunun için pt100 sensörü kullanılıyor ama bunu pıc e tanımlaması nasıl yapılır bunu bilmiyorum yardımcı olabilirmisiniz normalde pbp yi kullanıyorum pıc programlamak için teşşekkürler.

  • Mustafa Efe

    SDATA=((output_data&0x80)?1:0);

    Bu satırın görevi nedir? Hangi işlemi gerçekleştiriyor? Anlatabilirmisiniz acaba