Bu uygulamamız tarihi ve saati gösteren aynı zamanda kurulabilen bir alarma sahip Atmel firmasının üretmiş olduğu 8051 tabanlı AT89S52 mikrodenetleyicisi kullanılarak tasarlanmıştır.Uygulamamızın kodları C programlama dili kullanılarak Keil derleyicisi kul lanılarak yazılmıştır. Uygulamanın simülasyonu Proteus programının Isis kısmında yapılmış ve baskı devresi yine Proteus programına ait Ares’de çizilmiştir.
Uygulamanın çalışmasından kısaca bahsedecek olursak mikrodenetleyicimizin P0 portuna bağlanmış olan 3 adet anahtar ve 5 adet butonla yapılacak işlem seçilir. Örneğin; alarm kurulacaksa P0_7’e bağlı olan anahtar kapatıldıktan sonra eğer artırma yapılacaksa arttır anahtarı kapatılır ve dakika, saat butonlarına basılarak alarm kurulur. Alarm kurulu oldu- ğunda devrenin üstünde bulunan ve P2_4 pinine bağlı led yanacaktır. Bu sayede kullanıcı devreyi uzaktan gözleyerek alarm kurulumu değimli anlayacaktır. Devre üzerinde otamatik ve manuel olarak iki çeşit reset bulunmaktadır.
Zamanlayıcı /sayıcı0 (T0), otomatik yükleme(mod2) modunda 100 sayma değerine kurul- muş ve her 10.000 sayması 1sn’ye karşılık gelmiştir. Daha sonra saniyenin artışı kontrol ettirilerek dakika saat,gün,ay ve yıl değerleri arttırılmaktadır.
Yıl veya ay değiştirildiğinde gün otomatik olarak değişmektedir. Değişen bu değerler 2×16’lık bir text lcd’de gösterilmektedir. Text lcd’nin birinci satırındaki değerler 10sn’de bir değişmektedir.
Text Lcd (Liquid Cristal Display)
Şekil de görülen 2×16 Text Lcd’dir. Günümüzde kullanılan Lcd’lerin çalışma ilkeleri ve uç bağlantıları standartlaştırılmıştır. Lcd’nin dışardan veri okuyabilme ve dışarıya veri gönde- rebilmesini D0-D7 arasındaki veri yolu sağlar.
Lcd’nin çalışabilmesi için 1 numaralı ucuna (VSS) şase ve 2 numaralı ucuna (VDD) +5 voltluk besleme gerilimi verilir.3 numaralı bacağı Lcd’nin görüntü netlik ayarı(kontrast) için kullanılır. Ayrıca saklayıcı seçme(RS, Register Selected) ucu veri girişilerinden gönderilen 8 bitlik bilginin, bir karakter kodu veya komut olduğunu belirler.(RS=0 veri – RS=1 komut) Oku/yaz (R/W, Read/Write) ucu Lcd’ye veri aktarmak veya Lcd’den veri okumak için kullanılır.(R/W=1 ise veri okuma işlemi R/W=0 ise veriyazma işlemi yapılır.) Yetki (E, Enable) ucu istenilen işlemlerin gerçekleşmesi için lojik 1 seviyesine kurulan tek bitlik giriştir.
EA (External Accsess) : Mikrodenetleyicinin(AT89S52) 31. ucu olan bu uç düşük seviyede aktiftir. +5 voltluk besleme gerilimine yada şaseye bağlanır. +5 volta bağlanırsa programlar dahili romdan şaseye bağlanırsa programlar harici bellekten çalışır.
Alarm Devresi
Bu devrede özel olarak üretilmiş melodi transistorü olan UM 66 kullanılmıştır. Mikrodenetleyicinin 24.pininin (Port2_3) çıkış akımı çok zayıf olduğu için burada anahtarlama ele- manı olarak BC 547(npn) bir transistör kullanılmıştır.
UM66 ve Transistör bacak bağlantıları
AT89S52 Özellikleri ve Pin Konfigürasyonu
AT89S52 Özellikleri
• Kontrol uygulamalarına yönelik 8-bit CPU
• Mantıksal işlemci
• 8051-Tabanlı Düşük-Voltaj 16MHz CMOS Kontroller 4 adet 8-bit giriş/çıkış(I/O) portu(32 uç)
• 3 adet Zamanlayıcı/sayıcı,
• Watchdog Zamanlayıcı,
• 2 öncelik seviyesine sahip 8 kesme donanım yapısı
• UART, 2 DPTRs,
• 8K Byte Flash hafıza (ISP),
• 256 Byte On-chip RAM
Devrenin baskı şeması Proteus programının Ares kısmında çizilmiştir. Asetad ve ütü yöntemi kullanılarak bakırlı plaket üzerine basılmıştır.
Uygulamanın C Kodları
#include// islemci baslik dosyasi #include "T_LCD.H" // LCD baslik dosyasi #include // C dili baslik dosyasi #include // C dili baslik dosyasi /* Degisken Tanimlamalari */ int s1=0, s2=0, sn1=0, sn2=0, d1=0, d2=0, g1, g2=1,as1=0,as2=0,ad1=0,ad2=0; int a1, a2=1, y1=2, y2=0, y3=0, y4=0; int dongu=0; // 100 kesme = bir saniye oluyor int aysure[12]={31,29,31,30,31,30,31,31,30,31,30,31}; // ay günleri int haftagun = 0; bit Alarm_Kurulu=0; /* Ayar Butonlarinin Uç Tanimlamasi */ #define Azalt P0_0 #define Arttir P0_1 #define Dakika P0_2 #define Saat P0_3 #define Gün P0_4 #define Ay P0_5 #define Yil P0_6 #define Alarm P0_7 #define Alarm_Calsin P2_3 #define Akur P2_4 ///////////////////////////////////////////////////////////////////////////////////////////////////// // Saniye Fonksiyonu // // saniye sayaci ayarlaniyor // //////////////////////////////////////////////////////////////////////////////////////////////////// void saniye(void) { sn2++; if (sn2==10) //saniyenin onlar basamagina geçis kontrolü { sn1++; sn2=0; if(sn1==6) sn1=0; // saniyenin 60 kontrolü } } ////////////////////////////////////////////////////////////////////////////////////////////// // Dakika Fonksiyonu // // dakika sayaci ayarlaniyor // /////////////////////////////////////////////////////////////////////////////////////////////// void dakika(int deger) { if (deger) { d2++; if (d2==10) //dakikanin onlar basamagina geçis kontrolü { d1++; d2=0; if(d1==6) d1=0; // dakikanin 60 kontrolü } } else { d2--; if (d2==-1) { d2=9; d1--; if(d1==-1) d1=5; } } } /////////////////////////////////////////////////////////////////////////////////////////////// // Saat Fonksiyonu // // saat sayaci ayarlaniyor // // s2:saat birler basamagi s1:saat onlar basamagi // /////////////////////////////////////////////////////////////////////////////////////////////// void saat(int deger) { if (deger) { s2++; if(s1==2 && s2==4) // 24 kontrolü { s1=0; s2=0; } if (s2==10) { s1++; s2=0; } } else { s2--; if(s1==0 && s2==-1) { s1=2; s2=3; } if((s1!=0) && s2==-1) { s1--; s2=9; } } } //****************************************************// // alarm fonksiyonu // // alarm sayaci ayarlaniyor // //****************************************************// void alarm_dakika(int deger) //alarm dakika kismi {Akur=1; if (deger) { ad2++; //alarm dakika artrir bututonuna basiliyor if (ad2==10) //dakikanin onlar basamagina geçis kontrolü { ad1++; ad2=0; if(ad1==6) ad1=0; // dakikanin 60 kontrolü } } else { ad2--; //alarm dakika azalt butonu ayari if (ad2==-1) { ad2=9; ad1--; if(ad1==-1) ad1=5; } } } void alarm_saat(int deger) //alarm saat ayarlaniyor {Akur=1; if (deger) { as2++; if(as1==2 && as2==4) // 24 kontrolü { as1=0; as2=0; } if (as2==10) { as1++; as2=0; } } else { as2--; if(as1==0 && as2==-1) { as1=2; as2=3; } if((as1!=0) && as2==-1) { as1--; as2=9; } } } //////////////////////////////////////////////////////////////////////////////////////////////////////////// // Hafta Günü Bulan Fonksiyon // // Yil ve Ay'a göre haftanin günü ayarlaniyor // /////////////////////////////////////////////////////////////////////////////////////////////////////////// void haftaningunu(void) { int i; haftagun = g1*10 + g2; // haftanin günü for (i=0;i<(a1*10+a2-1);i++) haftagun = haftagun + aysure[i]; // haftanin gününe geçen // aylarin günü ekleniyor if (a1*10+a2 > 2) haftagun--; // subat 29 sayildigindan 1 gün düsülüyor // artik ilk yilda subat ayi gelmemisse haftagun bir eksiliyor if (((y1*1000+y2*100+y3*10+y4)%4 == 0) && (a1*10+a2 <= 2)) haftagun--; //hafta gününe geçen yil * 365 + artik yillar için 1 gün ekleniyor haftagun = haftagun + (y1*1000+y2*100+y3*10+y4) * 365; haftagun = haftagun + (y1*1000+y2*100+y3*10+y4) / 4; // mod 7 ile haftanin günü belirleniyor haftagun = haftagun % 7; } ///////////////////////////////////////////////////////////////////////////////////////////////////////// // Gün Hesabini Yapan Fonksiyon // // haftaningunu() fonksiyonu ile birlikte çalisiyor // ///////////////////////////////////////////////////////////////////////////////////////////////////////// void gun(int deger) { g2 = g2 + deger; // gün degiskeni artiriliyor // ay günü 29 hesaplandigindan 28 çeken günlerde ayin degismesi // için gün 29 yapiliyor if (((y1*1000+y2*100+y3*10+y4)%4 != 0) && (a1*10+a2 == 2) && (g1*10+g2 == 29)) { g2++; } // gün sayaci ayarlaniyor if (deger) { if (g1*10+g2 > aysure[a1*10+a2-1]) { g1 = 0; g2 = 1; } if (g2==10) { g1++; g2=0; } } else { if ((g1==0) && (g2==0)) { g1 = aysure[a1*10+a2-1] / 10; g2 = aysure[a1*10+a2-1] % 10; } if ((g1!=0) && (g2==-1)) { g1--; g2=9; } if (((y1*1000+y2*100+y3*10+y4)%4 != 0) && (a1*10+a2 == 2) && (g1*10+g2 == 29)) { --g2; } } haftaningunu(); } //////////////////////////////////////////////////////////////////////////////////////////////////////////// // Ay Fonksiyonu // // Ay sayaci ayarlaniyor // void ay(int deger) { if (deger) { if (a1==1 && a2==2) { a1=0; a2=0; } a2++; if (a2==10) { a1++; a2=0; } } else { --a2; if ((a2==0) && (a1==0)) { a1=1;a2=2; } if ((a2==-1) && (a1==1)) { a1=0;a2=9; } } haftaningunu(); } //////////////////////////////////////////////////////////////////////////////////////////////////////////// // Yil Fonksiyonu // // Yil sayaci ayarlaniyor // /////////////////////////////////////////////////////////////////////////////////////////////////////////// void yil(int deger) { if (deger) { y4++; if (y4==10) { y4=0; y3++; if (y3==10) { y3=0; y2++; if (y2==10) { y2=0; y1++; } } } } else { y4--; if (y4==-1) { y4=9; y3--; if (y3==-1) { y3=9; y2--; if (y2==-1) { y2=9; y1--; } } } } haftaningunu(); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////// // Zamanlayici Sayici Kesme Fonksiyonu // // T0 kesmesi kullanarak 1 sn'lik gecikme elde edilmesi // ///////////////////////////////////////////////////////////////////////////////////////////////////////////// timer_isr () interrupt 1 { int bekleme=0; dongu++; if (dongu == 10000) // 100 kesme 1 saniye oluyor { saniye(); if (sn1==0 && sn2==0) // dakika kismi { dakika(1); } if(sn1==0 && sn2==0 && d1==0 && d2==0) // saat kismi { saat(1); } if(!Alarm) //alarm kismi { if(Akur) { if(d1==ad1 && d2==ad2 && s1==as1 && s2==as2) //alarm caliyor Alarm_Calsin=1; else { if(Alarm_Calsin) Akur=0; Alarm_Calsin=0; } } } if(sn1==0 && sn2==0 && d1==0 && d2==0 && s1==0 && s2==0) { gun(1); // gün kismi } if(sn1==0 && sn2==0 && d1==0 && d2==0 && s1==0 && s2==0 && g1==0 && g2==1) // ay kismi { ay(1); } if (sn1==0 && sn2==0 && d1==0 && d2==0 && s1==0 && s2==0 && g1==0 && g2==1 && a1==0 && a2==1) // yil kismi { yil(1); } dongu = 0; } } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Gün Yazma Fonksiyonu // // Günlerin yazi ile LCD'de gösterilmesini saglar // //////////////////////////////////////////////////////////////////////////////////////////////////////////////// void gunyaz(int g) { int i; code char *gunadi[7]={"Cmt","Pzr","Pzt", "Sal","Car","Per", "Cum"}; for (i=0;i<3;i++) { if (g==0) Veri(*(gunadi[g]+i),0); if (g==1) Veri(*(gunadi[g]+i),0); if (g==2) Veri(*(gunadi[g]+i),0); if (g==3) Veri(*(gunadi[g]+i),0); if (g==4) Veri(*(gunadi[g]+i),0); if (g==5) Veri(*(gunadi[g]+i),0); if (g==6) Veri(*(gunadi[g]+i),0); } } ///////////////////////////////////////////////////////////////////////////////////////////////////////////// // LCD'ye Yazdirma Fonksiyonu // // Saniye, Dakika,Saat,Gün, Ay ve Yil // //////////////////////////////////////////////////////////////////////////////////////////////////////////// void bastir(void) { int i,j; code char sayi[10]={'0','1','2','3','4','5','6','7','8','9'}; // lcd'ye bastirilacak kisiltmalar code char *reklam ={"A.ACAY 010303028"}; code char *ayadi[12]={"01","02","03","04", "05","06","07","08", "09","10","11","12"}; /* Saati yazdiriyor */ Komut(IkinciSatir); for(i=0;i<4;i++) // bastaki bosluk: lcd göstergenin basinda 1 bosluk birakmak icin Veri (' ',0); Veri (sayi[s1],0); Veri (sayi[s2],0); Veri (':',0); Veri (sayi[d1],0); Veri (sayi[d2],0); Veri (':',0); Veri (sayi[sn1],0); Veri (sayi[sn2],0); /* Tarih kismini yazdiriyor */ Komut(BirinciSatir); if(Alarm) { for(i=0;i<5;i++) // bastaki bosluk Veri (' ',0); Veri (sayi[as1],0); Veri (sayi[as2],0); Veri (':',0); Veri (sayi[ad1],0); Veri (sayi[ad2],0); for(i=17;i<32;i++) // bastaki bosluk Veri (' ',0); } else { if (((sn1%2)==0) || (Arttir==1) || (Azalt == 1)) { Veri (' ',0); gunyaz(haftagun); Veri ('-',0); Veri (sayi[g1],0); Veri (sayi[g2],0); Veri ('-',0); for (j=0;j<2;j++) Veri (*(ayadi[a1*10+a2-1]+j),0); Veri ('-',0); Veri (sayi[y1],0); Veri (sayi[y2],0); Veri (sayi[y3],0); Veri (sayi[y4],0); Veri (' ',0); } else { for (i=0;i<32;i++) Veri(*(reklam+i),0); } } } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // ANA PROGRAM // /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void main (void) { P0=0x00; // P0'a basli butonlari resetle Alarm_Calsin=0; //P2_3 'cü pini sifirla Akur=0; //P2_4 'cü pini sifirla LcdAc(); // LCD açilis islemleri Komut(Sil); // Zamanlayici ve Kesmelerin kurulumu TMOD = 0x02; /* TMOD zamanlayici T0 in mod 2 ye kurulmasi*/ IE = 0x82; /*kesme yetkilendirme saklayicisi*/ TH0=-100; TL0=-100; TR0 = 1; while(1) { if(Alarm) { if(Arttir && !Azalt) { if (Dakika) alarm_dakika(1); if (Saat) alarm_saat(1); } if(Azalt && !Arttir) { if (Dakika) alarm_dakika(0); if (Saat) alarm_saat(0); } } while(!Alarm && Azalt) // alarm butonu açık ve azalt butonu basılı { sn1=0; sn2=0; if (Dakika) dakika(0); if (Saat) saat(0); if (Gün) gun(0); if (Ay) ay(0); if (Yil) yil(0); bastir(); Gecikme(5000); } while(!Alarm && Arttir) // alarm butonu açık ve arttır butonu basılı { sn1=0; sn2=0; if (Dakika) dakika(1); if (Saat) saat(1); if (Gün) gun(1); if (Ay) ay(1); if (Yil) yil(1); bastir(); Gecikme(5000); } bastir(); }
Yukarıda yazmış olduğumuz programın, LCD’de istenilen karakterleri ekrana basabilmesi bazı başlangıç ayarlarının yapılması gerekmektedir. Göstergenin açılması, kullanılacak bit sayısının belirlenmesi LCD’nin çalışması için ilk yapılması gereken işlemlerdir.
Metin ekran LCD uygulamalarında standart olarak kullanılacak olan komut gönderme, LCD’nin başlangıç koşullarını ayarlama vb. rutinleri bir fonksiyon olarak tanımlamak ve gerektiğinde çağırmak için aşağıdaki T_LCD fonksiyonundan yararlanılmıştır. Bu fonksiyon kütüphane dosyası olarak kaydedilmiştir.
/****************************************************************/ /* T_LCD.H */ /****************************************************************/ /* LCD'de kullanılan komutların tanımlanması */ #define Sil 1 // Ekranı temizler #define BasaDon 2 // İmleci sol üst köşeye getirir #define SolaYaz 4 // İmlecin belirttiği adres azalarak gider #define SagaYaz 6 // İmlecin belirttiği adres artarak gider #define ImlecGizle 12 // Göstergeyi aç, kursör görünmesin #define ImlecYanSon 15 // Yanıp sönen blok kursör #define ImlecGeri 16 // Kursörü bir karakter geri kaydır #define KaydirSaga 24 // Göstergeyi bir karakter sağa kaydır #define KaydirSola 28 // Göstergeyi bir karakter sola kaydır #define EkraniKapat 8 // Göstergeyi kapat (veriler silinmez) #define BirinciSatir 128 // LCD'nin ilk satir başlangıç adresi // (DDRAM adres) #define IkinciSatir 192 // İkinci satırın başlangıç adresi #define KarakUretAdres 64 // Karakter üreteci adresini belirle // (CGRAM adres) /* LCD'de Kullanılan Fonksiyon Seçimi */ #define CiftSatir8Bit 56 // 8 bit ara birim, 2 satır, 5*7 piksel #define CiftSatir4Bit 48 // 8 bit ara birim, 1 satır, 5*7 piksel #define TekSatir8Bit 40 // 4 bit ara birim, 2 satır, 5*7 piksel #define TekSatir4Bit 32 // 4 bit ara birim, 1 satır, 5*7 piksel /* LCD Girişlerinin Tanımlanması */ #define Data P1 // LCD Data girişleri için port ata #define RS P2_2 // Saklayıcı seçme girişi RS=0 komut, RS=1 veri #define RW P2_1 // Oku/Yaz girişi RW=0 yaz, RW=1 oku #define EN P2_0 // Yetki girişi /* LCD Gecikme Fonksiyonu */ void Gecikme (long int sure) { long int i; for (i=1;i<=sure;i++) {;} } /* LCD Hazır Olana Kadar Bekle Fonksiyonu */ //void LcdHazir () //{ // Data=0xFF; // LCD den veri almaya hazirlan // RS = 0; // komut modu // RW = 1; // LCDden okuma // EN = 1; // yetki için düşen kenar ayarı // Gecikme(200); // kısa bir bekleme süresi // while(Data & 0x7F == 0x80); // mesgul bitini kontrol et. //} /* LCD'ye Komut Yazdırma Fonksiyonu */ void Komut (int komut) { // LcdHazir(); // LCD hazir olana kadar bekle RS=0; // RS komut modunda RW=0; // RW yaz modunda EN=1; // işlemin yetkilendirilmesi için düşen kenar ayarı Data=komut; // LCD data girişlerine komut bilgisini aktar EN=0; // yetki için düşen kenar sağlandı Gecikme(1000); // gecikme } /* LCD'ye Tek Bir Karakter Yazdırma Fonksiyonu */ void Veri (char veri,unsigned int hiz) { // LcdHazir(); // LCD hazir olana kadar bekle RS=1; // RS komut modunda RW=0; // RW yaz modunda EN=1; // yetki için düsen kenar ayar işlemi Data=veri; // LCD data girişlerine veri bilgisini aktar EN=0; // yetki için düşen kenar sağlandı Gecikme(hiz); // Ekranda karakterlerin görünmesi arasındaki süre } /* LCD'ye Karakter Dizisi (String) Yazdırma Fonksiyonu */ /*void VeriDizi (char veri[], long int hiz) { int i=0; while(veri[i]!=0) { // LcdHazir(); // LCD hazir olana kadar bekle RS=1; // RS komut modunda RW=0; // RW yaz modunda EN=1; // yetki için düsen kenar ayar işlemi Data=veri[i]; // LCD data girişlerine veri bilgisini aktar EN=0; // yetki için düşen kenar sağlandı i++; // bir sonraki veri bitini almak için dizi'yi 1 arttır Gecikme(hiz); // karakterlerin görünmesi arasındaki süre } }*/ /* LCD Başlangıç Ayarlarını Yapan Fonksiyon */ void LcdAc(void) { Komut(ImlecGizle); Komut(CiftSatir8Bit); Komut(SagaYaz); }
Hazırlayan: Arif ACAY Emeği geçen Kişilere Teşekkürler.
Şifre-Pass: 320volt.com
Yayım tarihi: 2008/11/02 Etiketler: alarm, ares, AT89S52, atmel avr projeleri, atmel devreleri, C++ kodları, dijital, display, isis, lcd devreleri, mikrodenetleyi, proteus, Saat, um66
ne yazıkki hex dosyası yok
Hex dosyaları kaynak C kodlarından derlenir tahminimce yazıda verilen kaynak c kodlarını keil programı ile hex olarak derleyebilirsiniz
Bakınız http://www.8051turk.com/download_files/KeilISISveFlip.pdf
ben bunu AT89S52 mikrodenetleyicisi ile değilde AT89C51RC2 ile yapmak istiyorum. bir yardımcı olabilir misiniz? teşekkürler…
Bu devrede sağ alt köşeye GÜN:01 olarak yazdırabilirmiyiz? Teşekkürler