RTC saat entegreleri için kütüphane aramaya son.

RTC saat entegrelerini kullanırken devamlı kütüphane arayışı içerisine giriliyor. Fakat kütüphaneler kullanıcılar tarafından değişikliğe uğradığından programınız çalışırken birden çalışmaz olabiliyor.
Hele bir de aynı isimde kütüphaneler ise, güncelleme yapıldığında, eski kütüphane değişiyor ve çalışan program çalışmaz olabiliyor.
Çare nedir. Kütüphanesiz kolay erişim. Program sizin programınız olacak kafanız karışmayacak.
NOT : Bu yazının sonunda 3 kablo iletişim ve I2C iletişimi öğrenmiş olduğunuzdan I2C ve 3 kablo iletişim ile haberleşme yapan diğer sensörler ve cihazlar ile kütüphane olmaksızın haberleşebileceksiniz. Haberleşme tekniği aynı olduktan sonra yapılacak tek şey, Datasheete bakıp bilginin bulunduğu registerleri ( Yazmaçları ) öğrenmek ve kullandığımız sensör ya da modülün fonksiyonlarını bilmektir.

Kolay mı?         Çok kolay olacağını göreceksiniz.

Tek kablo iletişimi öğrenmek istiyorsanız, DS18B20 sıcaklık sensörünü anlattığım yazıma göz atabilirsiniz. 

Her ne kadar anlatılanlar Arduino konusu gibi görünse de tüm işlemcilerde durum değişmez. Bir modülü sadece kütüphane ile çalıştırırsanız, diğer modüllerde de kütüphane ararsınız. Bulamadığınızda kullanamazsınız. Haberleşme sistemlerini öğrendiğinizde Kütüphane arayışına girmeden modülleri kullanabilirsiniz.
Burada arduino için WIRE kütüphanesi I2C için kullanılmıştır. Picbasic te I2C komutları vardır . Diğer dillerde de haberleşme için, komut yada kütüphaneler vardır. Önemli olan haberleşmeyi bilmek ve datasheet dediğimiz kullanım kitapçıklarından faydalanabilmektir. 

Kütüphane konusuna bakalım. Tüm resimler kütüphane isimleri olarak RTClib.h ve RTClib.cpp yi kullanıyor. Boyutlarına bakarsanız hiçbiri, birbirinin aynı değil.
Bunlardan birini kütüphane olarak koydunuz, ya güncelleme geldiğinde değişirse, ya da aynı isimde, kütüphane kullanan birinin programını derlersiniz, fakat kütüphane de kullanılan fonksiyon isimleri gibi parametreler uymaz. Bundan dolayı derlenemez, ya da doğru çalışmaz. Bir de buna kullanmadığınız fonksiyonların kütüphane de olup programınıza eklenmesi var.
Bütün bunların ötesine geçersek, siz bir RTC entegresi aldınız fakat kütüphane bununla uyumsuz. Belki de kütüphanesi yok.

 

 

 

 

 

 

 

 

 

 

.

Bütün bunları bir kenara koyup, kendi RTC entegrenize ve benzer modüllere, kolay erişim programı yazın.

Entegrelerin Datasheetlerine bakarak hangi haberleşme sistemini kullandığını öğrenebiliriz. Buna göre kullanacağımız haberleşme metodunu seçeriz.
RTC entegresini nasıl seçeriz. Genelde saat söz konusu olduğunda hemen RTC entegresi kullan deriz. Doğru, yanına da bir sıcaklık sensörü koyarız. Bu da doğru. Programımızı yaparken harici belleğe de ihtiyacımız olur bir de 24C16 gibi bir I2C kullanan hafıza entegresi de kullanırız. Bütün bunların yerine DS323x entegre kullanmaya ne dersiniz. Hem RTC , hem Sıcaklık sensörü, hem de ekstra hafıza.
Seçiminizi yaparken kolaya kaçmayıp benzer sistemleri incelemenizde fayda var. Kütüphanesi olan bir entegre kullanırım demeyin, diye bu yazıyı yazdım. 



Örnek olarak yukarıdaki resimdeki modüle bakabilirsiniz. Bu modülde DS3231 kullanılmış. Bu entegrede hafıza sistemi yok. Bunun yerine ekstradan 256 byte’lık bir hafıza eklenmiş.

Siz olsanız hafızaya ihtiyacınız da varsa DS3232 entegresini seçermiydiniz. Hem  236 byte hafızası olan ve sıcaklık sensörü bulunan. (DS3231 de de sıcaklık sensörü vardır.)

DS1302 : 3 kablolu haberleşme kullanır. Senkronize seri iletişim protokolüdür.  Bu protokole uygun program mantığı ve videosu aşağıdadır.

