Friday, February 20, 2015

Interfacing DS1307 Real Time Clock with PIC Microcontroller

Interface DS1307 Real Time Clock with PIC16F877A Microcontroller

Make Your Own Digital Clock

We have seen how to write and read data to/from the DS1307 real time clock (RTC) on these two topics:
Write Data to DS1307 Real Time Clock
Now, we are going to see the circuit and software that makes a full project of a digital real time clock with full adjustment of time and calendar.
The microcontroller used is Microchip PIC16F877A runs at 12MHz as shown in the following circuit schematic. There are two push buttons, one used to select which parameter we are going to adjust (minutes, hours, date, month, and year) and it is connected to RB0, and the other push button is connected to RB1 which used to adjust the selected parameter.

pic16f877a ds1307 mikroc

I took this picture from my home made application:

pic16f877a ds1307 real time clock mikroc

Interfacing DS1307 Real Time Clock with PIC16F877A mikoC Code:
This is the project code it is working very well with no problem:

//DS1307 Real Time Clock with PIC16F877A
//Used microcontroller: PIC16F877A @ 12MHz
//Written by: BENCHEROUDA Okba
//http://www.elecnote.blogspot.com
//electronnote@gmail.com
//Use at your own risk

   // LCD module connections
sbit LCD_RS at RD0_bit;
sbit LCD_EN at RD1_bit;
sbit LCD_D4 at RD2_bit;
sbit LCD_D5 at RD3_bit;
sbit LCD_D6 at RD4_bit;
sbit LCD_D7 at RD5_bit;

