Monday, January 5, 2009

A Simple Clock using DS1307 + 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.
A 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 .
Schematic of a simple clock using DS1307 and PIC16F877A

The source code:
//Sample code for
//DS1307 RTC Interfacing with PIC16F877A
//Coded by punkky@gmail.com
//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(11"TIME:");
Lcd_Out(21"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
}

65 comments:

Blue Tear's said...

Great post. But i need help to increase buttons to set time and date. Can you help me with this.

punkky said...

I'm working on the complete clock. I will post the whole things. Please come back later.

Blue Tear's said...

Can you post your new code for the buttons. Thanks

oxoxo said...

thanks for sharing the code.
but i do not understand the datasheet for DS1307 on how to set the time that i want..for example, i want to set the time for 24-hr clock at 0800 or 1900(7p.m). i don get to understand how u write 0x01 as 14 hour (write_ds1307(2,0x01); //write hour 14) and other timing as well.
do advise this asap, a million thanks~!

PIC said...

good program

trungnt said...

Based on your code, I have written code for RTC using buttons to set time and 12 Led 7-Seg to show time (year-month-date-hour-min-sec). Thanks!!!

Chuck said...

Can you help me? This is my first attempt to program a chip.
What to make a red clock for car.
I've been trying to program a pic chip 16f628A for the last month.
For some reason all I get is ERROR hardware not found on COM.
I have down loaded picaxe programming editor.
I purchased the pic programmer.
I have a USB to serial cable.
What is wrong?????

Chuck said...

Me again. You can contact me at sbcm07@hotmail.com

Ranier said...

hi everyone, help me to make add-ons to this circuit.. i will make an alarm clock that will based to the digital clock made... this is my first time to program to a chip. pls help me... here's my email address... ranier21ph@yahoo.com

kenny90 said...

may i know wat type of crystal r using?

yayah said...

may i know which software did you used to simulate the circuit and the coding.tq

Minos said...

I've made the schematic, but the simul inisis doesn't work. time is 00:00:00, and date 00:00:2000. can u help me pls?

malik said...

I've made the schematic, but the simul inisis doesn't work. time is 00:00:00, and date 00:00:2000. can u help me pls?

malik said...

please please help for this issue


I've made the schematic, but the simul inisis doesn't work. time is 00:00:00, and date 00:00:2000. can u help me pls?

malik said...

I've made the schematic, but the simul inisis doesn't work. time is 00:00:00, and date 00:00:2000. can u help me pls?

testa said...

hi, may i know how to add the alarm function to this project code? thank

testa said...
This comment has been removed by the author.
malik said...

i have implemented it on hardware it works fyn.

On proteus it works only with i2c dbugger.

Do not waste ur tym by simulating it on Proteus..
just direct implement it.
thnx

GadgetCheap Shop said...

hello..
nice project..
i want to try this project, but i got some error when build at microC PRO..
so..
any problem at there..?
here's my email address... sk8terboy_amie@yahoo.com.my

malik said...

@hilmi
what is error?
give me details

GadgetCheap Shop said...
This comment has been removed by the author.
GadgetCheap Shop said...
This comment has been removed by the author.
GadgetCheap Shop said...

@malik.. this all the error.. please help me t build this source code.. i use microC PRO.. thank you
->27 324 Undeclared identifier 'I2C_Init' in expression delete.c
->31 313 Too many actual parameters delete.c
->32 324 Undeclared identifier 'Lcd_CLEAR' in expression delete.c
->33 324 Undeclared identifier 'Lcd_CURSOR_OFF' in expression delete.c
->88 324 Undeclared identifier 'I2C_Start' in expression delete.c
->89 324 Undeclared identifier 'I2C_Wr' in expression delete.c
->90 324 Undeclared identifier 'I2C_Wr' in expression delete.c
->91 324 Undeclared identifier 'I2C_Repeated_Start' in expression delete.c
->92 324 Undeclared identifier 'I2C_Wr' in expression delete.c
->93 315 Invalid expression delete.c
->92 401 ; expected, but 'data' found delete.c
->93 423 '}' expected ';' found delete.c
->96 1503 Result is not defined in function: 'read_ds1307' delete.c
->96 312 Internal error '' delete.c
->0 102 Finished (with errors): 08 Oct 2010, 05:14:12 delete.mcppi

malik said...

@hilmi
commands format in MickroC basic and pro is not not same.
go to help in MickroC pro and see proper formats.
Its better to use MickroC for PIC microcontrollers v8.1.
i personally used above version and got satisfactory results

GadgetCheap Shop said...

@malik
thank you very much..
this solution is work!
:)
so, how can i get the schematic with the button to setup the date and time..? do you have that project..?