DS1307 : I2C haberleşme protokolünü kullanır. Bu zaten Arduino kullanıcılarında wire.h kütüphanesi demektir. Bu kütüphaneyi kullanmamız gerekir. Protokolün karışık olmasından dolayı, kullanmış olsak da, biraz daha ileri seviyeye geldiğinizde buna da ihtiyacınız olmaz.
Diğer programlama dili kullanıcıları kendi programlama dillerinin gereği olarak, I2C kütüphanelerini ya da komutlarını kullanabileceklerdir.

DS3231 ve DS3232 : I2C haberleşme protokolünü kullanır. Hatta bazı parametreleri değiştirerek saat kısmı için DS1307 ile aynı programı kullanabilirsiniz. ( Bu konu videolarda gösterilecektir.) DS323X diye anılan 3231,3232 gibi seri entegrelerin bilgileri aşağıdaki tabloda yer almaktadır. Ayrıca farklılıklarını görmek için Bu Sayfaya Bakabilirsiniz.


Bu entegreler haberleşme protokolü olarak farklı protokol kullansa da gönderdiği datalar, BCD kodlamayı kullanır. Amatör olanlar DEC, HEX, BIN gibi parametreleri bilirler. Bunlar 10luk, 16lık, 2 lik sayı sistemleridir.BCD ise 4 bitlik yapısı ile 0-9 arası sayılan, sayıları temsil eder. Normalde 4 bit 0-15 e kadar saysa da BCD kodlamada sayıların sonu 9 dur.

BCD de nereden çıktı diyeceksiniz. BCD kolay bir sistemdir merak etmeyin.
Yukarıda gördüğünüz gibi bir çevrim yapıldığında 8 bitlik verinin birbiri ile aynı olmadığını görebilirsiniz. Çünkü BCD kodlama 8 bit değildir. 2 adet 4 bit sayı 8 bit gibi görünse de hepsi 4 bitlik olarak kendi arasında ayrılır. Aşağıdaki örneklerde bunu görebilirsiniz.

Yukarıdaki gibi saate 10:37:49 yazmak isterseniz kodu BCD ye çevirmeniz gerekir. Son şekilde aşağıdan yukarı doğru 4 bit temsil edilmiştir.
Çalışma mantığı şudur.
Entegreden gelen BCD yi decimal dediğimiz 10 luk sisteme çevirip işlemlerimizi yaparız. Çıkan sayıyı ise BCD ye çevirerek RTC entegresine yollarız. (BCD to DEC   ve DEC to BCD).

Örnek DEC to BCD : RTC ye göndereceğimiz bilgiyi BCD ye çeviririz.
Value=49;  Value=(Value/10*16) + (Value%10); // saniye
örnek BCD to DEC : RTC den gelen bilgiyi ayar yapmak için DEC değerine çeviririz.
Value=(Value/16 *10) + (Value%16);
Bunlar arduino için standart kalıptır kullanabilirsiniz. Ayrıca diğer dillerde farklı formüller kullanılabilir.
Mesela picbasic te kullanılan şekil şudur.
TEMP=(SN DIG 1)<<4+SN DIG 0:SN=TEMP     (Bu satır DEC to BCD)
BOS=((sn>>4) & $0F)*10+(SN & $0F):sn=BOS   ( Bu satır BCD to DEC) olarak kullanılır.

BCD konusu anlaşıldığına göre artık DS1302 ile programlamaya başlayabiliriz. 

DS1302 RTC entegresi : Datasheet’e buradan ulaşabilirsiniz. 

3 kablolu iletişim kullanıyor. Bu 3 pin istediğiniz dijital pimlerden seçilebilirsiniz. Devrede 32.768kHz kristal kullanmanız gerekir.
Pimler : I/O, SCLK,RST. Benim programımda 11., 12. , 13. pimler kullanılmıştır.
RTC , tarih,saat,haftanın günü artık yıl hesabı hazırdır. 2100 e kadar sorun yoktur.
Ayrıca 31*8bit batarya destekli RAM vardır. Şayet ekstra eeprom gibi kullanmak isterseniz burasını kullanabilirsiniz. Pil bitesiye kadar bilgiler burada saklı kalacaktır.

