A Simple Clock using DS1307 and PIC16F877A

Even I have posted about β€œDS1307 + PIC16F877Aβ€œ, I didn’t have chance to make a real prototype of the clock. I have done only on the simulation software.

Today, I have received a comment about that post. ah_bear followed my code and schematic on that post but the clock didn’t work. This is because the code on that post is for reading time from DS1307 so there must be some values in the DS1307 before you can read. The solution is simple. Just place setting time codes before reading codes.

This time, I have made a real prototype to confirm that it’s working. There is no setting buttons. If you want to make a real usable clock you have to implement the button interfaces (I may make one and post it here). The photo of my working prototype is featured below. Please check out my flikr at http://flickr.com/photos/punkky/ for more photos.

Simple Clock using DS1307 and PIC16F877A

The schematic of the clock is very simple. Please note that the schematic does not show power supply to the PIC16F877A and the DS1307, you have to connect them by youself. If you are new to PIC/LCD interface please seeΒ MikroC β€œHello World!” LCD exampleΒ .

Simple Clock using DS1307 and PIC16F877A schematic

The source code:

//SampleΒ codeΒ for
//DS1307Β RTCΒ InterfacingΒ withΒ PIC16F877A
//CodedΒ byΒ [email protected]
//Compiler:Β mikroCΒ 8.0.0
//http://picnote.blogspot.com
//05/01/2009
//UseΒ withΒ yourΒ ownΒ risk
unsignedΒ shortΒ read_ds1307(unsignedΒ shortΒ addressΒ );
voidΒ write_ds1307(unsignedΒ shortΒ address,unsignedΒ shortΒ w_data);
unsignedΒ shortΒ sec;
unsignedΒ shortΒ minute;
unsignedΒ shortΒ hour;
unsignedΒ shortΒ day;
unsignedΒ shortΒ date;
unsignedΒ shortΒ month;
unsignedΒ shortΒ year;
unsignedΒ shortΒ data;
charΒ time[9];
charΒ ddate[11];

unsignedΒ charΒ BCD2UpperCh(unsignedΒ charΒ bcd);
unsignedΒ charΒ BCD2LowerCh(unsignedΒ charΒ bcd);

voidΒ main(){

I2C_Init(100000);Β //DS1307Β I2CΒ isΒ runningΒ atΒ 100KHz
PORTBΒ =Β 0;
TRISBΒ =Β 0;Β //Β ConfigureΒ PORTBΒ asΒ output
TRISCΒ =Β 0xFF;
Lcd_Init(&PORTB);Β //Β InitializeΒ LCDΒ connectedΒ toΒ PORTB
Lcd_Cmd(Lcd_CLEAR);Β //Β ClearΒ display
Lcd_Cmd(Lcd_CURSOR_OFF);Β //Β TurnΒ cursorΒ off
Lcd_Out(1,Β 1,Β β€œTIME:”);
Lcd_Out(2,Β 1,Β β€œDATE:”);

//SetΒ Time
write_ds1307(0,0x80);Β //ResetΒ secondΒ toΒ 0Β sec.Β andΒ stopΒ Oscillator
write_ds1307(1,0x10);Β //writeΒ minΒ 27
write_ds1307(2,0x01);Β //writeΒ hourΒ 14
write_ds1307(3,0x02);Β //writeΒ dayΒ ofΒ weekΒ 2:Monday
write_ds1307(4,0x05);Β //Β writeΒ dateΒ 17
write_ds1307(5,0x01);Β //Β writeΒ monthΒ 6Β June
write_ds1307(6,0x09);Β //Β writeΒ yearΒ 8 –>Β 2008
write_ds1307(7,0x10);Β //SQWEΒ outputΒ atΒ 1Β Hz
write_ds1307(0,0x00);Β //ResetΒ secondΒ toΒ 0Β sec.Β andΒ startΒ Oscillator

while(1)
{
sec=read_ds1307(0);Β //Β readΒ second
minute=read_ds1307(1);Β //Β readΒ minute
hour=read_ds1307(2);Β //Β readΒ hour
day=read_ds1307(3);Β //Β readΒ day
date=read_ds1307(4);Β //Β readΒ date
month=read_ds1307(5);Β //Β readΒ month
year=read_ds1307(6);Β //Β readΒ year

time[0]Β =Β BCD2UpperCh(hour);
time[1]Β =Β BCD2LowerCh(hour);
time[2]Β =Β β€˜:’;
time[3]Β =Β BCD2UpperCh(minute);
time[4]Β =Β BCD2LowerCh(minute);
time[5]Β =Β β€˜:’;
time[6]Β =Β BCD2UpperCh(sec);
time[7]Β =Β BCD2LowerCh(sec);
time[8]Β =Β β€˜\0’;

ddate[0]Β =Β BCD2UpperCh(date);
ddate[1]Β =Β BCD2LowerCh(date);
ddate[2]Β =β€˜/’;
ddate[3]Β =Β BCD2UpperCh(month);
ddate[4]Β =Β BCD2LowerCh(month);
ddate[5]Β =β€˜/’;
ddate[6]Β =Β β€˜2’;
ddate[7]Β =Β β€˜0’;
ddate[8]Β =Β BCD2UpperCh(year);
ddate[9]Β =Β BCD2LowerCh(year);
ddate[10]Β =Β β€˜\0’;

Lcd_Out(1,6,time);
Lcd_Out(2,6,ddate);
Delay_ms(50);
}
}

