Ana səhifə Elektronika DS1307RTC Real zaman saatı

DS1307RTC Real zaman saatı

441

Kompüterlərimizdə saatların güc qaynağı olmadan ili, ayı, günü və saatı necə yadda saxladığını yəqin ki, həyatında bir dəfə də olsun düşünmüsünüz:) Əlbəttə orda bir “saat daşı” var deyib keçmisiniz. Əlbəttə orda bir pil vardır lakin təqvimi və saatı yadda saxlayan “Real Zaman Saatı” deyə adlandırdığımız mikrosxemlərdir. Real zaman saatları illərcə kiçik bir litium pillə işləyə bilən zəif axınlı dövrələrdir. Cihazların güc qaynaqlarını qapatsaq belə öz litium pili ilə uzun müddət təqvim və saatın davamiyyətini qoruyur.

İstifadə etdiyimiz Arduino, Rasberry kimi bütün kontrollerlərin bir real zaman dövrəsi vardır lakin güc qaynaqlarından ayırdığımız zaman bu zaman sayan dövrələr avtonom olaraq çalışmır və sıfıra qayıdır. Bu səbəblə layihələrimizdə kəsintili güc qaynaqlarından avtonom işləyən bir dövrəyə ehtiyac duyuruq. Bu məqalədə real zaman saatının populyar örnəklərindən DS1307 mikrosxemi haqqında əsas bilgiləri sizə çatdırmağa çalışacam.DS1307, I2C protokoluna əsasən işləyən bu dövrələrdən biridir. Elektronik komponent mağazalarından bu dövrəni DİP8 və hazır modul şəklində əldə etmək olur.

Şəkil 1. DS1307 DİP8 şəklində
Şəkil 2. DS1307 üzərində litium pil olan hazır modul

Kontrollerlərin daxili zaman sayan dövrələri yalnız həvəskar dövrələrdə istifadə üçün nəzərdə tutlub. Böyük və professional layihələrdə isə real zaman saatları istifadəsi vazkeçilməzdir.

DS1307 bağlantıları çox asan və işləməsi çox praktikdir. Aşağıdakı bağlantı qaydaları ilə tanış olduqdan sonra ATmega və Arduino üzərində təcrübə edəcəyik.

Şəkil 3. DS1307 PİC ilə bağlantı
Səkil 4. DS1307 Arduino ilə bağlantı
Şəkil 5. DS1307 Arduino ilə displey bağlantısı
Şəkil 6. ATmega ilə bağlantı

Yuxarıda gördüyünüz örnəklərdə bağlantı şəkillərindən istifadə edərək istənilən cihaza inteqrasiya edə bilərsiniz.

İndi isə gəlin DS1307 dövrəsinin pin sıralaması ilə tanış olaq.

Pin açıqlaması

X1 və X2 ayaqları daxili osillatoru işə salmaq üşün istifadə edilən pinlərdir. Bu ayaqlara 32768 Khz freqans kristalı bağlanır. Şəkil 1-də lövhə üzərindəki kristalı aydın görə bilərsiniz. Bundan əlavə xarici bir osillator X1 ayağına bağlı olarsa o zaman X2 ayağını boş buraxa bilərsiniz.

VBAT ayağı pil-dən gələn güc qaynağı üçündür. 3V yetərlidir ki dövrəmiz işə düşsün.

GND hər zamankı kimi torpaqlamadır(neqativ)

SDA ayağı ardıcıl verilənlər (serial data) girişidir. I2C  xəbərləşməsi üçün I2C interfeysinin giriş və çıxış ayağıdır. Arada 10KΩ dirənc istifadə edərək 5V-a bağlanır.

SCL ayağı I2C interfeysinin saat giriş pinidir. Arada 10KΩ dirənc istifadə edərək 5V-a bağlanır.

SQW/OUT düzbucaqlı dalğa çıxış ayağıdır. İstifadə etməyə ehtiyac duymadığınız zaman boş buraxa bilərsiniz.

Vcc əsas qida girişidir.

İndi isə DS1307 dövrəmizi Arduino ilə çalışdıraq

Başlamadan öncə qeyd edim ki, Arduino ilə quralan dövrədə hər zaman kontrollerin real zaman saatı I2C interfeysi master(yəni adruino mikrokontrolleri saat siqnalı, verilənlər yolu, başlatmaq və dayandırmaq kimi əməliyyatlara cavabdeh olur) DS1307 isə salve kimi işləyir.