Yukarıdaki tablo datasheet ten alınmıştır. Burada görülen Register denilen yazmaçlara bakalım. Bu kodlarla bilgileri alırız ya da göndeririz.
READ : Bu  satırdaki 8 bitlik bilgiyi okumak için bu adresi vermeniz lazım ondan sonra entegre size bu adrese ait satırdaki 8 biti verecektir.
WRITE : Bu satırdaki 8 bitlik sütunlara yazmak istediğiniz değeri yazmak için bu kodu verirsiniz. Entegre karşılık olarak verdiğiniz değeri alıp gerekli bit lere yazar.
bit7-bit0 : 8 bitlik değerdir. Bazı yerlerde gösterilecek değeri ve ayrıca saatte yapılması gereken işlemleri gösterir.
RANGE : saat bilgilerinde alabileceği değeri gösterir. Mesela satırda saniye varsa 00-59 arası sayar diye belirtir.
CH biti : clock halt bitidir. Saatin ilk çalıştırılmasında entegre çalışmıyormuş gibi gelir. Bu 8 bitlik alana saniye değeri 00 olarak girilmezse saat çalışmaz. Bundan dolayı entegreye önce doğru zaman değerlerinin kayıt edilmesini ister. Ayrıca entegrenin her iki gerilim kaynağı susarsa bu bit yine ilk haline döner. Gerilim kaynakları bağlansa bile Saat yeni kayıta kadar çalışmaz.
WP biti : write protect: yazma korumasıdır. Bu bit 1 olduğunda sadece bilgiler okunur yazılamaz. Buna RAM daki bilgiler de dahildir.
90h-91h olan satırdaki bilgiler şarjlı pil kullanılıyorsa diye düşünülmüş. Ayrıntıları datasheetten bakıp öğrenebilirsiniz.
CLOCK BURST : Buradaki read ve write kodlarını kullanarak zincir şeklinde tek komutla tüm saat bilgilerini bir kerede okuyup alabilirsiniz ya da tümüne birden yazabilirsiniz.
RAM : Bu kısımdaki READ ve WRITE kodlarını kullanarak 31 adet RAM bölgesine tek tek kayıt yapıp okuyabilirsiniz. Her kayıt 8bit=1 byte tır. 31x8bit kayıt yapılabilir.
RAM BURST :  Bu kodları kullanarak tüm RAM bölgesine zincir şeklinde tek bir komutla kayıt yapabilirsiniz.

Aşağıdaki program parçacıkları sadece anlatabilmek amaçlıdır tam program ise link olarak en altta mevcuttur.
Okuma algoritmasına bakalım:
readbyte alt programı ve onu çağıran yerdeki program parçaları bize bunu gösterecektir.
1- Öncelikle hangi satırı okumamız gerektiğini entegreye bildirmemiz lazım.(cmdByte = 0x81)
2- Bu byte’ı entegreye göndermemiz gerekir. (writebyte ile)
3- Gönderdikten sonra bilgi alabilmemiz için I/O pimini geçici olarak INPUT yapmamız gerekir.
4- Bilgiyi aldıktan sonra BCD to DEC ile kullanabileceğimiz duruma getiririz
5- iletişim hattını sonlandırırız.

Yazma Algoritması da şu şekildedir.
1- Göndermek istediğimiz değişkenlere değeri verip onları DEC to BCD kullanarak hazırlarız.
2- I/O pimini output olarak ayarlarız.
2- Hangi adrese kayıt yapılacaksa o adres entegreye bildirilir.
3- arkasından değişkenimizi entegreye göndeririz.
4- iletişim hattını sonlandırırız.

Bu mantık ile baktığımızda aşağıdaki program parçalarında, void date_hour() alt programı ile 0x81 yazmaçından bilgi okumak için önce 0x81 kodunu entegreye bildirmek gerekir. Bunun için digitalWrite(sclk_pin, LOW);
digitalWrite(ce_pin, HIGH); komutları kullanılarak iletişim başlatılır .
writeByte(cmdByte); ile writebyte  alt programını çağırırız. Daha sonra okumak için
readByte(); altprogramını çağırırız. Bu alt programda bilgi okunup BCD to DEC olarak çevrilir. Sonrasında
digitalWrite(ce_pin, LOW); // byte alımı tamamlandı  komutunu kullanarak iletişimi kapatırız.

Yazma kısmını da buradan takip edebilirsiniz. void rtc_adjust() alt programı entegreye saat bilgisini kaydetmek içindir.

Kısaca iletişim başlatmak için ve sonlandırmak için alttaki komutlar kullanılır. 
digitalWrite(sclk_pin, LOW); // haberleşme başlatmak için saat palsi sıfır yapılır.
digitalWrite(ce_pin, HIGH); // haberleşme başlatılır
writebyte ya da readbyte komutları
digitalWrite(ce_pin, LOW); // byte alımı tamamlandı İletişim sonlandırılır.

void readByte(){
  pinMode(data_pin, INPUT);
  Value = 0;
  for (int i = 0; i < 8; ++i)  // 8 bitlik data alınır. 
  {
    currentBit = digitalRead(data_pin);
    Value |= (currentBit << i);
    digitalWrite(sclk_pin, HIGH);
    delayMicroseconds(1);
    digitalWrite(sclk_pin, LOW);
  }
 // digitalWrite(ce_pin, LOW);   // byte alımı tamamlandı
  Serial.print ("DEC deger  : ");Serial.println (Value);
   Value=(Value/16 *10) + (Value%16); // dec kod hex koduna çevrilir. 
  return Value;
}

void writeByte(uint8_t value)
{ 
  pinMode(data_pin, OUTPUT);
  shiftOut(data_pin, sclk_pin, LSBFIRST, value);
}

