Monday, February 16, 2015

Read Data From DS1307 Real Time Clock

Interfacing DS1307 Real Time Clock with PIC16F877A Microcontroller
Read Data From DS1307 Real Time Clock

Related Topic:

The topic above shows how to write time and calender to DS1307 RTC. In this topic we are going to see how to write/read data to/from the DS1307 RTC.
The read  values will be displayed on 1602 LCD display.
To read data from ds1307 you have to do the following:
1 - Start I2C protocol,
2 - Send the DS1307 address which is in binary 11010000,
3 - Send register address,
3 - I2C repeated start,
4 - Send 11010001 to tell ds1307 that we want to read data,
5 - Stop the I2C protocol.
Note that the values come from the ds1307 are in BCD format, so in our program we split the bcd value into tow values, for example if we have minute 45, the read value from ds1307 is in binary 01000101, then we display 0100 alone and 0101 alone.
Read data from DS1307 RTC circuit:
The schematic of the circuit is shown below:
Read data from DS1307 RTC circuit

read data from ds1307 rtc mikroc

The simulation will not work properly if we do not add the I2C Debugger.
Read data from DS1307 RTC mikroC code:

//DS1307 Real Time Clock Write & Read Data
//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 short sec,sec10,min1,min10,hour,hour10,
                day,date,date10,month,month10,year,year10;
 char *text, mytext[4];

 void main() {
 Lcd_Init();                // Initialize LCD
 Lcd_Cmd(_LCD_CLEAR);       // Clear LCD display
 Lcd_Cmd(_LCD_CURSOR_OFF);  // Turn cursor off
 text = "TIME:  :  :" ;
 Lcd_Out(1, 1, text);
 text = "DATE:  /  /20" ;
 Lcd_Out(2, 1, text);
 I2C1_Init(100000);// initialize I2C protocol

 I2C1_Init(100000); // initialize I2C protocol at 100KHz
 I2C1_Start();      // start I2C signal
 I2C1_Wr(0xD0);   // address DS1307
 I2C1_Wr(0);     // start from word at address (REG0)
 I2C1_Wr(0x80);  // write $80 to REG0. (pause counter + 0 sec)
 I2C1_Wr(0x20);  // write 20 to minutes word to (REG1)
 I2C1_Wr(0x10);  // write 10 to hours word (24-hours mode)(REG2)
 I2C1_Wr(0x02);  // write 2 - Monday (REG3)
 I2C1_Wr(0x16);  // write 16 to date word (REG4)
 I2C1_Wr(0x02);  // write 2 (February) to month word (REG5)
 I2C1_Wr(0x15);  // write 15 to year word (REG6)
 I2C1_Stop();    // issue stop signal

 I2C1_Start();   // issue start signal
 I2C1_Wr(0xD0);  // address DS1307
 I2C1_Wr(0);     // start from word at address 0
 I2C1_Wr(0);     // write 0 to REG0 (enable counting + 0 sec)
 I2C1_Stop();    // stop I2C signal

 while(1){
 I2C1_Start();
  I2C1_Wr(0xD0);
  I2C1_Wr(0);
  I2C1_Repeated_Start();
  I2C1_Wr(0xD1);
  sec =I2C1_Rd(1);
  min1 =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();
  sec10  =  (sec & 0x70) >> 4;
  sec = sec & 0x0F;
  min10  =  (min1 & 0x70) >> 4;
  min1 = min1 & 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
  //Seconds
  ByteToStr(sec, mytext);
  Lcd_Out(1,13,Ltrim(mytext));
  ByteToStr(sec10, mytext);
  Lcd_Out(1,12,Ltrim(mytext));
   //Minutes
  ByteToStr(min1, mytext);
  Lcd_Out(1,10,Ltrim(mytext));
  ByteToStr(min10, mytext);
  Lcd_Out(1,9,Ltrim(mytext));
  //Hours
  ByteToStr(hour, mytext);
  Lcd_Out(1,7,Ltrim(mytext));
  ByteToStr(hour10, mytext);
  Lcd_Out(1,6,Ltrim(mytext));
  //Display Calender
  //Date
  ByteToStr(date, mytext);
  Lcd_Out(2,7,Ltrim(mytext));
  ByteToStr(date10, mytext);
  Lcd_Out(2,6,Ltrim(mytext));
  //Month
  ByteToStr(month, mytext);
  Lcd_Out(2,10,Ltrim(mytext));
  ByteToStr(month10, mytext);
  Lcd_Out(2,9,Ltrim(mytext));
  //Year
  ByteToStr(year, mytext);
  Lcd_Out(2,15,Ltrim(mytext));
  ByteToStr(year10, mytext);
  Lcd_Out(2,14,Ltrim(mytext));

 }
}


This is another code which uses less memory:

   // 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 short second,second10,minute,minute10,hour,hour10,
                day,date,date10,month,month10,year,year10;
 char *text;

 void main() {
 Lcd_Init();                // Initialize LCD
 Lcd_Cmd(_LCD_CLEAR);       // Clear LCD display
 Lcd_Cmd(_LCD_CURSOR_OFF);  // Turn cursor off
 text = "TIME:  :  :" ;
 Lcd_Out(1, 1, text);
 text = "DATE:  /  /20" ;
 Lcd_Out(2, 1, text);
 I2C1_Init(100000); // initialize I2C protocol at 100KHz
 I2C1_Start();      // start I2C signal
 I2C1_Wr(0xD0);   // address DS1307
 I2C1_Wr(0);     // start from word at address (REG0)
 I2C1_Wr(0x80);  // write $80 to REG0. (pause counter + 0 sec)
 I2C1_Wr(0x20);  // write 20 to minutes word to (REG1)
 I2C1_Wr(0x10);  // write 10 to hours word (24-hours mode)(REG2)
 I2C1_Wr(0x02);  // write 2 - Monday (REG3)
 I2C1_Wr(0x16);  // write 16 to date word (REG4)
 I2C1_Wr(0x02);  // write 2 (February) to month word (REG5)
 I2C1_Wr(0x15);  // write 15 to year word (REG6)
 I2C1_Stop();    // issue stop signal

 I2C1_Start();   // issue start signal
 I2C1_Wr(0xD0);  // address DS1307
 I2C1_Wr(0);     // start from word at address 0
 I2C1_Wr(0);     // write 0 to REG0 (enable counting + 0 sec)
 I2C1_Stop();    // stop I2C signal
 while(1){
 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();
  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);
 }
}