Home / How-To's / Make a Digital Clock with DS1307 and PIC 18F4520

Make a Digital Clock with DS1307 and PIC 18F4520

Digital clocks are are very commonly (cheaply) available these days. Some of them have a built in RTC to keep the time running even if the main battery fails and some of them don’t. In either case, for an offline embedded application to get a time stamp, an RTC in almost the only cheap solution solution available. Most of these clocks use a 7-Segment display to display the time and date while some use LCD displays. In this post we will see how to make a digital clock with DS1307 and PIC 18F4520.

Besides this is a project to show off your geekish skills to the world. Make a digital clock all by yourself and hang is in you room and let the presence on an Embedded Engineer be known!

What does it take to make a digital clock?


Other than time and effort you will need the following components to make a digital clock.

  • PIC Microcontroller (PIC18F4520)
  • LCD Display
  • RTC DS1307
  • CMOS Battery and its slot.


For this tutorial I assume you have a working knowledge about the I2C Protocol (Read about I2C protocol), interfacing DS1307 (Read about DS1307), and programming an LCD module (Read LCD Basics) in 8 bit or 4 bit mode.

The image above uses the LCD in 8 bit mode but any thing should work. If you do not know any of the above please read through them first and then get back to this post you can follow the links to read all the relevant posts (if it’s not very obvious).

So now you should have the following C source files and header files added to your project. If you do not have any one of these files either written by yourself or downloaded form my previous posts (links specified in the prerequisite section) the following code will not work.

You can find a link to download the entire project at the end of the post.

  • rtc.c
  • i2c.c
  • lcd.c
  • rtc.h
  • i2c.h
  • lcd.h

Now that know how to read and write data to the RTC, all that is remaining is to get the values form an RTC’s timekeeping registers and display them in the LCD display. This is how we are going to arrange the received data on the screen,

digital clock lcd

I use a 20×4 line LCD display. Here is the Display Data RAM addresses to which the data will be written to. The source code below will use this table as the reference for the display. If you are using an LCD with a different configuration, you might have to modify the DD RAM address accordingly for this code to work.

Line1 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13
Line2 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53
Line3 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27
Line4 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 60 61 62 63 64 65 66 67

For making this digital clock, you will have to acquire information on the time, date and day form the RTC. After getting them you will have to display them on the LCD display. The time and date information that is read form the RTC is not it a format that can be displayed on the LCD. So we have to do some processing before the data can be printed to the LCD. For this we will write some subroutines that will take care of the job.

Here is a function that basically calls the other subroutines that actually does all the processing of the data. So this is just a wrapper function so that we don’t have to call the individual functions separately.

We will also need two global variables ‘units’ and ‘tens’  for splitting the data into higher nibble and lower nibble (in case of the RTC its the tens digit and units digit of the data)

Function to display the Time

This function is used to display the time in the LCD display. It takes the time value as a parameter and converts them into printable data and puts them in their corresponding positions in the display. Again this is a code for the 20×4 LCD. If you have some other module modify the DD RAM address.
Note: the variable units and tens are global variable and are updated every time the decode() is called.

Function to display the Date, Month and Year

The date, month and year values read from the RTC are provided as parameters for this function. Here the numerical (decimal) data is translated to ASCII values and are written to the LCD module at appropriate character positions.
Note: the variable units and tens are global variable and are updated every time the decode() is called.

Function to display the Day

The day is represented as a number (with 0 representing Sunday) in the RTC time keeping registers. A switch case was the most common way to decode it into the actual day and print it on the LCD display

Asides these function we will need a function to decode the data into the units and tens place. This function also updates the values of the global variables units and tens.

Now all that you have to do is to collect all these functions and put them in a file called clock.c and create a clock.h to be included in your main program.

Download Related Files

Here are the C Files, the HEX file and the Mplab X project folder for the above tutorial.

I hope this post was to an extent helpful in the process of making a digital clock. If you are facing any problems leave a comment below and we will sort it out.

About Siddharth

Siddharth is a Firmware Engineer, techie, and a movie-buff. His interests include, Programming, Embedded Systems, Linux, Robotics, CV, Carpentry and a lot more. At times, you could see some of his sunday projects converge on release quality. You get to know him on the following social channels.

Check Also

PIC Pin Diagram: A printable copy for quick reference

