PDA

View Full Version : Single digit 7 Seg LED clock - PIC16F88



thirsty
- 15th July 2009, 09:35
Hi All,

I've been wanting to do this project for a while now and have finally gotten around to it.

I've built a single digit clock using a 2.3" 7 segment LED (green in this case). The clock flashes each digit in the time for one second before displaying the next. It also lights the DP on the second hour digit.

There are 2 push buttons for setting the time as well.

Here is the code and a couple of photos of the boards.



'************************************************* ***************
'* Name : Large_LED_Clock.BAS
'* Author : Tony Hirst [email protected]
'* Date : 14/07/2009
'* Version : 1.0
'* Notes : Program to drive a 7 segment LED single digit clock.
'* : Utilises Darrel Taylor's Instant Interrupt routines.
'* : The program should be self explanatory but here are
'* : the basics:
'* : Program simply checks to see if seconds have
'* : changed and, if so, displays the next number
'* : sequence on the single LED display.
'* : Firstly the first hours digit is displayed,
'* : pause for 1 second, then display the second
'* : hour digit with the dp and so on. Display is
'* : blanked for one second after the second minute
'* : has been displayed.
'* :
'* : There is also a fade in routine that brings the
'* : digits on "gently" over a few milliseconds to
'* : make the display a bit easier on the eye.
'* : The clock is in 24hour mode and if the hour is
'* : only one digit the program only displays one digit.
'*
'* : There are two buttons connected to RA2 and 3.
'* : RA2 when pressed increments the minutes and RA3
'* : the hours.
'* : To set the time initially hold down mbtn while
'* : powering on. This puts device into setup mode.
'* : Pressing mbtn and hbtn increments the hours and
'* : minutes respectively. No btn presses for 2 secs
'* : will start program proper.
'* :
'* : Hardware:
'* : PIC16F88
'* : 4MHz Xtal (XT) 30ppm accuracy preferred
'* : UDN2981 for CC LED's or ULN2003 for CA LED's
'* : 2.3" 7 Segment LED from Futurlec
'* : 12V for UDN/ULN
'* : 78L05 V reg for Pic
'************************************************* ***************


INCLUDE "DT_INTS-14.bas"
INCLUDE "ReEnterPBP.bas"
INCLUDE "Elapsed_INT.bas" ; Elapsed Timer Routines

ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler TMR1_INT, _ClockCount, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor

INT_ENABLE TMR1_INT ; Enable Timer 1 Interrupts
ENDASM

TRISB = %00000000 'ALL OUTPUTS
TRISA = %00001100 '2 and 3 are inputs
ANSEL = %00000000 'PortA all digital

TEMP var byte ' last digit displayed ie h1, h2, m1, m2, or pause 1s
' 0 1 2 3 4
pulse var byte 'Holds value for display in fade in routine
i var word '
x var word 'General purpose vars used in fade in routine
y var word '
h var byte 'used in initial time setup
m var byte ' " "
init var bit 'flag to indicate initial time setup

NUM var byte ' number to display

mbtn var porta.2 'button to set minutes
hbtn var porta.3 'button to set hours

GOSUB ResetTime ' Reset Time to 0d-00:00:00.00

h = 0
m = 0
init = 0

'************************************************* *****************************
' to set time initially mbutton must be pressed for at least 1 sec while *
' powering on. *
' Prog stays in this loop until 2ish seconds has passed without a button being*
' pushed. *
'************************************************* *****************************
if mbtn = 0 then 'if mbtn pushed
pause 1000
while mbtn = 0 'wait 'til button released
wend
setup:
if mbtn = 0 then
pause 30 'debounce
if mbtn = 0 then gosub mbtn_handler
GOSUB ResetTime 'reset the clock to keep track of the 2 seconds wait
gosub StartTimer 'start timer
endif
if hbtn = 0 then
pause 30 'debounce
if hbtn = 0 then gosub hbtn_handler
GOSUB ResetTime 'reset the clock to keep track of the 2 seconds wait
gosub StartTimer 'start timer
endif
if seconds < 2 then goto setup 'if we're within the 2ish seconds then wait
endif

gosub ResetTime 'reset the timer

init = 1 ' reset init flag
hours = h ' allocate initial times from setup
minutes = m ' these will be zero if setup was skipped

GOSUB StartTimer ' Start the Elapsed Timer

temp = 4 'init display routine to blank