İlk növbədə Arduino üçün kitabxana faylını yükləmək lazımdır. Kitabxana fayllarını aşağıdakı linklərdən endirə bilərsiniz.

DS1307RTC-1.4.1Download

DS1307RTC-1.4.0Download

Bu proyektdə isə proqram içərisində ‘RTClib’ adlı xüsusi bir kitabxana istifadə edilmişdir və github/adafruit/RTClib üzərindən bu kitabxananı endirilə bilərsiniz.

Endirib Arduino kitabxanasının verilənlər bazasına əlavə olunduğundan əmin olmalısınız. Məlumatları və saatı DS1307 RTC inteqrə dövrəsinə yükləmək üçün, RTClib kitabxanasında olan və Arduinonun kodu yükləyərkən tarix və saatı kompüterdən yükləyəcəyi bir xüsusiyyətdən istifadə edilmişdir.

Dövrə sxemi:

DS 1307 RTC Modulu üçün ;

VCC  = +5V

GND = Torpaq

SDA = Arduino Analog giriş PC4/ADC4/SDA

SCL = Arduino analog giriş PC5/ADC5/SCL

16×2 LCD Gösrüntü üçün ;

GND 1 = Torpaq

VCC 2 = +5V

Cont 3 = 10 KΩ Pot(potensiometr)

RS 4 = Arduino PD7/AIN1

E 6 = PD6/AIN0

D4 11= PD5/T1

D5 12 = PD4/T0/XCK

D6 13= PD3/INT1

D7 14 = PD2/INT0

LED+ 15 = -> 1 kΩ dirənc -> +5V

LED- 16 = Torpaq

Arduino Kodu :

#include <Wire.h>

#include <LiquidCrystal.h>

#include “RTClib.h”

RTC_DS1307 rtc;

LiquidCrystal lcd(7,6,5,4,3,2); // (rs,e,d4,d5,d6,d7)

char daysOfTheWeek[7][12] = {“Sun”,”Mon”,”Tue”,”Wed”,”Thu”,”Fri”,”Sat”};

void setup ()

{

Serial.begin(9600);

lcd.begin(16, 2)

if (! rtc.begin())

{

lcd.print(“RTC tapılmadı”);

while (1);

}

if (! rtc.isrunning() )

{

lcd.print(“RTC ishlemir”)

}

rtc.adjust(DateTime(F(__DATE__),F(__TIME__))); //PC’dən zamanı yenilə

}

void loop ()

{

DateTime now = rtc.now();

lcd.setCursor(0,1);

lcd.print(now.hour());

lcd.print(‘ : ’);

lcd.print (now.minute());

lcd.print(‘ : ’);

lcd.print(now.second());

lcd.print(“    ”);

lcd.setCursor(0,0);

lcd.print(daysOfTheWeek[now.dayOfTheWeek()]);

lcd.print(“ , ”);

lcd.print(now.day());

lcd.print(‘ / ’);

lcd.print(now.month());

lcd.print(‘ / ’);

lcd.print(now.year());

}

PİC ilə qurulan dövrəni də sizə təqdim edirəm.

DİQQƏT! Pic ilə DS1307 ye istifadə edərkən əmrlərinizə birbaşa cavab vermir. Əvvəlcə DS1307-ye bir başlanğıc saatı təyin etməniz lazımdır. Yalnız ondan sonra saat, təyin etdiyiniz tarixdən və saatdan başlayaraq real zamanlı saat və tarix saymağa başlayır. Pic Basic pro saatı yazmaq və oxumaq üçün belə bir kombinasiya yaradıla bilər.

1-ci addım: RTC DS1307-ə Saat və Təqvim təyin edirik

void RTC_Clock_Write(char sec, char min, char hour, char AM_PM)                                /* function for clock */

{

    hour = (hour | AM_PM);     /* whether it is AM or PM */

        I2C_Start(device_id_write);/* start I2C comm. with device slave address*/  

        I2C_Write(0);                     /* write 0 location for sec value */

        I2C_Write(sec);                   /* write second value on 00 location */

        I2C_Write(min);                   /* write min value on 01 location */

        I2C_Write(hour);                  /* write hour value on 02 location */

        I2C_Stop();                              /* stop I2C communication */

}

void RTC_Calendar_Write(char day, char date, char month, char year)  /* function for calendar */

{

        I2C_Start(device_id_write);/* start I2C comm. with device slave address */

        I2C_Write(3);                     /* write on 3 location for day value */

        I2C_Write(day);                   /* write day value on 03 location */

        I2C_Write(date);                  /* write date value on 04 location */

        I2C_Write(month);                 /* write month value on 05 location */

        I2C_Write(year);                  /* write year value on 06 location */

        I2C_Stop();

}