unsignedΒ shortΒ read_ds1307(unsignedΒ shortΒ address)
{
I2C_Start();
I2C_Wr(0xd0);Β //addressΒ 0x68Β followedΒ byΒ directionΒ bitΒ (0Β forΒ write,Β 1Β forΒ read)Β 0x68Β followedΒ byΒ 0 –>Β 0xD0
I2C_Wr(address);
I2C_Repeated_Start();
I2C_Wr(0xd1);Β //0x68Β followedΒ byΒ 1 –>Β 0xD1
data=I2C_Rd(0);
I2C_Stop();
return(data);
}

unsignedΒ charΒ BCD2UpperCh(unsignedΒ charΒ bcd)
{
returnΒ ((bcdΒ >>Β 4)Β +Β β€˜0’);
}

unsignedΒ charΒ BCD2LowerCh(unsignedΒ charΒ bcd)
{
returnΒ ((bcdΒ &Β 0x0F)Β +Β β€˜0’);
}
voidΒ write_ds1307(unsignedΒ shortΒ address,unsignedΒ shortΒ w_data)
{
I2C_Start();Β //Β issueΒ I2CΒ startΒ signal
//addressΒ 0x68Β followedΒ byΒ directionΒ bitΒ (0Β forΒ write,Β 1Β forΒ read)Β 0x68Β followedΒ byΒ 0 –>Β 0xD0
I2C_Wr(0xD0);Β //Β sendΒ byteΒ viaΒ I2CΒ (deviceΒ addressΒ +Β W)
I2C_Wr(address);Β //Β sendΒ byteΒ (addressΒ ofΒ DS1307Β location)
I2C_Wr(w_data);Β //Β sendΒ dataΒ (dataΒ toΒ beΒ written)
I2C_Stop();Β //Β issueΒ I2CΒ stopΒ signal
}

Source : A Simple Clock using DS1307 and PIC16F877A


About The Author

Ibrar Ayyub

I am an experienced technical writer holding a Master's degree in computer science from BZU Multan, Pakistan University. With a background spanning various industries, particularly in home automation and engineering, I have honed my skills in crafting clear and concise content. Proficient in leveraging infographics and diagrams, I strive to simplify complex concepts for readers. My strength lies in thorough research and presenting information in a structured and logical format.

Follow Us:
LinkedinTwitter

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.