Saturday, June 14, 2008

Making a Digital Clock

Please check the update at === Digital Clock Updated Version ===

--- Original Version ---
As I am a WIS so I built a clock as my first microcontroller project.

The clock is controlled by PIC16F628A from the PIC book . The idea was making a digital clock with hour, minute and second display. I just wanted to learn about microcontroller so the accuracy of the clock was not an issue (yet). However, I was trying to make it the most accurate as possible by using Timer1 Module of the PIC.

Timer1 Module (TMR1 Register)

The Timer1 Module is a 16 bit counter. It counts from 0x0000 to 0xFFFF and rolls over to 0x0000. The TMR1 interrupt is generated on overflow of the TMR1 register. More information about TMR1 is available in the data sheet of the PIC. In my clock, the PIC is running with 20MHz crystal so the internal clock is 5MHz. So, the duration between each TMR1 increment is 1/5000000 = 0.2 µs . That means TMR1 will overflow every 0.2 µs x 65536 = 0.0131072 s. If I count number of overflows to 77 times, I will get 1.0061744 s which is close to 1 second but the clock will gain about 6ms every second. The result will be a fast running clock (gaining about 9 min/day) .

To get a better accuracy, I make TMR1 counts to 62500 and set prescaler of the TMR1 to 1:8 (How these 62500 and 1:8 come? I did guess and test) . From these settings, the TMR1 will overflow every 1/5000000 x 8 x 62500 = 0.1 s. Counting number of overflows to 10 will yield 1 second. Just perfect huh!

Making Timer1 counts to 62500
It's easy. Just make it starts counting at 65536-62500 = 3036 = 0x0BDC by setting: (MikroC compiler)

TMR1L = 0xDC; //Write TMR1L first to reduce timing error.
TMR1H = 0x0B;

Setting TMR0 requires 2 clock cycles but I have no idea about how many cycles required for setting TMR1L. If 2 cycles were required for setting TMR1L, I should set TMR1L to 0xDC+2 = 0xDE so my clock will run more accurate. The frequency drift in the crystal is also a source of inaccuracy of the clock. The time drift from crystal can be calculated by using data from data sheet of the crystal. Normally, it says 20ppm (Part-Per-Million). That means the crystal will produce error about 20 s. in 1,000,000 s. or about 1.7 s./day.

Making prescaler 1:8
T1CON register contains TMR1 setting information. I set prescaler to 1:8 by

T1CON = 0x31;

Driving 7-segment leds
I don't multiplex the 7-segment leds, so I have to use 6 pieces of CD4543B to drive each 7-segment from BCD output of the PIC. As an outcome of non-multiplexing leds, I can get very bright display. Nearly all of the digital clock projects I have found on the Internet used 7447 or 4511 as the BCD 7-Segment decoders. I use CD4543B because it displays 6 and 9 with tails (nicer looking). However, I have seen some of 7447 and 4511 that also display 6 and 9 with tails but the data sheets of these ICs show 6 and 9 without tails.
number 9 without tailnumber 6 without tail6 and 9 without tails... I just don't like them :)

The schematic of the clock is very simple as shown in the image below (power supply of CD4345B doesn't show).
Schematic of the 7-segment Digital Clock
The working digital clock on protoboards.
Working digital clock on protoboards
Working digital clock on protoboards Missing things
- Buttons for setting time : The time is set by hard code in the program :) . Yeah, it's a very bad idea. But, I had a plan to get the time from GPS module so I didn't bother making those buttons. Now, my GPS clock is up and running.

- Alarm function: it's not alarm clock so there is no alarm function.

- Date: umm.. my GPS clock has it.

1 comment:

arrogant.bastard said...

Nice little thing!
I did something similar in my college digital electronics class, though at the time I tried it with a much more cumbersome computing method...

Anyway, my one recommendation is to add your desired values to the timer value registers rather than directly write them. This way, whatever cycles it takes to write the two registers are also accounted for.
Also you can pretty much do whatever processing you want in between, because whatever clock cycles that are eaten between the overflow and you adding the number to the timer registers will be accounted for-- the next overflow will happen in 65535 minus X(the number you add) minus the number of clock cycles that have already occured since the overflow.