"Enter"a basıp içeriğe geçin

XC8 ile DS1307 Gerçek Zaman Saati

DS 1307 Gerçek Zaman Saati entegresi hassas tarih ve saat bilgisinin gerektiği yerlerde sıklıkla kullanılmaktadır. Bu entegreler saniye, dakika, saat, gün, ay ve yıl bilgisini verir. Aynı zamanda düşük güç tüketimine ve küçük hacme sahiptirler bundan dolayı gömülü sistemlerde sıklıkla kullanılmaktadırlar.

Gerçek zaman saati bulunmayan mikrodenetleyicilerde zamanı tutmak oldukça zordur ve zamanlayıcı ve saat gerektiren uygulamalarda da çok önemli bir yere sahiptir. Çoğu uygulama, belirli olaylar meydana geldiğinde saat / tarih kaydının tutulmasını gerektirir. Gerçek Zaman Saatleri (RTC) bu tür uygulamalarda oldukça kullanışlıdır.

RTC’ler, genelde loglama uygulamalarında kullanılmaktadır. Ayrıca bilgisayarlar, dizüstü bilgisayarlar ve cep telefonları gibi cihazlarda da kullanılırlar.  Güç kesintileri durumunda bile zamanı ve verileri koruyabilmeleri için harici pillerle çalıştırılır. RTC’ler saat ve tarihi takip edebilmek için birkaç kaydedicisi vardır.

Bu yazı kapsamında incelediğimiz DS1307 RTC modülü de I2C protokolü üzerinde çalışan bir RTC’dir. PIC18F4550 mikrodenetleyicilerinde I2C protokolünün kullanımı hakkında daha fazla bilgi için, ilgili yazıyı okumanızı öneririm.

DS 1307 Gerçek Zaman Saatinin Özellikleri

  • 12 veya 24 saat formatına göre çalışabilen bu entegrelerin saat formatı kullanıcı tarafından değiştirilebilir.
  • Artık yıl hesaplamaları (ayın 31indeki atlamalar) ile ay sonu otomatik olarak hesaplanır.
  • Harici kaynaktan besleme kesildiğinde otomatik olarak kendisini dahili bataryadan beslemeye alır.
  • Düşük güç tüketimi ve küçük boyutu DS1307’nin bir çok projede kullanılmasını sağlamıştır.
ds1307 Gerçek Zaman Saat Entegresi
ds1307 Entegresinin Görüntüsü
DS1307 RTC Module
DS1307 RTC Modülü
DS1307 RTC Pin Diagram
DS1307 RTC Pin Şeması
  • RTC DS1307, yukarıdaki şekilde gösterilen 8 pinli entegredir.
  • RTC DS1307, 32.768 kHz frekanslı harici kristal kullanır, bu kristali X1 ve X2 pinine bağlamamız gerekir.
  • Vbat pinine 3 Voltluk CMOS pili bağlanır. RTC DS1307, 5 volt VCC’yi algılamak için dahili bir mekanizmaya sahiptir, eğer harici 5 volt VCC yoksa, 3 volt CMOS pilden de besleme alır.
  • SDA (Seri Veri) ve SCL (Seri Saat) pinleri, mikrodenetleyicinin I2C pinlerine bağlanmak için kullanılan I2C seri iletişim pinleridir.
  • SQW/OUT pini kare dalga çıkış sürücüsüdür. SQW/OUT pini, dahili register bitlerini ayarlayarak 1Hz, 4kHz, 8kHz, 32kHz olmak üzere dört kare dalga frekansından birini verir.

Genel olarak, RTC’yi (Gerçek Zamanlı Saat) ilk kez kullanırken, güncel saat ve tarihi ayarlamamız gerekir. Daha sonra RTC bu değerleri saniyeler içinde güncellemeye devam eder. RTC DS1307’de, saat ve tarih bilgisini Timekeeper yazmacından ayarlarız. Saat ve tarih değerini ayarladıktan sonra, RTC DS1307 her saniye saat ve tarih bilgisini güncellemeye devam eder, böylece ilerleyen zamanlarda güncel saati alabiliriz.