void rtc_adjust(){

  valsec=25;valsec=(valsec/10*16) + (valsec%10);cmdByte = 0x80;commstart(); writeByte(cmdByte); writeByte(valsec);digitalWrite(ce_pin, LOW);   // byte alımı tamamlandı
  valmin=35;valmin=(valmin/10*16) + (valmin%10);cmdByte = 0x82;commstart(); writeByte(cmdByte); writeByte(valmin);digitalWrite(ce_pin, LOW);   // byte alımı tamamlandı
 valhour=23;valhour=(valhour/10*16) + (valhour%10);cmdByte = 0x84;commstart(); writeByte(cmdByte); writeByte(valhour);digitalWrite(ce_pin, LOW);   // byte alımı tamamlandı
  
}

void date_hour(){
  cmdByte = 0x81; // 129= 81h registerini okumak için 
 Serial.println (cmdByte); 
  digitalWrite(sclk_pin, LOW);  // haberleşme başlatmak için saat palsi sıfır yapılır
  digitalWrite(ce_pin, HIGH);  // haberleşme başlatılır
  writeByte(cmdByte);  // cmdbyte = okuma ve yazma kodunun başladığı adresi RTC ye gönderir.
  readByte();   // RTC gelen adrese göre data yollar. data alımına gidilir.
  valsec=Value & 0x7F;  // 
  Serial.println (valsec);
  
}

void seridata(){
  for (int k = 0; k < 7; ++k)
  {
  cmdByte=0x81;
  cmdByte=cmdByte+(k*2);
   digitalWrite(sclk_pin, LOW);  // haberleşme başlatmak için saat palsi sıfır yapılır
  digitalWrite(ce_pin, HIGH);  // haberleşme başlatılır
  writeByte(cmdByte);  // cmdbyte = okuma ve yazma kodunun başladığı adresi RTC ye gönderir.
  readByte();   // RTC gelen adrese göre data yollar. data alımına gidilir.
    myInts[k]=Value;
   digitalWrite(ce_pin, LOW);   // byte alımı tamamlandı 
  }
  
  Serial.print ("myint_0  ");Serial.println (myInts[0]);
  Serial.print ("myint_1  ");Serial.println (myInts[1]);
  Serial.print ("myint_2  ");Serial.println (myInts[2]);
  Serial.print ("myint_3  ");Serial.println (myInts[3]);
  Serial.print ("myint_4  ");Serial.println (myInts[4]);
  Serial.print ("myint_5  ");Serial.println (myInts[5]);
  Serial.print ("myint_6  ");Serial.println (myInts[6]);
}



 

DS1307 I2C haberleşmeli RTC entegresi : Datasheet’e buradan bakabilirsiniz.

Bu entegre DS1302 den farklıdır. I2C ile haberleşir, hem de SQW denilen ayarladığınız frekansta kare dalga çıkış verir. Batarya destekli 56 byte lık NV SRAM vardır. Devrede 32.768kHz kristal kullanmanız gerekir.

SQW çıkışında 1 adet direnç olmak zorunda. Çünkü bu çıkış açık kollektör dediğimiz VCC ye bağlı olmayan bir çıkıştır ve burayı VCC ye bağlamanız gerekmektedir. Ancak o zaman çıkış alabilirsiniz. Şeması şu şekildedir.( açık kollektör veya açık kanal  , open collector,open drain) Tavsiyem sizler de bu tip bilgilerde ingilizcesini kullanın. 

Burada tek bir adres var. Bu adres ile hem kayıt yapılır hem de okunur. Ayrıca DEVICE ADDRESS denilen I2C haberleşmesini başlatan bir adres vardır. uint8_t devaddr=0x68; şeklinde program başında tanımlanmıştır. Burada gördüğünüz 0x68 hex kodudur. Fakat sadece 7 bitlik bir sayıya karşılık gelir. ( 1101000 )  buna wire.h kütüphanesi tarafından 1 ya da 0 eklenir. 1 okuma yapacağını 0 kayıt yapacağını belirtir. Sayının son hali ise 0xD0 ya da 0xD1 olacaktır. 

Bu tabloda ise SQW çıkışının nasıl ayarlanacağı görülmektedir. 1Hz lik sinyali buradan alıp saatlerinizde “:”  işaretiyle gösterilen yerde yanıp sönme animasyonu yapabilirsiniz. Bunun için arduinoyu kullanmanıza gerek yok. Devredeki SQW çıkışını 1-4.7K lık direnç ve transistör ile Displayin  nokta ledlerine verebilirsiniz. ( videolarda 0x90=90h =10010000 verilerek 1Hz sinyal üretilmiştir. ) Ya da LCD kullanacaksanız Arduinonun giriş ucuyla hissedip LCD de gerekli işlemi yapabilirsiniz.  Videoda 90 sayısı hex girileceğine dec girildiğinden sonuç hatalı çıkmıştır. buradaki doğrudur.

Yukarıdaki tabloda I2C olarak yazma ve okuma bilgilerinin çalışma şekli belirtilmiştir. Slave Address bölümüne dikkat ederseniz bizim verdiğimiz 0x68 adresinin yanına 1 ya da 0 getirilmiştir. Bu adres tüm I2C kullanan sistemlerde farklı olmaktadır. DS1307 ve DS3232  gibi entegrelerde bu adres değişmiyor gibi görünse de muadili olan RTC entegrelerinde değişik olabilir. Aldığınız entegrenin datasheet’ine bakarak öğrenebilirsiniz. 

DS1307 ile nasıl haberleşiriz.
Yazma kısmında algoritma:
1- yazılacak değişken belirlenir.
2- DEC to BCD ile BCD koda çevrilir.
3- Haberleşme başlatılır
4- hangi yazmaç’a bilgi yazılacaksa o bildirilir
5- yazılacak bilgi gönderilir.
6- haberleşme sonlandırılır.

Program olarak karşılığı aşağıdaki şekildedir. 
Value=55;
Value=(Value/10*16) + (Value%10); // saniye
Wire.beginTransmission(devaddr); // haberleşme başlat (slave adres belirt)
Wire.write(0); // sıfırıncı registerden basla demektir.
Wire.write(Value);
Wire.endTransmission(); // haberleşme sonlandırılır.

Okuma kısmında algoritma:
1- Haberleşme başlatılır
2- Hangi yazmaçtan okunacağı bildirilir
3- haberleşme kapatılır.
4- Bilgi isteği gönderilir. Slave adresi belirtilir, kaç byte bilgi istenecekse bildirilir. ( Dikkat : Bu bilgiden daha az ya da daha fazla almak isterseniz hata verir ve değişkene aktarılmaz.)
5- Bilgi beklemeye başlanır bilgi geldiğinde bilgi değişkenlere byte olarak aktarılır
6- Haberleşme son bilgi alındıktan sonra otomatik kapatılmış demektir sonlandırmanıza gerek yoktur.