goto display

'***************************
'* Handle minutes btn push *
'***************************
mbtn_handler:

if init = 1 then
Minutes=Minutes + 1
IF Minutes=60 THEN
Minutes=0
ENDIF
else
m = m + 1
if m = 60 then m = 0
endif
pause 200
seconds = 0
return

'***************************
'* Handle hours btn push *
'***************************
hbtn_handler:

if init = 1 then
Hours=Hours+1
IF Hours=24 THEN
Hours=0
ENDIF
else
h = h + 1
if h = 24 then h = 0
endif
pause 200
seconds = 0
return

'************************************************
'* Display routine *
'* *
'* Output hours and minutes one digit at a time.*
'* Light the dp with the second hours number *
'************************************************
display:
'check if a button has been pushed
if mbtn = 0 then
pause 30 'debounce
if mbtn = 0 then
gosub mbtn_handler
endif
endif
if hbtn = 0 then
pause 30 'debounce
if hbtn = 0 then
gosub hbtn_handler
endif
endif

' Now work out which digit to display next. 1 second between changes
if secondschanged = 1 then
secondschanged = 0

if Hours < 10 then 'if no 1st hour digit then skip it and go to 2nd dig
if temp = 0 then temp = 1
endif
select case temp
case is = 0
temp = 1
'output first hour digit
num = hours dig 1
goto led_driver
case is = 1
temp = 2
'output second hour digit
if hours < 10 then
num = Hours
else
num = hours dig 0
endif
goto led_driver
case is = 2
temp = 3
'output first minute digit
if minutes < 10 then
num = 0
else
num = minutes dig 1
endif
goto led_driver
case is = 3
temp = 4
'output second minute digit
if minutes < 10 then
num = minutes
else
num = Minutes dig 0
endif
goto led_driver
case is = 4
temp = 0
'blank display
num = 99
goto led_driver
end select
else
goto display 'second hasn't changed so wait in this function
endif

'now fall thru to led display

'************************************
'* LED driver routine *
'* Uses NUM variable set in Display *
'* routine to display number *
'************************************
led_driver:
pulse = 0
select case num
case is = 0
pulse = %11110101
case is = 1
pulse = %11000000
case is = 2
pulse = %10111100
case is = 3
pulse = %11101100
case is = 4
pulse = %11001001
case is = 5
pulse = %01101101
case is = 6
pulse = %01111101
case is = 7
pulse = %11000100
case is = 8
pulse = %11111101
case is = 9
pulse = %11101101
case is = 99
portb = 0
end select

' Fade in routine - pulse is value of number on LED
if pulse > 0 then
if temp = 2 then ' if dp is needed
pulse = pulse + %00000010
endif
x = 0
y = 20
for i = 1 to 10
portb = pulse
pause x ' turn on LED
portb = 0
pause y ' turn off LED
y = y - 2
x = x + 2
next
portb = pulse ' turn LED on for final time
endif

goto display 'go back and wait for seconds to change over

END

Jerson
- 15th July 2009, 10:54
Tony

First impressions, you seem to be doing a pretty neat job at coding. We don't know if you're a PC side programmer, but your style shows the way a good program code should be written with self documentation.

thirsty
- 15th July 2009, 11:09
Hi Jerson,

Yep I'm a programmer (amongst other things) in the PC world and like to keep my progs neat and tidy.

I'm sure the code could be made smaller and more "clever" but I like to keep it understandable and I'm no PBP expert.

I've also posted a video of the clock running on youtube here - http://www.youtube.com/watch?v=qEjSHqqNrzI

Darrel Taylor
- 17th July 2009, 09:27
That's different. Neat.

I noticed in the video it goes from 13.39 to 13.30 to 13.40, when the minute changed in the middle of displaying the time.

Maybe if you saved the time before displaying it, it wouldn't do that.

Seems like it could go a little faster too, but maybe it would be too fast for some people.

Nice work,

thirsty
- 17th July 2009, 09:42
Thanks Darrel.

I've already fixed the time problem you mentioned and I did it exactly as you suggested! I'll need to post the new code soon as I also removed one of the buttons - I stole another idea I saw on youtube where a press of the btn will increment the digit currently displayed. A lot more elegant and works well.

I've got the clock running in the lounge along with my nixie tube clock and it's actually very easy to read at the current speed. It's not at all annoying either which is nice.

Making up a nice wood housing for it now.