Timekeeper Yazmaçları

  • Timekeeper yazmaçlarının içeriği BCD (Binary Coded Decimal value) formatındadır.
  • Timekeeper yazmaçlarında saniye, dakika, saat, gün, tarih, ay, yıl ve kontrol ayarı için toplam sekiz adet yazmaç vardır.
  • Bu yazmaçların değerini belirledikten sonra, kendilerini güncellemeye devam edecekler. Daha sonra güncellenmiş değerleri almak için bu kayıtları okuyabiliriz.
DS1307 RTC Registers
Timekeeper Yazmaçları

Adres – 00H:02H: Saat Yazmaçları

Adres – 00H:

  • Bu yazmaçta bit-7, kristal osilatör etkinleştirme/devre dışı bırakma biti olan CH bitidir, sıfır olduğunda kristal osilatör etkinleştirilir, aksi takdirde osilatör etkinleştirilmez, bu nedenle RTC’yi kullanırken bu biti her zaman sıfır yaparız.
  • Diğer bitler saniyeyi okumak/yazmak için kullanılır. Timekeeper yazmacı, değeri BCD formatında sakladığından, burada Bit-4 ila Bit-6 saniyenin üst BCD basamağını (0’dan 5’e kadar) ve Bit-0’dan Bit-3’e, saniyenin alt BCD basamağını ( 0 ile 9 arası değer). Saniyenin değeri 00’dan başlayıp 59’da biter.

Adres – 01H:

  • Bu adres dakika değerini okumak / yazmak için kullanılır.
  • Dakika değerinin üst BCD basamağı Bit-4 – Bit-6 arasında ve alt BCD basamağı Bit-0 – Bit-3 arasında saklanır.

Adres – 02H:

  • Bu adres saat okumak / yazmak için kullanılır.
  • Saat, 12H veya 24H formatında çalışabilir.
  • 12 Saatlik Format: 12 saatlik saat formatını ayarlamak için Bit-6’yı mantıksal 1’e ayarlamamız gerekir. 12 saatlik format biçiminde Bit-5, AM / PM’yi gösterecektir, Mantıksal 1 PM içindir ve Mantıksal 0, AM içindir. Bit-4, 12 saatlik sistemde 0 veya 1 olan saat değerinin yüksek basamağını saklamak için 10 Saat olarak gösterilir. Bit-0 ila Bit-3, saatin alt basamağının değerini kaydeder (0’dan 9’a kadar değer).
  • 24 Saatlik Format: 24 saatlik saat formatını ayarlamak için Bit-6’yı mantıksal 0’a sıfırlamamız gerekir. Bit-4 ve Bit-5, 24 saatlik sistemde 0 veya 2 olan saat değerinin yüksek basamağını saklamak için10 Saat olarak gösterilir. Bit-0 ila Bit-3, saatin alt basamağının değerini kaydeder (0-9 arasındaki değerler).

Adres – 03H: 06H: Tarih Yazmacı

Adres – 03H:

  • Bu adres, 1’den 7’ye kadar gün değerini okumak / yazmak için kullanılır. Bit-0’dan Bit-2’ye, gün değerini okumak / yazmak için kullanılır.

Adres – 04H:

  • Bu adres, tarih değerini okumak / yazmak için kullanılır. Bit-4 ve Bit-5 tarihin üst basamak değerini okumak / yazmak için kullanılır (0’dan 3’e kadar değer). Tarih değerinin alt basamağı için Bit-0 ila Bit-3 kullanılır (0’dan 9’a kadar olan değerler).

Adres – 05H:

  • Bu adres, ayı okumak / yazmak için kullanılır. 0 veya 1 olan ayın üst basamak değeri için Bit-4 kullanılır. Bit-0 ile Bit-3 ayın alt basamak değerini (0-9 arası değerler) saklamak için kullanılır.