2-ci addım. Təqvim və zamanı RTC DS1307-dən oxuyuruq:

#include <stdio.h>

#include “Configuration_Header_File.h”

#include “16x2_LCD_4bit_File.h”

#include <pic18f4550.h>

#include “I2C_Master_File.h”

#define device_id_write 0xD0

#define device_id_read 0xD1

int sec,min,hour;

int Day,Date,Month,Year;

void RTC_Read_Clock(char read_clock_address)

{

    I2C_Start(device_id_write);

    I2C_Write(read_clock_address);     /* address from where time needs to be read*/

    I2C_Repeated_Start(device_id_read);

    sec = I2C_Read(0);                 /*read data and send ack for continuous reading*/

    min = I2C_Read(0);                 /*read data and send ack for continuous reading*/

    hour= I2C_Read(1);                 /*read data and send nack for indicating stop reading*/

}

void RTC_Read_Calendar(char read_calendar_address)

{  

    I2C_Start(device_id_write);

    I2C_Write(read_calendar_address); /* address from where time needs to be read*/

    I2C_Repeated_Start(device_id_read);

    Day = I2C_Read(0);                /*read data and send ack for continuous reading*/

    Date = I2C_Read(0);               /*read data and send ack for continuous reading*/

    Month = I2C_Read(0);              /*read data and send ack for continuous reading*/

    Year = I2C_Read(1);               /*read data and send nack for indicating stop reading*/

    I2C_Stop();

}

void main()

{

    char secs[10],mins[10],hours[10];

    char date[10],month[10],year[10];

    char Clock_type = 0x06;

    char AM_PM = 0x05;

    char days[7] = {‘S’,’M’,’T’,’W’,’t’,’F’,’s’};

    OSCCON=0x72;                    /*Use internal oscillator and

                                     *set frequency to 8 MHz*/

    I2C_Init();                     /*initialize I2C protocol*/

    LCD_Init();                     /*initialize LCD16x2*/   

    LCD_Clear();

    MSdelay(10);

    while(1)

    {

        RTC_Read_Clock(0);              /*gives second,minute and hour*/

        I2C_Stop();

        if(hour & (1<<Clock_type)){     /* check clock is 12hr or 24hr */

            if(hour & (1<<AM_PM)){      /* check AM or PM */

                LCD_String_xy(1,14,”PM”);

            }

            else{

                LCD_String_xy(1,14,”AM”);

            }

            hour = hour & (0x1f);

            sprintf(secs,”%x “,sec);   /*%x for reading BCD format from RTC DS1307*/

            sprintf(mins,”%x:”,min);   

            sprintf(hours,”Tim:%x:”,hour); 

            LCD_String_xy(0,0,hours);           

            LCD_String(mins);

            LCD_String(secs);

        }

        else{

            hour = hour & (0x3f);

            sprintf(secs,”%x “,sec);   /*%x for reading BCD format from RTC DS1307*/

            sprintf(mins,”%x:”,min);   

            sprintf(hours,”Tim:%x:”,hour); 

            LCD_String_xy(0,0,hours);           

            LCD_String(mins);

            LCD_String(secs);

        }

        RTC_Read_Calendar(3);        /*gives day, date, month, year*/       

        I2C_Stop();

        sprintf(date,”Cal %x-“,Date);

        sprintf(month,”%x-“,Month);

        sprintf(year,”%x “,Year);

        LCD_String_xy(2,0,date);

        LCD_String(month);

        LCD_String(year);

    /* find day */

        switch(days[Day])

        {

            case ‘S’:

                        LCD_String(“Sun”);

                        break;

            case ‘M’:

                        LCD_String(“Mon”);

                        break;               

            case ‘T’:

                        LCD_String(“Tue”);

                        break;               

            case ‘W’:  

                        LCD_String(“Wed”);

                        break;               

            case ‘t’:

                        LCD_String(“Thu”);

                        break;

            case ‘F’:

                        LCD_String(“Fri”);

                        break;               

            case ‘s’:

                        LCD_String(“Sat”);

                        break;

            default:

                        break;

        }

    }   

}

Oxuma faylını endir (qaynaq kod)

Yazma faylını endir(qaynaq kod)

Əvvəlki məqaləİşığa duyarlı sensor LDR
Növbəti məqaləRele nədir