sbit LCD_RS_Direction at TRISD0_bit;
sbit LCD_EN_Direction at TRISD1_bit;
sbit LCD_D4_Direction at TRISD2_bit;
sbit LCD_D5_Direction at TRISD3_bit;
sbit LCD_D6_Direction at TRISD4_bit;
sbit LCD_D7_Direction at TRISD5_bit;
  // End LCD module connections
 unsigned char *text, second, second10, minute, minute10,
               hour, hour10, date, date10, month, month10,
               year, year10, day, i = 0;

 void display(){
  //Split data into tow parts
  second10  =  (second & 0x70) >> 4;
  second = second & 0x0F;
  minute10  =  (minute & 0x70) >> 4;
  minute = minute & 0x0F;
  hour10  =  (hour & 0x30) >> 4;
  hour = hour & 0x0F;
  date10  =  (date & 0x30) >> 4;
  date = date & 0x0F;
  month10  =  (month & 0x10) >> 4;
  month = month & 0x0F;
  year10  =  (year & 0xF0) >> 4;
  year = year & 0x0F;
  //Display Time
  Lcd_Chr(1, 13, second + 48);
  Lcd_Chr(1, 12, second10 + 48);
  Lcd_Chr(1, 10, minute + 48);
  Lcd_Chr(1, 9, minute10 + 48);
  Lcd_Chr(1, 7, hour + 48);
  Lcd_Chr(1, 6, hour10 + 48);
  //Display calendar
  Lcd_Chr(2, 7, date + 48);
  Lcd_Chr(2, 6, date10 + 48);
  Lcd_Chr(2, 10, month + 48);
  Lcd_Chr(2, 9, month10 + 48);
  Lcd_Chr(2, 15, year + 48);
  Lcd_Chr(2, 14, year10 + 48);
  }
 void write_value(char address, char data_){
   I2C1_Start();
   I2C1_Wr(0xD0);
   I2C1_Wr(address);
   I2C1_Wr(data_);
   I2C1_Stop();     }
 void main() {
 TRISB = 3;
 Lcd_Init();                // Initialize LCD
 Lcd_Cmd(_LCD_CLEAR);       // Clear LCD display
 Lcd_Cmd(_LCD_CURSOR_OFF);  // Turn cursor off
 I2C1_Init(100000);         // initialize I2C at 100KHz
 return_:
 text = "TIME:  :  :" ;
 Lcd_Out(1, 1, text);
 text = "DATE:  /  /20" ;
 Lcd_Out(2, 1, text);
 write_value(0, 0);   //Reset seconds and start oscillator
 while(1){
 if(i == 1){
 Lcd_Cmd(_LCD_CLEAR);
 text = "Adjust Minute:";
 Lcd_Out(1, 2, text);
 minute = minute + minute10 * 10;
 while(1){
 if (Button(&PORTB, 0, 100, 0)) i++;
 if(i!=1){
 minute = ((minute/10) << 4) + (minute % 10);
 write_value( 1 , minute);
 goto return_;}
 if (Button(&PORTB, 1, 100, 0)) minute++;
 if (minute > 59) minute = 0;
 Lcd_Chr(2, 8, (minute/10) + 48);
 Lcd_Chr(2, 9, (minute % 10) + 48);}
    }
 if(i == 2){ Lcd_Cmd(_LCD_CLEAR);
 text = "Adjust Hour:";
 Lcd_Out(1, 2, text);
 hour = hour + hour10 * 10;
 while(1){
 if (Button(&PORTB, 0, 100, 0)) i++;
 if(i!=2){
 hour = ((hour/10) << 4) + (hour % 10);
 write_value( 2 , hour);
 goto return_;}
 if (Button(&PORTB, 1, 100, 0)) hour++;
 if (hour > 23) hour = 0;
 Lcd_Chr(2, 8, (hour/10) + 48);
 Lcd_Chr(2, 9, (hour % 10) + 48);}
    }
 if(i == 3){ Lcd_Cmd(_LCD_CLEAR);
 text = "Adjust Date:";
 Lcd_Out(1, 2, text);
 date = date + date10 * 10;
 while(1){
 if (Button(&PORTB, 0, 100, 0)) i++;
 if(i!=3){
 date = ((date/10) << 4) + (date % 10);
 write_value( 4 , date);
 goto return_;}
 if (Button(&PORTB, 1, 100, 0)) date++;
 if (date > 31) date = 1;
 Lcd_Chr(2, 8, (date/10) + 48);
 Lcd_Chr(2, 9, (date % 10) + 48);}
    }
 if(i == 4){ Lcd_Cmd(_LCD_CLEAR);
 text = "Adjust Month:";
 Lcd_Out(1, 2, text);
 month = month + month10 * 10;
 while(1){
 if (Button(&PORTB, 0, 100, 0)) i++;
 if(i!=4){
 month = ((month/10) << 4) + (month % 10);
 write_value( 5 , month);
 goto return_;}
 if (Button(&PORTB, 1, 100, 0)) month++;
 if (month > 12) month = 1;
 Lcd_Chr(2, 8, (month/10) + 48);
 Lcd_Chr(2, 9, (month % 10) + 48);}
    }
 if(i == 5){ Lcd_Cmd(_LCD_CLEAR);
 text = "Adjust Year:";
 Lcd_Out(1, 2, text);
 year = year + year10 * 10;
 while(1){
 if (Button(&PORTB, 0, 100, 0)) {i++;
 if (i > 5) i = 0;}
 if(i!=5){
 year = ((year/10) << 4) + (year % 10);
 write_value( 6 , year);
 goto return_;}
 if (Button(&PORTB, 1, 100, 0)) year++;
 if (year > 99) year = 0;
 Lcd_Chr(2, 7, 2 + 48);
 Lcd_Chr(2, 8, 0 + 48);
 Lcd_Chr(2, 9, (year/10) + 48);
 Lcd_Chr(2, 10, (year % 10) + 48);}
    }
 if (Button(&PORTB, 0, 100, 0)) i++;
 I2C1_Start();
  I2C1_Wr(0xD0);
  I2C1_Wr(0);
  I2C1_Repeated_Start();
  I2C1_Wr(0xD1);
  second =I2C1_Rd(1);
  minute =I2C1_Rd(1);
  hour =I2C1_Rd(1);
  day =I2C1_Rd(1);
  date =I2C1_Rd(1);
  month =I2C1_Rd(1);
  year =I2C1_Rd(0);
  I2C1_Stop();
  display();
}
}

Interfacing DS1307 Real Time Clock with PIC16F877A video:


You can make some modification for example you can add an Alarm.
Enjoy with your digital clock!