malik said...

@hilmi
wel come

no i have not sch project including button to set the time

Actually i used DS1307 in big project where just one time time and date is being set by microcontroller commands and then RTC works for whole life..

but on internet buttons project for set and reset time is available
search for it

thnx

GadgetCheap Shop said...

@malik
i already build this circuit with that source code.
but i got some problem at circuit after rebuild for 3 times to get confirmation about this circuit..
1st, my LCD just show only one line of two..
thats mean just at upper line of LCD have show the 16 black square and at the second line, nothing display..
2nd, if this CLOCK successful, the LED will be blinking..?
thank you..
:)

malik said...

chk ur circuit's connection
place the crystal for RTC very near to RTC.
adjust the crystal by hand so that display will be shown

also chk ur programing software to burn in ucontroller.such as configration bits

Anderson said...

Please, i need your help, like malik, i've made the schematic and the program but in the simulation appears Hour: 00:00:00 and Date: 00/00/2000

did someone fix that?

THANKS

malik said...

i have implemented it on hardware it works fyn.

On proteus it works only with i2c dbugger.
i2c debugger is present wt the place where oscilloscope is present in proteus.

Do not waste ur tym by simulating it on Proteus..
just direct implement it.
thnx

malik said...

Image for Proteus simulation:

http://www.ziddu.com/download/12265522/RTC.png.html

malik said...

@anderson
@all

code and schematic is given below:

http://www.ziddu.com/download/12265583/finalRTC.rar.html

Pakistan Zindabad

BeNg HuA said...

hi...
can u write the sample of codes start from 0 until 9 for me to display on the LCD?

malik said...

for(i=0;i<=9;i++)
{
Lcd_Show(i);
delay(200);
{

PA system and canopy said...

hi everyone, help me to make add-ons to this circuit.. i will make an alarm clock that will based to the digital clock made... this is my first time to program to a chip. pls help me... here's my email address...
please help me><....next week i need to prepare my presention..i need fast...please><..email me..meel_mjii91@yahoo.com

malik said...

Dear this code works fine
copy this code compile it and burn it in chip
it works fine on hardware.i have used this.thnx

Hasan said...

just use 10khz for i2c it worked for me

Antonio said...

thank you for this post I used this code and worked fine in my pic16f877a and ds1307

best regards from Brazil

par said...

where is I2C_Rd function?????

malik said...

@par
i2c_rd() is built in function in mickroC compiler.
If u want to search this in above code then do: Ctrl+f and search ur required function.

Mith said...

Hai, I would like to do a DIGITAL TIMETABLE DISPLAY SYSTEM IN CLASSROOM with an alert at the end of each periods. I selected pic 16f877a ic for this purpose. But I don't know the proper use of embedded c language. So, could u please give the codes... I did't have any simple tutorial from internet to study the embedded c. I know the standard c language, but I am confused with some embedded c programs that i had seen on internet, so I need to study from the basics of embedded c. could u please give any suggestion.....

MPElectronique said...

Hello! Nice project! :)

but i don't see any push-button to set the minutes etc..

where are they?

thank you so much! :)
marC:)

MPElectronique said...

Hello! Nice project! :)

but i don't see any push-button to set the minutes etc..

where are they?

thank you so much! :)
marC:)

MPElectronique said...

Hello! Nice project! :)

but i don't see any push-button to set the minutes etc..

where are they?

thank you so much! :)
marC:)

malik said...

sorry dear time set option is not present in above mine project.time is set only once in c code and then can be changed or set by again in c code.one can add time set option in this project.thnx

SANJEEV said...

very nice project...and thanks for posting the code...it will be nice if someone here add push buttons to set time....and share the code.. once again thanks to punkky....

nasser said...

hey....such a great post
i've been trying to do this clock but the only compiler that i know how to use is the pic c compiler so can u help me and send me the source code in c....... thanks
keep it up

