I have added time setting feature to make it to be a usable clock. The updated version is shown below:
More features will be added in the future.
There is no fast or slow time setting as in normal/simple digital clocks. In this clock, each digit of the clock display can be set one by one via 2 setting buttons.
Features
1. Bright Led 7-Segment display without Multiplexing
2. Display: Hour, Minute, Second
3. Set time via 2 buttons
4. Set time Digit by Digit
5. Use internal oscillator of PIC16F627a or PIC16F628
6. Use 32.768KHz crystal for better clock accuracy
Setting Time:
1. The clock shows 12:34:56 when power the clock on. The first digit of hour (it's number 1 in this case) will be blinking to notify that the time is not correct and need to be set.
2. Press SET button to count up the digit.
3. Press MODE button when the digit is the correct time. The next digit will be blinking.
4. Repeat step 2 and 3 for setting minute and second.
5. Make sure that pressing MODE button for setting the second digit of second at the correct time.
Shecmatic of the Digital Clock
Example of a PCB design of the Digital Clock
The firmware ( source code in C ) written in MikroC
//6 digit clock
//Using timer1 16bit counter interrupt
// PIC16F627A or PIC16F628
// Internal Clock 4MHz
// PUNKKY@gmail.com
#define MODE PORTB.F4
#define SET PORTB.F5
#define Sec_port_l PORTA.F6
#define Sec_port_h PORTA.F4
#define Min_port_l PORTA.F3
#define Min_port_h PORTA.F2
#define Hr_port_l PORTA.F1
#define Hr_port_h PORTA.F0
#define Blink PORTA.F7
#define HTMR1 0x80
#define LTMR1 0x00
typedef unsigned short uns8;
uns8 i;
uns8 hr_h;
uns8 hr_l;
uns8 min_h;
uns8 min_l;
uns8 sec_h;
uns8 sec_l;
uns8 tick;
uns8 myTimer;
uns8 setting_time;
void setup ();
void set_time ();
void show_time ();
void display (uns8 digit);
void blink_digit (uns8 digit);
void check_bt ();
//void check_bt(); //chech button
void interrupt ()
{
PIR1.TMR1IF = 0;
// clears TMR1IF
TMR1H = HTMR1;
tick = 1;
Blink = 1;
sec_l ++;
if(sec_l>9){
sec_l = 0;
sec_h++;
}
if(sec_h>5){
sec_h=0;
min_l++;
}
if(min_l>9){
min_l = 0;
min_h++;
}
if(min_h>5){
min_h = 0;
hr_l++;
}
if(hr_l>9){
hr_l = 0;
hr_h++;
}
if(hr_h >2){
hr_h = 0;
}
if(hr_h >=2 && hr_l>3){
hr_h = 0;
hr_l = 0;
}
}
void main ()
{
setup ();
//Set time
hr_h = 1;
hr_l = 2;
min_h = 3;
min_l = 4;
sec_h = 5;
sec_l = 6;
show_time ();
setting_time = 1;
set_time();
while (1)
{
//blink_digit();
if (tick)
{
tick = 0;
show_time ();
Delay_ms (300);
Blink = 0;
}
check_bt ();
}
}
void setup ()
{
tick = 0;
//Digital output on PORTA
CMCON = 0x07;
//Input buttons + external clock
TRISB = 0xB0;
PORTB = 0x00;
TRISA = 0x00;
PORTA = 0x00;
//Internal Clock 4MHz
PCON.OSCF = 1;
// Prescaler 1:1 external clock
T1CON = 0x0F;
PIE1.TMR1IE = 0; // disable interupt to stop the clock
INTCON = 0xC0;
// Set GIE, PEIE
TMR1L = LTMR1;
TMR1H = HTMR1;
// TMR1 starts at 0x0BDC = 3036 to make TMR1 counts to 62500 and
// overclows in every 0.1 sec
// Math: 1/500000*8*62500 = 0.1
// 1/5000000 : time for 20MHz crystal (internal clock will be 20/4 = 5MHz)
// 8: prescaler
// 62500: TMR1 counts to 62500
// Counting number of overflows to 10 will get 1 sec.
}
void show_time ()
{
display (1);
display (2);
display (3);
display (4);
display (5);
display (6);
}
void display (uns8 digit)
{
switch (digit)
{
case 1 :
PORTB = hr_h;
Hr_port_h = 1;
Hr_port_h = 0;
break;
case 2 :
PORTB = hr_l;
Hr_port_l = 1;
Hr_port_l = 0;
break;
case 3 :
PORTB = min_h;
Min_port_h = 1;
Min_port_h = 0;
break;
case 4 :
PORTB = min_l;
Min_port_l = 1;
Min_port_l = 0;
break;
case 5 :
PORTB = sec_h;
Sec_port_h = 1;
Sec_port_h = 0;
break;
case 6 :
PORTB = sec_l;
Sec_port_l = 1;
Sec_port_l = 0;
break;
}
}
void blink_digit (uns8 digit)
{
switch (digit)
{
case 1 :
PORTB = 0xFF;
Hr_port_h = 1;
Hr_port_h = 0;
Delay_ms (100);
display (1);
Delay_ms (100);
break;
case 2 :
PORTB = 0xFF;
Hr_port_l = 1;
Hr_port_l = 0;
Delay_ms (100);
display (2);
Delay_ms (100);
break;
case 3 :
PORTB = 0xFF;
Min_port_h = 1;
Min_port_h = 0;
Delay_ms (100);
display (3);
Delay_ms (100);
break;
case 4 :
PORTB = 0xFF;
Min_port_l = 1;
Min_port_l = 0;
Delay_ms (100);
display (4);
Delay_ms (100);
break;
case 5 :
PORTB = 0xFF;
Sec_port_h = 1;
Sec_port_h = 0;
Delay_ms (100);
display (5);
Delay_ms (100);
break;
case 6 :
PORTB = 0xFF;
Sec_port_l = 1;
Sec_port_l = 0;
Delay_ms (100);
display (6);
Delay_ms (100);
break;
}
}
void set_time ()
{
i = 1;
while (setting_time)
{
blink_digit (i);
while (SET == 0)
{
Delay_ms (5);
switch (i)
{
case 1 :
hr_h ++;
if (hr_h > 2)
{
hr_h = 0;
}
break;
case 2 :
hr_l ++;
if (hr_l > 9)
{
hr_l = 0;
}
if (hr_h >= 2 && hr_l > 3)
{
hr_l = 0;
}
break;
case 3 :
min_h ++;
if (min_h > 5)
{
min_h = 0;
}
break;
case 4 :
min_l ++;
if (min_l > 9)
{
min_l = 0;
}
break;
case 5 :
sec_h ++;
if (sec_h > 5)
{
sec_h = 0;
}
break;
case 6 :
sec_l ++;
if (sec_l > 9)
{
sec_l = 0;
}
break;
}
while (SET == 0)
{
Delay_ms (5);
}
}
while (MODE == 0)
{
Delay_ms (5);
i ++;
if (i > 6)
{
sec_l--;
TMR1H = 0x80;
TMR1L = 0x00;
PIE1.TMR1IE = 1;
setting_time = 0;
break;
}
while (MODE == 0)
{
Delay_ms (5);
}
}
}
}
void check_bt ()
{
myTimer = 0;
if (setting_time == 0)
{
while (MODE == 0)
{
Delay_ms (5);
myTimer ++;
if (myTimer > 200)
{
setting_time = 1;
myTimer = 0;
break;
}
}
}
while (MODE == 0)
{
PIE1.TMR1IE = 0;
//Stop clock
Delay_ms (5);
blink_digit (1);
}
set_time ();
}
//Using timer1 16bit counter interrupt
// PIC16F627A or PIC16F628
// Internal Clock 4MHz
// PUNKKY@gmail.com
#define MODE PORTB.F4
#define SET PORTB.F5
#define Sec_port_l PORTA.F6
#define Sec_port_h PORTA.F4
#define Min_port_l PORTA.F3
#define Min_port_h PORTA.F2
#define Hr_port_l PORTA.F1
#define Hr_port_h PORTA.F0
#define Blink PORTA.F7
#define HTMR1 0x80
#define LTMR1 0x00
typedef unsigned short uns8;
uns8 i;
uns8 hr_h;
uns8 hr_l;
uns8 min_h;
uns8 min_l;
uns8 sec_h;
uns8 sec_l;
uns8 tick;
uns8 myTimer;
uns8 setting_time;
void setup ();
void set_time ();
void show_time ();
void display (uns8 digit);
void blink_digit (uns8 digit);
void check_bt ();
//void check_bt(); //chech button
void interrupt ()
{
PIR1.TMR1IF = 0;
// clears TMR1IF
TMR1H = HTMR1;
tick = 1;
Blink = 1;
sec_l ++;
if(sec_l>9){
sec_l = 0;
sec_h++;
}
if(sec_h>5){
sec_h=0;
min_l++;
}
if(min_l>9){
min_l = 0;
min_h++;
}
if(min_h>5){
min_h = 0;
hr_l++;
}
if(hr_l>9){
hr_l = 0;
hr_h++;
}
if(hr_h >2){
hr_h = 0;
}
if(hr_h >=2 && hr_l>3){
hr_h = 0;
hr_l = 0;
}
}
void main ()
{
setup ();
//Set time
hr_h = 1;
hr_l = 2;
min_h = 3;
min_l = 4;
sec_h = 5;
sec_l = 6;
show_time ();
setting_time = 1;
set_time();
while (1)
{
//blink_digit();
if (tick)
{
tick = 0;
show_time ();
Delay_ms (300);
Blink = 0;
}
check_bt ();
}
}
void setup ()
{
tick = 0;
//Digital output on PORTA
CMCON = 0x07;
//Input buttons + external clock
TRISB = 0xB0;
PORTB = 0x00;
TRISA = 0x00;
PORTA = 0x00;
//Internal Clock 4MHz
PCON.OSCF = 1;
// Prescaler 1:1 external clock
T1CON = 0x0F;
PIE1.TMR1IE = 0; // disable interupt to stop the clock
INTCON = 0xC0;
// Set GIE, PEIE
TMR1L = LTMR1;
TMR1H = HTMR1;
// TMR1 starts at 0x0BDC = 3036 to make TMR1 counts to 62500 and
// overclows in every 0.1 sec
// Math: 1/500000*8*62500 = 0.1
// 1/5000000 : time for 20MHz crystal (internal clock will be 20/4 = 5MHz)
// 8: prescaler
// 62500: TMR1 counts to 62500
// Counting number of overflows to 10 will get 1 sec.
}
void show_time ()
{
display (1);
display (2);
display (3);
display (4);
display (5);
display (6);
}
void display (uns8 digit)
{
switch (digit)
{
case 1 :
PORTB = hr_h;
Hr_port_h = 1;
Hr_port_h = 0;
break;
case 2 :
PORTB = hr_l;
Hr_port_l = 1;
Hr_port_l = 0;
break;
case 3 :
PORTB = min_h;
Min_port_h = 1;
Min_port_h = 0;
break;
case 4 :
PORTB = min_l;
Min_port_l = 1;
Min_port_l = 0;
break;
case 5 :
PORTB = sec_h;
Sec_port_h = 1;
Sec_port_h = 0;
break;
case 6 :
PORTB = sec_l;
Sec_port_l = 1;
Sec_port_l = 0;
break;
}
}
void blink_digit (uns8 digit)
{
switch (digit)
{
case 1 :
PORTB = 0xFF;
Hr_port_h = 1;
Hr_port_h = 0;
Delay_ms (100);
display (1);
Delay_ms (100);
break;
case 2 :
PORTB = 0xFF;
Hr_port_l = 1;
Hr_port_l = 0;
Delay_ms (100);
display (2);
Delay_ms (100);
break;
case 3 :
PORTB = 0xFF;
Min_port_h = 1;
Min_port_h = 0;
Delay_ms (100);
display (3);
Delay_ms (100);
break;
case 4 :
PORTB = 0xFF;
Min_port_l = 1;
Min_port_l = 0;
Delay_ms (100);
display (4);
Delay_ms (100);
break;
case 5 :
PORTB = 0xFF;
Sec_port_h = 1;
Sec_port_h = 0;
Delay_ms (100);
display (5);
Delay_ms (100);
break;
case 6 :
PORTB = 0xFF;
Sec_port_l = 1;
Sec_port_l = 0;
Delay_ms (100);
display (6);
Delay_ms (100);
break;
}
}
void set_time ()
{
i = 1;
while (setting_time)
{
blink_digit (i);
while (SET == 0)
{
Delay_ms (5);
switch (i)
{
case 1 :
hr_h ++;
if (hr_h > 2)
{
hr_h = 0;
}
break;
case 2 :
hr_l ++;
if (hr_l > 9)
{
hr_l = 0;
}
if (hr_h >= 2 && hr_l > 3)
{
hr_l = 0;
}
break;
case 3 :
min_h ++;
if (min_h > 5)
{
min_h = 0;
}
break;
case 4 :
min_l ++;
if (min_l > 9)
{
min_l = 0;
}
break;
case 5 :
sec_h ++;
if (sec_h > 5)
{
sec_h = 0;
}
break;
case 6 :
sec_l ++;
if (sec_l > 9)
{
sec_l = 0;
}
break;
}
while (SET == 0)
{
Delay_ms (5);
}
}
while (MODE == 0)
{
Delay_ms (5);
i ++;
if (i > 6)
{
sec_l--;
TMR1H = 0x80;
TMR1L = 0x00;
PIE1.TMR1IE = 1;
setting_time = 0;
break;
}
while (MODE == 0)
{
Delay_ms (5);
}
}
}
}
void check_bt ()
{
myTimer = 0;
if (setting_time == 0)
{
while (MODE == 0)
{
Delay_ms (5);
myTimer ++;
if (myTimer > 200)
{
setting_time = 1;
myTimer = 0;
break;
}
}
}
while (MODE == 0)
{
PIE1.TMR1IE = 0;
//Stop clock
Delay_ms (5);
blink_digit (1);
}
set_time ();
}
I don't have the picture of the prototype as I haven't made it yet. But I have tested the circuit and firmware with proteus already.
--- Update ---
- The prototype of this updated version is done. Please see its photographs at 7-Segment PIC Digital Clock : The photographs
- The PCB is ready: please check out PCB for PIC Digital Clock
37 comments:
Seems to me like this is a very part-heavy project, without really having to be. I would think it would be possible to use row/column addressing and reverse parallel to get all 44 LED segments on something like 10 I/O pins, all without supporting hardware. The PIC16F628 has 15 I/O pins (1 I-only) with all accessories off, minus two for the crystal oscillator gives us three extra pins to use still, if we wanted to get lazy with the multiplexing. Buttons can be multiplexed with the display pins too using a few resistors.
Thank you for your comment. You are right this clock uses too many components but it was my intention. I made this clock to test my ideas and to learn Microcontroller. However, it is not easy to do led multiplexing with PIC16F627A/628 without using port expansion via shift register or something like that. Because, multiplexing 6x7-segment led requires 7 (for driving each segment)+ 6 (for commond cathode/anode) = 13 I/O pins and 2 pins are used for x-tal osc so I don't have pins for time setting buttons and for blinking second dots. Anyways, it's doable by multiplexing buttons and display as you suggested. I have done another updated version using multiplexing via 74HC595 shift register. I will post it soon, please come back again.
Thank you.
Hi, your project is very good, but I can't do work fine. in all digits show zeros. what is the error?.
sorry for my english but I'm from PERU.
thank you
The clock should display 12:34:56 when it's powered on. I am not sure what's cause the problem. Please make this 10-second counter http://picnote.blogspot.com/2008/11/10-second-counter.html for testing your equipment and wiring.
OK. thank you.
now All work fine!!!
what is the config of pic?
wachtdog on/off?
lvp on/off?
i don't know the config(the fuses)
Please check out http://picnote.blogspot.com/2008/11/10-second-counter.html for the config.
WDT : Off
LVP : Off
INTOSC_OSC_NOCLKOUT
Hi, please send me eagle sch and brd files Thanks.
Also, is 4543n is bcd to seven segment or any oyhrt buffer?
This might help you out if you want to cut down on display drivers.
http://datasheets.maxim-ic.com/en/ds/ICM7218-ICM7228.pdf
hi. i want to know if i can used the pic 16f628A.
or is only with 16f627A or 16f628
thanks.
Yes, you can use the PIC16f628A. But, the PIC16f627 is a little bit cheaper.
hii nathan, your digital clock are seems like this http://www.youtube.com/watch?v=BT-aQeqnPdw
but your clock doesnt have real time sync to PC. Actually i'm trying to build the same stuff as in youtube link, but i'm in stuck to figure out the sync and multiplexing process. i already contact alphap8, but there is no answer yet.
Do you have suggestion how the process does and how to build it?
thanks b4
uaps at gmail dot com
oupss sorry , my last comment is for punkky not nathan.
thanks b4
uaps at gmail dot com
Hi,Please send me your circuit simulated in Proteus.My email:
ngththien@gmail.com.Thanks very much!!!
No need of all those shift registers. You can drive 8 7-seg displays with only 9 pins. This is called charlieplexing.
Have a look at my project for an example.
http://tinyurl.com/nx56jo
Dear sir,
your digital clock was so amazing. . Sir can you send me the materials that you have use for that clock right n0w please. This my email add bloodyrole.amate@gmail.com
sir i am in a college in the philippines and i would like to know more about your digital clock cam you share to me the eagle file and the name of the materials including the name of the ic`s it an honor working with you sir this is my email: ferdz_14abuan@yahoo.com
Regards
I was looking for digital clock and came across on this post. it help me. Can it be possible if you can send me the PCB layout so i can develop it.
Secondly it it possible to make modifify it to Alarm clock or Digital temp. meter
My E-Mail add is "sadeekey@hotmail.com"
Thank you
Regards
Hi, im new in this! if you could help me out, im trying to program a pic 16f887, what i need is to control a servomotor, i have the program already, but it doesnt seem to work. my e-mail is llrholl@hotmail.com, thanx a lot
hey, I'm new on this. I want to build a 7 segment clock display like yours but an additional hourly alarm system. Basically, the buzzer will buzz every hour but I have no idea where should i connect the buzzer to. Please reply me on this as soon as possible, my email is mist_rival@hotmail.com
hi,
I would like to know how a 4-digit seven segment display can be interfaced with PIC16F877A using mplab IDE software.
Thank you.
Wow! Just the project that I was looking for! Please, can you email me the files for this project? also, if you have the multiplexed version too? Thank you very much! markdguzman@yahoo.com
hi...
i couldn't figure out how a 4-digit display can b interfaced... I've worked on 3-digit seven segment display... I'll send you the program... u need to have MPlab IDE 7.5 for this program to work...
HI PUNKKY: DO YOU SEND MI THE .HEX FILE OF YOUR PROYECT. I´M NOT HAVE EXPERIENCE WHITH PIC COMPILE.
THANK YOU
Washington Rojas
LU3EI
Radioamateur station from La Plata, Buenos Aires, Argentina
Hi Punkky~Can u send me the .hex to me? Currently i'm stuck at firmware file when im try to simulate at Protues. My email is kitt7974@hotmail.com.
Sorry for bad in english.
hi, can you send me the .hex. i don't complete. thanks
my mail: vaa.admin@gmail.com
Hi, is it possible ICD 2 use for MikroC programming? What programing hardware you are using?
Hello sir...
i am a university student,I study Engineering of Electronic Systems. sir i want to create this digital clock.would you mind give me a PCB layout of this circuit ? .please kindly request thanks sir ...
I like your posts sir , keep up ..
umax1989@hotmail.com
hello sir..
m studying electronics engineering..i need to do project on 'digital watch without microprocessor'..so can u please guide me with the apparatus,circuit etc.. and this is my first project..just mail me to my ID mandapallivarsha@gmail.com
thank u
Bro....its better to use multiplexing...becoz with very less components you can easily make it :) i have multiplexed 6 Digits..easily using PIC 16F877A :) i m too learning but it rocks...mux is the best...way...and professional too
hey, i'm jhavik. i'm a student on electronics engineering, your project is amazing and i would like to make a project like yours can you please send me a digital circuit on email please.
bferndejhavik@gmail.com
I am new in microcontroller. I do not understand your osc. because i was trying its but not works as per your osc 32.768khz setting in RB7 and RB6 but d clock pulse setting then works and blinking led. belal08mg@gmail.com
That's really nice!!! Cos I'm finding some circuit and code for my study project. Just this is enough for me. Thank you very much.
Hope you have new update project.
Great explanation about digital clock making. Thanks.
Digital clock online
Oximus smart watch @ http://www.oximustechnologies.com/
Oximus best smart watches deals :
Oximus U8 Smart Watch : https://www.amazon.in/U8-Notification-Bluetooth-Android-Smartwatch/dp/B003ZDRL2O
Oximus Dz09 Smart Watch : https://www.amazon.in/Oximus-Digital-Unisex-Screen-Bluetooth/dp/B074GY3N47
Oximus V8 Smart Watch : https://www.amazon.in/Compatible-V8-Monitoring-Microphone-Multi-Language/dp/B008S9U3KC
Post a Comment