Today when I was hooking up my PIC micro on to a breadboard for a …

  • Nice ! By the way, LCD_data and LCD_cmd I think I am familiar with this when dealing with 8085 uP. What is the fucntion for the LCD_data and LCD_cmd ? I mean I can’t see the function in your code. Thanks

  • Can you make LED clock with date and time?

    • Hi Murugan, What exactly do you mean by a LED clock? The one with the dot matrix LED display? It’s certainly possible.

  • Samuel

    Hi, could you kindly help me out with this?

    1) may i know how is the schematic for this setup like? could you kindly send it to my email?
    2) I am working with the PIC18F4520 chip, DS1307 chip as well as a 16×2 LCD C1602A-V1.2. How am I to go about to use the related codes as stated in this website to work?
    3) I am currently using MPLAB version 7.4, is there a difference if i were to use the codes?

    • Hi Samuel,

      1) There are not much circuitry involved. That is the reason I did not add a schematic. Just plug the DS1307 to the I2C bus and the LCD to the digital IO. See the datasheet for the LED to know the pin out and application circuit.
      2) Perfect, you seem to have the same hardware that I have used.
      3) There is no difference in the the code. You can use the same code to build your project. I have used the C18 compiler to compile the code. Download and install the compiler. Create a new project and put above source files in the project folder and include them into the project. Then build it to get the HEX file.

      Let us know of your progress.
      All the best!

  • Samuel

    Hi Siddharth,

    1) I have tried looking at your LCD post but I am still quite confused as to what pins from PIC18f4520 are used and which of these are connected to the LCD or any buttons used for the configuration of the date/time/day. I was wondering if you could email me a schematic pertaining to the exact connections?

    2) I am not using the C18 compiler. Instead, my PIC18F4520 board uses a debugger program (ds30 Loader GUI Free edition) to flash the program into the chip where I select a hex file to flash. Will the various hex files you provided on your site work without the C18 compiler?

    3) Lastly, I do not necessarily have to use MPLABX, right? Will MPLAB 7.4 free edition be able to do all these?


    • Hi Samuel,

      1) I will make a schematic and update the post soon.
      2) The HEX file is independent of any compiler. It can be used directly in a PIC 18F4520 with the correct connections.
      3) No you can use any IDE you prefer. But read why you should move to the new MPLAB X IDE

      Cheers, Siddharth.

  • utpal

    hi ,
    i am trying to your porgram comple on hi-tech but its giving me lot of error

    • Hi Utpal, the code I’ve given was tested in C18 compiler. At that time I was was using C18 then I moved on to HiTech C and currently xc8. I keep shifting compliers for two reasons,

      1. It helps me improve my adaptability to new environments and
      2. I like to use the most recent software.

      Please download c18 and compile the code or migrate the code from c18 to HiTech C. Read my article Migrating to HI-TECH C Compiler from the Microchip C18 Compiler to get an idea of the changes you need to make.

      Its not that hard. Good luck!!

  • harsh

    Hi Siddharth,
    I have been trying to make the digital clock but I can not seem to get any result. Would you mind uploading a schematic or emailing it to me so I can see where the problem may be. Thanks!

    • Sure Harsh, I will update this post with a schematic as soon as I get some time.

  • Suman

    HI Siddharth,
    I was looking at your I2C code, I can see in start / restart /write etc function the following line is added


    in datasheet of 18F4520 it is written that SSPIF to be cleared in software. SO how this register is going to be cleared or set automatically?

    • Hi suman, the SSP interrupt flag is set by the hardware in when the I2C communication is over and has to be cleared by software. So the line while(PIR1bits.SSPIF==0); waits for the flag to be set. Then before initiating a new transfer you should have noticed that I have cleared the flag with PIR1bits.SSPIF=0. I hope this answers your questions!


  • Ramesh

    Thanks siddharth,

    I am facing a problem to make a header file in mplab x
    please guide me to make a header file in mplab X.

    Thanks once again.

    • Ramesh, there is no difference in creating a header file in mplab x. You have to create a new file and save it with .h extension and save the contents in that file.

  • umar

    please share if you
    have done same for PIC 24.
    waiting for your reply

    • Hi Umar, I haven’t worked with PIC 24 as of now. I don’t see why its difficult for you to port this code to work with PIC24 compiler.. as far as I know microchip c code can be ported from one family to another without a lot of changes.

  • Ankush

    Hello siddharth,
    my clock is not set using set_time function and code is not working please help me.what is disp_frame(); function it is not present.please help me…

    • The disp_frame() function is used to print the static data on to the LCD. It is the first function in rtc.c file. Please check you mail for my reply to your questions.

      • ANKUSH

        Thanks…now its working fine and i learnt from my mistakes. Siddharth i2c i got now.now i’m working on writing and reading the byte from eeprom at25010a with spi communication using pic18f4520. Can you guide me.

        • I am glad you where able to solve the problem. Please specify how I can help you with the EEPROM.

        • Rajat Dumbhare

          hey sidharth i’m facing problem in disp_frame();
          pls help me out in ti problem. and data is also not displayind on lcd what to do

      • Rajat Dumbhare

        I’m also facing same problem . what to do ? plz send solution at rajatdumbhare@gmail.com

  • raj

    Hai , rtc ds1307 interface to pic18f97j60 reads the date and time in lcd display when power off to on the lcd display shows date: 1515:1515:1515
    time: 1515/1515/1515
    and sometimes stops the rtc… how to solve…

  • Anand Gupta

    dear sidharth ji
    i am very much new to these projects,i had seen you project its really good,i didn’t found any switch to set the system and also no any schematic found.you are requested to please send me schematic and switches details at my email id,i will be very thankful to you.

    Anand gupta

  • mothafar

    how can i write this code in xc8 , thanks in advance

    • There is not much to change I have not done anything compiler specific. You should change the header file to #include instead of the #include.

      Other wise it should just compile. Let me know if you have any problem.

  • Kenny Heller

    Hey siddharth,

    quick question. can i just upload the .hex file and run the program? i am using a mac and am having trouble uploading the project. Thanks!


    • Hey, What problems are you facing? Try creating a new project and adding the source files alone form the downloaded project.

      But you could also burn the hex file to see the output. You should use the same pins that I have used though.

  • ravi

    How to import this code in ic

  • Yosry Khalef

    where Circuit Diagram i don’t see it

  • Sathish Baskaran

    Dear siddarth, i am facing write collision problem (WCOL bit) in my pic18f458 with ds1307….

  • Nelida Payton5

    Thoughtful article , For what it’s worth , if anyone requires a a form , my business encountered a blank form here http://goo.gl/xgTzlJ

Keep in touch with the current trends!
Did you like this article? Sign up and get our latest posts delivered to your inbox!
  We hate spam and never share your details.