Adres-06H:

  • Bu adres yıl değerini okumak / yazmak için kullanılır. Yıl değerinin yalnızca son iki hanesini sağlar. Bit-0 ila Bit-3 alt basamağı depolar ve Bit-4 ila Bit-7 yılın daha yüksek basamağını depolar.

Adres-07H: Kontrol Yazmacı

Bit 7 – OUT: Çıkış

Bu bit, SQW/OUT pininin çıkış seviyesini kontrol eder. Kare dalga çıkışı devre dışı bırakıldığında, SQWE biti sıfırdır. Dolayısıyla, SQW/OUT üzerindeki mantık seviyesi bu OUT biti yüksek olduğunda yüksek ve bu OUT biti sıfır olduğunda sıfırdır.

Bit 4 – SQWE:

  • SQW / OUT pininde kare dalga çıkışını etkinleştirmek / devre dışı bırakmak için

1 = Osilatör çıkışını etkinleştir
0 = Osilatör çıkışını devre dışı bırak

  • Kare dalganın frekansı RS0 ve RS1 bitine bağlıdır.

Bit 0: 1 – RS0 ve RS1:

  • SQW / OUT pinindeki kare dalga çıkışının frekansını ayarlar.

DS1307 RTC Modülünü PIC18F4550 ile Programlama

RTC’yi ilk kez kullanırken, saat ve takvim değerlerini ayarlamamız gerekir. Bundan sonra RTC bu saati ve takvim değerlerini güncellemeye devam eder.

Birinci adımda RTC saat ve takvim değerlerini ayarlayacağız ve ikinci adımda bu değerleri okuyacağız.

Adım 1: Saat ve Takvimi Ayarlama

  • RTC ile çalışırken öncelikle mikrodenetleyicinin DS1307 ile haberleşeceği cihaz (slave) adresine ihtiyacımız olacak. Datasheet’ine göre DS1307, cihaza yazma için 0xD0 adresini, cihazdan okuma için 0xD1 adresini kullanılmaktadır.
  • PIC18F4550 mikrodenetleyicinin I2C kanalını başlatıyoruz.
  • Slave cihazla I2C iletişimini cihaz (yazma) adresi olan 0xD0 ile başlatıyoruz.
  • Saniye bilgisinin yazmaç adresi olan 0x00 değerini gönderiyoruz. Hemen sonra saniye değerini RTC’ye yazmak üzere gönderiyoruz. Bundan sonraki değer yazma işlemlerinde RTC adresi otomatik olarak artıracağından sadece dakika, saat, haftanın günü, ayın günü, ay ve yıl değerlerini göndermemiz yeterli olacak.
  • Veri gönderme işlemi bitti. Bu yüzden I2C haberleşmesini durduruyoruz.
void rtc_clock_write(char sec, char min, char hour, char AM_PM)     /* RTC'ye saat bilgisini yazacak fonksiyon */
{
    hour = (hour | AM_PM);     /* Saat AM veya PM */
    i2c_start(0xD0);/* I2C haberleşmesini 0xD0 slave (yazma) adresi ile başlatıyoruz */	
    i2c_write(0x00);     /* saniye değeri için yazmaç adresini yaz */
    i2c_write(sec);	     /* saniye değerini 0x00 yazmaç konumuna yaz */
    i2c_write(min);	     /* dakika değerini 0x01 yazmaç konumuna yaz */
    i2c_write(hour);     /* saat değerini 0x02 yazmaç konumuna yaz */
    i2c_stop();	     /* I2C haberleşmesini durdur */
}

void rtc_calendar_write(char day, char date, char month, char year)     /* RTC'ye tarih bilgisini yazacağımız fonksiyon */
{
    i2c_start(0xD0);     /* I2c haberleşmesini slave cihaz (yazma) adresi ile başlatıyoruz */
    i2c_write(0x03);     /* haftanın günü değeri için 0x03 yazmaç konumunu yaz */
    i2c_write(day);	     /* haftanın günü değerini 0x03 yazmaç konumuna yaz */
    i2c_write(date);     /*  ayın günü değerini 0x04 yamaç konumuna yaz*/
    i2c_write(month);    /* ay değerini 0x05 yazmaç konumuna yaz */
    i2c_write(year);     /* yıl değerini 0x06 yamaç konumuna yaz */
    i2c_stop();          /* I2C haberleşmesini durdur */
}

