3 Attachment(s)
	
	
		Single digit 7 Seg LED clock - PIC16F88
	
	
		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.
	Code:
	
'****************************************************************
'*  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