﻿/******************************************************************
 PIC16F877 ile DS1621 Sıcaklık ve Termostat Entegresi Uygulaması
*******************************************************************/
#include <16f877.h>     // Kullanılacak denetleyicinin başlık                 // dosyası tanıtılıyor.
#fuses XT,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD // Denetleyici konfigürasyon ayarları

#use delay (clock=4000000) // Gecikme fonksiyonu için kullanılacak osilatör frekansı belirtiliyor.


#define use_portb_lcd TRUE   // LCD B portuna bağlı
#include <lcd.c>

#use i2c(master,sda=pin_c1, scl=pin_c0, slow=100000) // I2C Fonksiyonu,SDA ve SCL pinleri ve iletişim hızı belirleniyor

//***************** DS1621 SICAKLIK OKUMA FONKSİYONU **************************

float ds1621_oku (void)
{
   float th,tl;
   float sicaklik;

   i2c_start();        // i2c iletişimi başlangıç ayarları
   i2c_write(0x90);    // DS1621 entegresine adres ve R/W bit bilgisi gönderiliyor
                       // R/W biti yazma yapılacağı için "0"
   i2c_write(0x22);    // sıcaklık dönüşümünü durdur komutu gönderiliyor
   i2c_stop();         // i2c iletişimini durdur

   i2c_start();        // i2c iletişimi başlangıç ayarları
   i2c_write(0x90);    // DS1621 entegresine adres ve R/W bit bilgisi gönderiliyor
                       // yazma yapılacağından burada R/W biti "0"
   i2c_write(0xee);    // Sıcaklık dönüşümüne başla komutu gönderiliyor
   i2c_stop();

   i2c_start();
   i2c_write(0x90);
   i2c_write(0xaa);    // Sıcaklığı oku komutu gönderiliyor
   i2c_start();
   i2c_write(0x91);    // DS1621 entegresine adres ve R/W bit bilgisi gönderiliyor
                       // okuma yapılacağından burada R/W biti "1"
   th=i2c_read(0);     // sıcaklık değerinin yüksek 8 bitlik değerini oku ve değişkene kaydet
   i2c_start();
   i2c_write(0x91);
   tl=i2c_read(0);     // sıcaklık değerinin düşük 8 bitlik değerini oku ve değişkene kaydet
   i2c_stop();

   if (th>0x80)
      th=th-(0xFF+1);

   if (tl==0x80)      // Eğer sıcaklık değeri buçuklu ise sıcaklığa 0.5 ekle
      sicaklik=th+0.5;
   else
      sicaklik=th; // Eğer sıcaklık değeri buçuklu değilse aynen değişkene kaydet

   delay_ms(50);
   return(sicaklik);   // Fonksiyon "sicaklik" değeri ile geri döner
}

//*************** DS1621 TH'a VERİ YAZMA FONKSİYONU ****************************

void yaz_ds1621_th_tl (byte th_h, byte th_l, byte tl_h, byte tl_l)
{
   i2c_start();       // i2c iletişimi başlangıç ayarları
   i2c_write(0x90);   // DS1621 entegresine adres ve R/W bit bilgisi gönderiliyor
                      // yazma yapılacağından burada R/W biti "0"
   i2c_write(0xa1);   // TH'a erişme komutu gönderiliyor
   i2c_write(th_h);   // TH değerinin yüksek değerlikli byte'ı gönderiliyor
   i2c_write(th_l);   // TH değerinin düşük değerlikli byte'ı gönderiliyor
   i2c_stop();        // i2c iletişimi sonlandırılıyor
   delay_ms(11);      // Belli bir süre bekleniyor

   i2c_start();
   i2c_write(0x90);
   i2c_write(0xa2);  // TL'ye erişme komutu gönderiliyor
   i2c_write(tl_h);  // TL değerinin yüksek değerlikli byte'ı gönderiliyor
   i2c_write(tl_l);  // TL değerinin düşük değerlikli byte'ı gönderiliyor
   i2c_stop();
   delay_ms(11);
}

//******** DS1621 KONFİGÜRASYON KAYDEDİCİSİNE VERİ YAZMA FONKSİYONU ************

void yaz_ds1621_ayar (byte deger)
{
   i2c_start();
   i2c_write(0x90);
   i2c_write(0xac);  // Konfigürasyon kaydedicisine erişme komutu gönderiliyor
   i2c_write(deger); // Konfigürasyon ayar bilgisi gönderiliyor
   i2c_stop();
   delay_ms(11);
}

//************ DS1621 KONFİGÜRASYON KAYDEDİCİSİNİ OKUMA FONKSİYONU *************

byte oku_ds1621_ayar ()
{
   byte con;

   i2c_start();
   i2c_write(0x90);  // DS1621 entegresine adres ve R/W bit bilgisi gönderiliyor
                     // yazma yapılacağından burada R/W biti "0"
   i2c_write(0xac);  // Konfigürasyon kaydedicisine erişme komutu gönderiliyor
   i2c_start();
   i2c_write(0x91);  // DS1621 entegresine adres ve R/W bit bilgisi gönderiliyor
                     // okuma yapılacağından burada R/W biti "1"
   con=i2c_read(0);  // Konfigürasyon kaydedicisi içeriği okunuyor
   i2c_stop();
   return(con);      // Fonksiyon "con" değişkeni değeri ile geri döner
}

char sonuc[17];
byte ayar;

//******************* ANA PROGRAM FONKSİYONU *******************
void main ()
{
   setup_psp(PSP_DISABLED);        // PSP birimi devre dışı
   setup_spi(SPI_SS_DISABLED);     // SPI birimi devre dışı
   setup_timer_1(T1_DISABLED);     // T1 zamanlayıcısı devre dışı
   setup_timer_2(T2_DISABLED,0,1); // T2 zamanlayıcısı devre dışı
   setup_adc_ports(NO_ANALOGS);    // ANALOG giriş yok
   setup_adc(ADC_OFF);             // ADC birimi devre dışı
   setup_CCP1(CCP_OFF);            // CCP1 birimi devre dışı
   setup_CCP2(CCP_OFF);            // CCP2 birimi devre dışı

   lcd_init();
   delay_ms(5);

   ayar=oku_ds1621_ayar();  // DS1621 konfigürasyon kaydedicisi içeriği okunuyor
   bit_set(ayar,1);         // Konfigürasyon kaydedicisinde POL biti "1" yapılıyor
                            // bu bit alarm anında çıkışın lojik-1 olması için
                            // "1" yapılıyor
   bit_set(ayar,0);         // Konfigürasyon kaydedicisinde 1SHOT biti "1" yapılıyor
                            // sürekli sıcaklık okuması yapılsın diye
   yaz_ds1621_ayar(ayar);   // Yapılan değişiklikler konfigürasyon kaydedicisine aktarılıyor

   yaz_ds1621_th_tl(22,0,21,5);  // TH ve TL değerleri belirleniyor

   while(1)
   {
      sprintf(sonuc,"\fSicaklik=%0.1fC",ds1621_oku());
      printf(lcd_putc,"%s",sonuc);
      delay_ms(500);
   }
}