Adım 2: DS1307’den Saat ve Tarih değerini okuma

Bu adımda RTC’den saniye, dakika, saat, gün, ay, vs. gibi verileri okuyacağız.

  • Öncelikle slave cihaz (yazma) adresi 0xD0 ile I2C iletişimini başlatıyoruz.
  • Ardından datayı okuyacağımız yerin yazmaç adresini yazıyoruz (saniyeyi okumak için 0x00 yazmaç adresi)
  • Ardından bu sefer 0xD1 slave cihaz (okuma) adresi ile I2C iletişimini tekrar başlatıyoruz.
  • Şimdi veriyi slave cihazdan kabul/alındı bilgisi ile birlikte okuyabiliriz.
  • Son veriyi her zaman olumsuz onay (NACK) ile okumamız gerekiyor, böylece cihaz bunun cihazdan okunacak son veri olduğunu anlayacak ve iletişimi durduracaktır.
  • Sonraki baytı okumak için yazmaç adresinin konumu otomatik olarak artırılacaktır.
void rtc_read_clock(int *sec, int *min, int *hour)
{
    i2c_start(0xD0);
     /* cihazı 0xD0 slave adresi ile başlatıyoruz */
    i2c_write(0x00);     /* saatin okunacağı 0x00 yazmaç adresini yazıyoruz */
    i2c_repeated_start(0xD1);
     /* 0xD1 slave cihaz adresi ile I2C iletişimini tekrar başlatıyoruz */
    sec = i2c_read(0);   /* 0x00 yazmaç adresinden saniyeyi okuduktan sonra sürekli okuma için ACK gönderiyoruz */
    min = i2c_read(0);   /* 0x01 yazmaç adresinden dakikayı okuduktan sonra sürekli okuma için ACK gönderiyoruz */
    hour= i2c_read(1);   /* 0x02 yazmaç adresinden saati okuduktan sonra okumayı durdurmak için NACK gönderiyoruz */
}

void rtc_read_calendar(int *day, int *date, int *month, int *year)
{   
    i2c_start(0xD0);     /* cihazı 0xD0 slave adresi ile başlatıyoruz */
    i2c_write(0x03);     /* haftanın günü bilgisinin okunacağı 0x03 yazmaç adresini slave cihaza yazıyoruz */
    i2c_repeated_start(0xD1);
    day = i2c_read(0);   /* 0x03 yazmaç adresinden haftanın günü bilgisini okuduktan sonra sürekli okuma için ACK gönderiyoruz */
    date = i2c_read(0);  /* 0x04 yazmaç adresinden ayın günü bilgisini okuduktan sonra sürekli okuma için ACK gönderiyoruz */
    month = i2c_read(0); /* 0x05 yazmaç adresinden ay bilgisini okuduktan sonra sürekli okuma için ACK gönderiyoruz */
    year = i2c_read(1);  /* 0x05 yazmaç adresinden ay bilgisini okuduktan sonra okumayı durdurmak için NACK gönderiyoruz */
    i2c_stop();     /* i2c iletişimini durdur */
}

haruncetin.com.tr

KAYNAKLAR:

1-RTC DS1307 Datasheet: https://datasheets.maximintegrated.com/en/ds/DS1307.pdf

2-Real Time Clock RTC DS1307 Module: https://www.electronicwings.com/sensors-modules/real-time-clock-rtc-ds1307-module

3-Real Time Clock RTC DS1307 interfacing with PIC18F4550: https://www.electronicwings.com/pic/real-time-clock-rtc-ds1307-interfacing-with-pic18f4550

İlk Yorumu Siz Yapın

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir