Bu projede, 8051 mikrodenetleyici kullanarak bir RTC Clock yapmayı göstereceğiz. Bu projeyi Arduino ile yapmak istiyorsanız, Arduino kullanarak bu dijital saati kontrol edin. Bu projenin ana bileşeni, gerçek zamanlı dijital saat entegresi olan DS1307'dir. Bu IC'yi detaylı olarak öğrenelim.
RTC DS1307:
DS1307 seri gerçek zamanlı saat (RTC), düşük güçlü, tam ikili kodlu ondalık (BCD) saat / takvim artı 56 bayt NV SRAM'dir. Bu çip, I²C protokolü üzerinde çalışır. Saat / takvim saniye, dakika, saat, gün, tarih, ay ve yıl bilgilerini sağlar. Ay sonu tarihi, artık yıl düzeltmeleri de dahil olmak üzere 31 günden az olan aylar için otomatik olarak ayarlanır. Saat, AM / PM göstergesiyle 24 saatlik veya 12 saatlik biçimde çalışır. DS1307, güç kesintilerini algılayan ve otomatik olarak yedek kaynağa geçiş yapan yerleşik bir güç algılama devresine sahiptir. Parça yedek beslemeden çalışırken zaman işleyişi devam eder. DS1307 yongası 10 yıla kadar sürekli çalışabilir.
8051 tabanlı Gerçek zamanlı saat, I2C protokolü üzerinde çalışan bir RTC DS1307 kullanarak gerçek zamanı gösteren dijital bir saattir. Gerçek zamanlı saat, elektrik kesintisinden sonra bile çalıştığı anlamına gelir. Güç yeniden bağlandığında, kapalı durumda olduğu zaman ve süreye bakılmaksızın gerçek zamanı görüntüler. Bu projede saati - (saat, dakika, saniye, tarih, ay ve yıl) formatında görüntülemek için 16x2 LCD modül kullandık. Gerçek zamanlı saatler bilgisayarlarımızda, evlerimizde, ofislerimizde ve elektronik cihazlarımızda onları gerçek zamanlı olarak güncel tutmak için yaygın olarak kullanılmaktadır.
I2C protokolü, iki kablo kullanarak iki veya daha fazla cihazı tek bir sisteme bağlamak için bir yöntemdir ve bu nedenle bu protokol aynı zamanda iki kablolu protokol olarak da adlandırılır. 127 cihazı tek bir cihaza veya işlemciye iletmek için kullanılabilir. I2C cihazlarının çoğu 100 Khz frekansında çalışır.
Master'dan slave'e veri yazma adımları (bağımlı alıcı modu)
- BAŞLAT koşulunu slave'e gönderir.
- Slave adresini slave'e gönderir.
- Slave'e yazma biti (0) gönderin.
- Slave'den ACK biti alındı
- Slave'e kelime adresi gönderir.
- Slave'den ACK biti alındı
- Verileri slave'e gönderir.
- Slave'den ACK biti alındı.
- Ve son olarak STOP koşulunu slave'e gönderir.
Slave'den master'a veri okuma adımları (slave aktarım modu)
- BAŞLAT koşulunu slave'e gönderir.
- Slave adresini slave'e gönderir.
- Okuma bitini (1) slave'e gönderin.
- Slave'den ACK biti alındı
- Slave'den veri alındı
- Slave'den ACK biti alındı.
- STOP koşulunu slave'e gönderir.
Devre Şeması ve Tanımı
Devrede DS1307, AT89S52 ve LCD'nin 3 bileşenini kullandık. Burada AT89S52, DS1307'den zamanı okumak için kullanılır ve 16x2 LCD ekranda gösterir. DS1307, mikrodenetleyiciye 2 satır kullanarak saat / tarih gönderir.
Devre bağlantılarının anlaşılması kolaydır ve yukarıdaki şemada gösterilmiştir. DS1307 çip pimi SDA ve SCL, veri ve saat hatlarında varsayılan değeri HIGH tutan yukarı çekme direnci ile 89S52 mikro denetleyicinin P2.1 ve P2.0 pinlerine bağlanır. Ve tam 1 saniyelik gecikme oluşturmak için 32.768KHz kristal osilatör DS1307 yonga ile bağlanmıştır. Ve elektrik kesintisinden sonra zamanın devam etmesini sağlayan DS1307'nin 3. pimine (BAT) 3 voltluk bir pil de bağlanır. 16x2 LCD, 4 bit modunda 8051'e bağlanır. Kontrol pimi RS, RW ve En doğrudan 89S52 pini P1.0, GND ve P1.1'e bağlanır. Ve D0-D7 veri pini 89S52'nin P1.4-P1.7'sine bağlıdır.
Saat zamanını 89S52'nin P2.4, P2.3 ve P2.2 pinlerine ayarlamak için SET, INC / CHANGE ve Next adlı üç düğme kullanılır (aktif düşük). SET'e bastığımızda zaman ayar modu devreye girer ve şimdi INC / CHANGE butonunu kullanarak zamanı ayarlamamız gerekir ve haneye geçmek için Next butonu kullanılır. Zaman ayarlandıktan sonra saat sürekli çalışır.
Program Açıklaması
Kodda 8051 aile kitaplığı ve standart bir girdi çıktı kitaplığı ekledik. Ve kullandığımız pimleri tanımladık ve hesaplamalar için bazı değişkenler aldık.
#Dahil etmek
Ve verilen fonksiyon LCD'yi sürmek için kullanılır.
geçersiz tarih () {rs = 1; en = 1; gecikme (1); en = 0; } void lcddata (işaretsiz karakter ch) {lcdport = ch & 0xf0; daten (); lcdport = (ch << 4) & 0xf0; daten (); } void cmden (void) {rs = 0; en = 1; gecikme (1); en = 0; } void lcdcmd (işaretsiz karakter ch)
Bu işlev, RTC'yi başlatmak ve RTC IC'den saat ve tarihi okumak için kullanılır.
I2CStart (); I2CSend (0xD0); I2CSend (0x00); I2CStart (); I2CSend (0xD1); sec = BCDToDecimal (I2CRead (1)); min = BCDToDecimal (I2CRead (1)); saat = BCDOndalık (I2CRead (1)); gün1 = BCDToDecimal (I2CRead (1)); tarih = BCDToDecimal (I2CRead (1)); mon = BCDToDecimal (I2CRead (1)); yıl = BCDToDecimal (I2CRead (1)); I2CStop (); gösteri zamanı(); // zaman / tarih / gün gecikmesini göster (1);
Bu işlevler, ondalık sayıları BCD'ye ve BCD'yi Ondalık sayıya dönüştürmek için kullanılır.
int BCDToDecimal (char bcdByte) {char a, b, dec; a = (((bcdByte & 0xF0) >> 4) * 10); b = (bcdByte ve 0x0F); dec = a + b; dönüş aralık; } char DecimalToBCD (int decimalByte) {char a, b, bcd; a = ((decimalByte / 10) << 4); b = (decimalByte% 10); bcd = ab; dönüş bcd; }
Aşağıda verilen fonksiyonlar I2C İletişimi için kullanılır.
void I2CStart () {SDA = 1; SCL = 1, SDA = 0, SCL = 0;} // ds1307 RTC void I2CStop ile iletişim için "start" işlevi () {SDA = 0, SCL = 1, SDA = 1; } // ds1307 ile iletişim kurmak için "durdur" işlevi RTC işaretsiz karakter I2CSend (işaretsiz karakter Verisi) // verileri ds1307'ye gönder {char i; char ack_bit; için (i = 0; i <8; i ++) {if (Data & 0x80) SDA = 1; aksi takdirde SDA = 0; SCL = 1; Veri << = 1; SCL = 0; } SDA = 1, SCL = 1; ack_bit = SDA; SCL = 0; dönüş ack_bit; } unsigned char I2CRead (char ack) // ds1307'den veri alır {unsigned char i, Data = 0; SDA = 1; for (i = 0; i <8; i ++) {Data << = 1; yap {SCL = 1;} while (SCL == 0); eğer (SDA) Veri- = 1; SCL = 0; } if (ack) SDA = 0; aksi takdirde SDA = 1; SCL = 1; SCL = 0; SDA = 1; Verileri döndür; }
Set_time işlevi, saati saat içinde ayarlamak için kullanılır ve aşağıdaki show_time işlevi, LCD'de zamanı görüntülemek için kullanılır.
void show_time () // LCD'de saati / tarihi / günü görüntülemek için işlev {char var; lcdcmd (0x80); lcdprint ("Tarih:"); sprintf (var, "% d", tarih); lcdprint (var); sprintf (var, "/% d", pazartesi); lcdprint (var); sprintf (var, "/% d", yıl + 2000); lcdprint (var); lcdprint (""); lcdcmd (0xc0); lcdprint ("Zaman:"); sprintf (var, "% d", saat); lcdprint (var); sprintf (var, ":% d", min); lcdprint (var); sprintf (var, ":% d", sn); lcdprint (var); lcdprint (""); // gün (gün1); lcdprint (""); }