Unknown said...
This comment has been removed by the author.
Unknown said...

Hye..Thankz for the code...it's help me a lot to do a project...hehe3,,but i have changed some code but it's works in hardware and not working in proteus i don't know why...ahakz!!

Software: Mikro C Pro for PIC v5.6.1

Here the Code:
// LCD module connections

sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D4 at RD4_bit;
sbit LCD_D5 at RD5_bit;
sbit LCD_D6 at RD6_bit;
sbit LCD_D7 at RD7_bit;

sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISD4_bit;
sbit LCD_D5_Direction at TRISD5_bit;
sbit LCD_D6_Direction at TRISD6_bit;
sbit LCD_D7_Direction at TRISD7_bit;


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 take;
char time[9];
char ddate[11];

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

void main(){

I2C1_Init(32768); //DS1307 I2C is running at 100KHz
PORTB = 0;
TRISB = 0; // Configure PORTB as output
TRISC = 0xFF;
Lcd_Init(); // 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 //09
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)
{
I2C1_Start();
I2C1_Wr(0xd0); //address 0x68 followed by direction bit (0 for write, 1 for read) 0x68 followed by 0 --> 0xD0
I2C1_Wr(address);
I2C1_Repeated_Start();
I2C1_Wr(0xd1); //0x68 followed by 1 --> 0xD1
take = I2C1_Rd(0);
I2C1_Stop();
return(take);
}

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)
{
I2C1_Start(); // issue I2C start signal
//address 0x68 followed by direction bit (0 for write, 1 for read) 0x68 followed by 0 --> 0xD0
I2C1_Wr(0xD0); // send byte via I2C (device address + W)
I2C1_Wr(address); // send byte (address of DS1307 location)
I2C1_Wr(w_data); // send data (data to be written)
I2C1_Stop(); // issue I2C stop signal
}

Unknown said...

My code works on Proteus fine even without I2C debug... but cant get it working on Hardware.
My controller is fine programmer works good.
All circuit connection are Ok.
But cant get it running!

Unknown said...

if somebody can upload picture of breadboard or PCB, it might be helpful. Thanks

Sebas said...

to work in ISIS put the I2C DEBUGGER and it's work well in the schematic

nevchits said...

Thank you very Much!!!

Unknown said...

Hi Im using your code that posted form this thread. But when simulating the program, the time display on LCD was "January 01,2000" not the set date that was given on the code. Please nee a help

Unknown said...

well, my MPLAB hitech compiler doesn't seem to recognise any i2c functions like i2c_start().... what can i do about it?please, do shed light on me!!!

Unknown said...

my mplab hitech compiler doesn't seem to recognise any of the i2c functions like i2c_start(), i2c_init(),...
how can i solve this problem?please shed some light on this...

Unknown said...

pls ,who can tell me how to implement the i2c debugger????

Udaya Ruwan said...

Good post. can help us to set the time with input buttons please.

Unknown said...

Hy, i made the schematic in Proteus but the circuit count 1,2 second, and the display Value disappear(nothing shown) the value of second is reset.
What is happen ?

uthmanzubair@gmail.com said...

please who can send me the hex file bcos i try runing the program using pic c compiler i have 1 error "uthmanzubair@gmail.com"

Unknown said...

hello,i'am a new student in studying engineering of embedded system..
for these year, i and my partner want to build a fyp..
your project like a simple way for we to build it..
but before we build,we must know the source code for programming the hardware..
but i become confiused,where the true source code that must used in this project..
can you help my problem?

Ummey Rezwana said...
This comment has been removed by the author.
Ummey Rezwana said...

Great Content.I have appreciate with getting lot of good and reliable information with your post.......
Thanks for sharing such kind of nice and wonderful collection......again, beautiful :) I love reading your posts. They make me happy . . I know something information, to know you can click here
bundy clocks
electronic bundy clocks
bundy cards

Unknown said...

good content.how can i interface a AC BELL to this circuit.pls give me any one program using mikroc c programming

babagyi-test.blogspot.com said...

hi
plz help me
i want the code for digital clock with hour,min,sec
using pic16f877a+ds1307ic+7segment display in mikroC
i hope you will help me
plz help me as soon as possible
thank full