Program olarak karşılığı aşağıdaki şekildedir.
Wire.beginTransmission(devaddr); // haberleşme başlat (slave adres belirt)
Wire.write(0x00); // Hangi registerden alınacaksa o yazılır.
Wire.endTransmission(); // haberleşme sonlandırılır
Wire.requestFrom(devaddr,8);  // haberleşmeyi tekrar sağlar ve slave adres ile kaç byte isteneceği yazılır.
if(Wire.available()<=8) { //   burada while ile bekleme de kullanılabilir.
myInts[0] = Wire.read();// okunacak karakter değişkene aktarılır.
myInts[1] = Wire.read();// okunacak karakter değişkene aktarılır.
myInts[2] = Wire.read();// okunacak karakter değişkene aktarılır.
myInts[3] = Wire.read();// okunacak karakter değişkene aktarılır.
myInts[4] = Wire.read();// okunacak karakter değişkene aktarılır.
myInts[5] = Wire.read();// okunacak karakter değişkene aktarılır.
myInts[6] = Wire.read();// okunacak karakter değişkene aktarılır.
myInts[7] = Wire.read();// okunacak karakter değişkene aktarılır.

Tüm bilgiler okunduktan sonra değişkenler BCD to DEC ile çevrilerek işlemlerde kullanılabilir sadece göstermek için kullanacaksanız buradaki gibi BCD yi çevirmeden kullanabilirsiniz.
showhour=String(myInts[2],HEX)+”:”+String(myInts[1],HEX)+”:”+String(myInts[0],HEX);
Bu şekilde showhour değişkenini LCD ye yazdırabilirsiniz.

Aşağıdaki program parçaları ise PICBASIC ile nasıl yapılacağını gösterir.

ZAMAN_YAZ:
hesap=YIL/4
k=status.0
if k=1 AND AY=2 AND GUN>28 then
GUN=28
ELSE

 if k=0 and ay=2 and gun>28 then 
    gun=29
    else
    endif
endif
;baslayaz: sn=00:dak=10:saat=13:gun=25:ay=6:YIL=17
        TEMP=(SN DIG 1)<<4+SN DIG 0:SN=TEMP
        TEMP=(DAK DIG 1)<<4+DAK DIG 0:DAK=TEMP
        TEMP=(SAAT DIG 1)<<4+SAAT DIG 0:SAAT=TEMP
        TEMP=(GUN DIG 1)<<4+GUN DIG 0:GUN=TEMP
        TEMP=(AY DIG 1)<<4+AY DIG 0:AY=TEMP
        TEMP=(YIL DIG 1)<<4+YIL DIG 0:YIL=TEMP
        I2CWrite SDA, SCL,$D1,$00,[SN,DAK,SAAT,HAFGUN,GUN,AY,YIL]
        PAUSE 10 
        return 


SAATOKU:
    I2CRead SDA, SCL,$D1,$00,[SN,DAK,SAAT,HAFGUN,GUN,AY,YIL,TEMP]
         BOS=((sn>>4) & $0F)*10+(SN & $0F):sn=BOS
         BOS=((DAK>>4) & $0F)*10+(DAK & $0F):DAK=BOS
         BOS=((SAAT>>4) & $0F)*10+(Saat & $0F):SAAT=BOS
         BOS=((GUN>>4) & $0F)*10+(GUN & $0F):GUN=BOS
         BOS=((AY>>4) & $0F)*10+(AY & $0F)  :AY=BOS
         BOS=((YIL>>4) & $0F)*10+(YIL & $0F):YIL=BOS

SEROUT2 GPIO.5,84,["LCDWR 1,1-","Hour:"," ",DEC2 saat,":",DEC2 dak,":",DEC2 sn ]

 

DS3232 I2C haberleşmeli RTC entegresi : Datasheet’e buradan bakabilirsiniz.

Bu entegre proteus denemelerinde DS3231 olmadığı için seçildi. I2C kullanım sistemi aynı olduğundan I2C olan RTC lerde sadece başlangıç registerinin (yazmaç) numarasını yazmanız yeterli saat bilgileri için datasheet’e bakarsanız DS1307 ile aynı olduğunu görebilirsiniz. DS1307 programını hiç bir değişiklik yapmadan DS3232 ve 3231 entegrelerinde kullanabilirsiniz.

Önemli bir farklılık. Bu entegrelerin bağlantı resmine bakarsanız X1 ve X2 girişleri yoktur. Bunların kristalleri içindedir. Kristaller sıcaklıkla küçük sapmalar yapıyordu. İçeri almakla birlikte, içinde sıcaklık sensörü de bulunduğundan, sıcaklığa göre kristal frekansını da düzeltiyor. Bununla ilgili registerleri de datasheet içinde bulabilirsiniz. 10h registeri aging offset registeri bu iş için ayrılmıştır. 

Farklılıklar nelerdir . Buradan DS323X entegrelerinin farklılıklarına bakabilirsiniz. Tabii ki iş sadece saat kısmıyla kalmıyor. I2C kullanan kısım ortak. Saat kısmı ortak olsa da saat kısmındaki registerlerde bazı küçük değişiklikler var.
Bunun yanı sıra ds323X serisi SICAKLIK ölçümü yapılabiliyor. Sıcaklık doğruluğu 3 derece civarına çıksa da, devrenizi kutu içerisine koyduğunuzda kutu içerisindeki sıcaklığı ölçmek için ayrıca bir sıcaklık sensörüne gerek yoktur. Bu sıcaklık kısmını kullanarak gerektiğinde FAN sisteminizi devreye alabilirsiniz.
Entegrelerde bir de RAM sistemi var Bunun boyutları farklıdır. Bazı bilgileri buraya koyarak işlemcinizi rahatlatabilirsiniz. Mesela yeni karakter tanımlarınızı buraya koyarak işlemcinizin hafızasından tasarruf edebilirsiniz. Zaten saati öğreniyorsunuz oradan karakter de çağırabilirsiniz.
Ayrıca 2 adet ALARM bölgesi var. Bu bölgeleri, programlayarak çeşitli işlevler yükleyebilirsiniz.
Bazıları 3.3V ile çalışabilecek kapasitededir.
Saat (RTC) entegrenizi seçerken bu gibi kriterlere göre seçmeniz yerinde olacaktır. 

Aşağıdaki register tablosunu gördüğünüzde, farklılıkları da görmüş olacaksınız. Fakat güzel tarafı her birine, aynı saat bilgilerine ulaşabiliyormuşsunuz gibi, kolaylıkla ulaşabileceksiniz.

Buraya kadar da saat entegrelerini ve iletişimini konuştuk. Şimdi ise saat değerlerini değiştirmeye yönelik bir kaç örnek yapalım.
Mesela okuduğumuz saat 13:15:00 olsun. Bu saati 1 saat ileri almak istesek ne yapmamız lazım.
13:15:00 için  BCD kodlamaya göre çalıştığından 3 registeri okuyup bilgileri aldıktan sonra da değişikliğimizi yapıp hemen RTC içerisindeki ilgili registerlere koyabiliriz.
Dikkat edilmesi gereken bir durum:
00h registerinden saniyeyi okuduk. Bu değer 7 bitlik bir değer. Şayet 8. bit 1 olursa ki bazı entegrelerde bu bit kullanılabiliyor. O zaman bizim ihtiyacımız neyse onu almalıyız. Yani 8. biti sıfırlamalıyız.
Bunun için mantık işlemlerini kullanıp AND işlemiyle 8. biti sıfırlayacağız. b=binary demektir.
Saniye=10000000b  saniye =saniye & 01111111b
AND işlemi 1. sayı ile 2. sayı bitlerini birbiri ile çarpmak demektir. Bu şekilde 8. biti 0 yaptığımız için 8. bit sıfırlanmış olacak diğer bitler olduğu gibi kalacaktır. Net olarak saniye bilgisini aldık.

01h registerinden Dakika =15   dakika =0001 0101 sayılarına tekabül eder. BCD olarak 4 bitlik gösterimde.
Bunu da 7 bit olduğunu bildiğimizden AND işlemine tabi tutup yanlışlık olmasını önleyelim.
Dakika=00010101b   Dakika=Dakika & 01111111b işlemiyle 8. biti sıfırladık.

02h registerinden Saat bilgisini okuduk. (Burada bazı bitlerdeki bilgiler bize net olarak saati vermeyebilirler. Bunları sıfırlamamız lazım.  6. 7. bitler 24 saat metoduna göre çalışıyorsak sıfırdır. fakat biz yine net saat bilgisini almak için AND işlemine tabi tutalım.
Saat=13  saat= 0001 0011  BCD bilgisini aldık.  saat=saat & 00111111b   Bu şekilde net olarak saati elde ettik.
5. bitin özel bir durumu var. 24 saatlik dilimi kullanıyorsanız 21 yazmak için 5. bite ihtiyacınız var. bunu kullanmanız lazım. Şayet 6. biti 1 yaparsanız 12 saatlik sistemi kullanmanız gerektiğini göreceksiniz. Bu şekilde kullanımda 5. biti de kontrol edip, AM/PM kısmını da saate yazdırmanız gerekir. 5. biti kontrol ederseniz buradaki bitin durumu AM/PM bilgisini verecektir. Zaten 12 saatlik sistemde 20. saat olmadığından bu bit kullanılmamaktadır.
AND işleminin arduinoda nasıl olur diyenler bu sayfaya bakabilirler. 

Bu şekilde NET olarak BCD değerlerimizi aldık.
Hatırlatma : 8 bit ile sadece 99 a kadar sayıları bcd olarak kullanabilirsiniz. BCD çevrim aracı
Şimdi BCD DEC ve DEC BCD dönüşümlerine bakalım. Zaten aşağıdaki formüller bu işi yapıyor. sadece formülleri doğru yerde kullanmanız kalıyor.
Normalde BCD DEC desek de bu okuma ve gösterilme itibariyle BCD HEX gösterme şekli diyebiliriz.
Mesela 1001 1001bcd olan bir kodumuz var. Bu okunurken 4 bitlik okuma yapıldığından HEX gibi okunur. 99 demektir. Bunu birleştirip gerçek bilgisayarımızdaki gibi DEC komutuna çevirmek için bu bitleri birleştirelim. 10011001b = 153 desimal sayıya karşılık gelir. Gerçek binary sistemde hex 99 DEC 153 sayısıdır. Fakat bunu şöyle düşünelim. 153 sayısı hex olarak 99 çıktı binary sisteminde de bunu teyit edebiliyoruz.
Ya sayı 140 olsa. dec 140 =  hex 8C = 1000 1100b yapardı.  BCD ye çevrilemezdi. bcd 9 dan yukarısını kullanamaz. Sayı çevrimlerinde hata yapmazsanız programınız gayet güzel çalışacaktır.

Neden HEX gibi okunur dedik. Hex sayıları, 2 tane 4 bitlik sayı olarak okunur. Aynı BCD deki gibi okunur. 0xFE gibi. Burada F yüksek 4 bit’i belirtir E düşük 4 bit’i belirtir.

Formülleri inceleyelim. :
DEC to BCD formülü  saat=(saat/10*16) + (saat%10);
Bu formüle göre işlemleri yapalım.
99/10= 9,9  buradan ilk sayının 9 olduğunu görebiliriz.
bunu binary olarak yazalım ki *16 yı gösterebilelim. 1001b
İkili kodlamada sola kaydırma çarpma demektir. 4 kez sola kaydırırsanız 16 ile çarpmış olursunuz. Şimdi sayımız 10010000b oldu. ilk dört bit yerine oturdu.
ikinci işlem olarak 99/10=9.9 fakat % işareti mod alma işlemi olduğundan mod 10 a göre kalan 9 olur.
Bu sayıyı da düşük 4 bit kısmına yazarsak 10011001bcd olacaktır.
Şimdi saat örneğimize dönelim. Saatimizin 13 olduğunu biliyoruz. 13+1=14 yaptık.
Bunu BCD koduna çevirelim.
14/10=1.4  burada 1 sayısını alıyoruz.
1*16 = 0001000b sayısına denk gelecektir.
2. işlemde ise 14 mod 10 yaptığımızda kalan 4 olacaktır.
işlem sonucu = 00010100bcd olarak bulunur.

DEC TO BCD için başka bir formül de budur. 
formül : DEC2BCD(dec) (((dec / 10) << 4) + (dec % 10))

BCD TO DEC  formülü : Value=(Value/16 *10) + (Value%16);
Burada ise 98=1001 1000bcd sayısıdır. Bu sayıyı Desimal olarak aldığımızda 152 eder.
152 yi formülde yerine koyalım.
152/16= 9,5  buradan 9 tamsayıyı alalım ve 10 ile çarpalım.
9*10=90 bunu bekletelim ve mod alma işlemini yapalım.
152 mod 16 =8 sayısıdır.
98bcd sayısını buluruz. =10011000bcd

Aşağıda DS1302 entegresinden alınan bilgiler DEC ve HEX olarak gösterilmektedir.
BCD değerler HEX değeri gibi düşünülebilir.
Örnek: dec37 sayısı hex 0x25 sayısına Bin 00100101 sayısına denk gelir.
BCD ye göre 25 sayısı da 0010 0101 sayısına eşittir. Bu tip sayı çevrimlerinde okunuşu birbirine benziyor diye yanlış algılamayın. Mutlaka bilgiyi alırken ve entegreye geri koyarken bu dönüşümlere dikkat edin. 
Sayı dönüşümlerinde buna dikkat ediniz. Saat ekranında görünen sayı BCD sayısıdır ve HEX sayısı gibi okunur.
Bunu ne zaman kullanabilirsiniz. Ancak direkt olarak lcd de göstermek isterseniz (sayı,HEX) olarak gösterebilirsiniz.
İşlemlerde kesinlikle bu şekilde kullanılamaz. Dönüşüm yapmak şarttır.
Yapmazsanız ne olabilir : Ekrandaki dakika 35 tir. bunu öğrendiniz ve dönüşüm yapmadınız. 35= 00110101bcd dir. Bunu 0x35 gibi algılayıp, bunun üzerinde 5 koyarsak toplam 40 olması gerekirken 3A olacaktır. BCD kodlamada 9 dan daha büyük sayı yazamadığımız için hata verecektir.
Bu hatanın önüne geçebilmek için entegreden bilgiyi aldığınızda dönüşüm işlemi yapın ve entegreye yollarken de dönüşüm işlemi yapın. 

Videolarda kullanılan tüm dosyalara buradan ulaşabilirsiniz. 

Not:
Videolarda rs232 usb dönüştürücü ile birlikte seri haberleşme sistemini kullanan EASYLCD modül kullanılmıştır. Tek kablo ile de kütüphanesiz olarak kullanılabilen bir modüldür.
Bu modül hakkında detaylı bilgiyi bu sayfadan alabilirsiniz.

Ayrıca RTC entegrelerde kullanacağınız pillerin ömrünü hesaplamak için bu sayfaya bakabilirsiniz.

DS1302 RTC entegresine ait video:

DS1307 RTC entegresine ait video:

DS3232 ve DS323x I2C sistemli RTC entegresine ait video:

RTC Entegrelerinin gösterimi için EASYLCD ve LCD kütüphane, LCD shield ile çalışması.

Konuda eksik olan yerler varsa iletişim köşesinden bildirebilirsiniz.
Sormak istediklerinizi iletişim köşesinden sorabilirsiniz.

4 Comments

  1. Eline sağlık güzel paylaşım olmuş. Bu paylaşımla ilgili arduino örnekleri de yaparsanız daha çok pekişeceğine eminim elinize yüreğinize sağlık tşk ederiz bu engin bilgilerinizi bizlerle paylaştığınız için.

    1. zaten videolarda arduino üzerine örnekler var. tüm dosyaları aldığınızda arduino dosyalarına da ulaşabilirsiniz. farklı bir arduino program düşünceniz varsa rtv ile ilgili bunu belirtirseniz ben de elimden geldiği kadar örnek vermeye çalışabilirim.

  2. 7 segment displayla rtc ugulaması olabilir ayar kısmını kullanması da pekişir sayenizde tablo okumayı öğrendim bir de ds1302, ds1307, ds3232 bu rtc lerin kodlarını bir araya getirip kütüphane oluşturup diğer rtc kütüphaneleri gibi kullanılsa bu sistemle çok güzel olurdu ☺️

    1. amaç kullanıcıları kütüphane kullanımından uzaklaştırıp konuyu algılayıp, istediği kadarını programına eklemesi veya istediği projeye kolay bir şekilde ekleme yapabilmesi. Bu konuda yazılmış bir çok kütüphane mevcut fakat kütüphaneler sadeleştirildiği için klon olarak az özellikli kütüphanelere dönüştüğünden bazen istediğimiz özelliği kullanamıyoruz. hatta saati kullanıp aynı modülde rtc entegresi içeriğindeki bazı özellikleri kullanamıyoruz. mümkünse kütüphane kullanımından uzaklaşmak konuyu anlamak iyidir. tüm dillerde program yazmak isteseniz kütüphane bulamayabilirsiniz. anladığınızda tüm dillere çevirebilirsiniz.

Cem için bir cevap yazın Cevabı iptal et

E-posta hesabınız yayımlanmayacak.