astouffer
- 27th February 2014, 02:09
Well my numitron clock project is nearly complete. My problem is in the code to set the initial time. It didn't allow for the minutes to be set at 00. I fixed that by moving the "mm = mm + 1" line to the bottom of the setmm loop. That allows for 00 to be selected. Now when the timekeeping loop runs it changes 00 to 01 instantly. The time is set by a button that grounds a pin. It increments the digits until the pin is brought high again. When the hours and minutes are set, grounding the pin a third time starts the timekeeping loop. While setting the time the decimal points are lit up so you know the clock is not running. Here is what the code looks like:
@ __CONFIG _FOSC_INTOSCIO & _WDTE_OFF & _WDT_OFF & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _IESO_OFF & _FCMEN_OFF
OSCCON = %01110101 'Internal OSC 8MHz
DEFINE OSC 8 '8MHz
PORTA = 0 '
TRISA = %00100100 'Porta.2 input
WPUA = %00100000 'Weak pullup on Porta.5
TRISC = 0 '
PORTC = 0 '
ANSEL = 0 '
CMCON0 = %00000111 'Comparators off and I/O is digital
ADCON0 = 0 'A/D is off
CCP1CON = 0 'PWM and CCP off
OPTION_REG = %01110110 'Timer0 on with 128 prescaler and weak pullups on
INTCON = %11100000 'INTCON.2 overflow bit
Include "modedefs.bas"
hstro VAR portc.3 'Strobe line for hours chip
mstro VAR portc.2 'Strobe line for mins chip
dat VAR portc.5 'Data line for chips
clk VAR portc.4 'Clock line for chips
ss VAR byte 'Seconds
mm VAR byte 'Minutes
hh VAR byte 'Hours
v1 VAR byte 'Display bits for tube V1
v2 VAR byte 'Display bits for tube V2
v3 VAR byte 'Display bits for tube V3
v4 VAR byte 'Display bits for tube V4
ss = 0
mm = 0
hh = 0
shiftout dat, clk, 0, [$80, $80] 'Turn on decimal points to show its working
pulsout hstro, 10
pulsout mstro, 10
waithere: 'Wait until a button is pressed
while porta.5 = 1
@ NOP
wend
sethh: 'Routine for setting the hours
if porta.5 = 1 then goto waitformm
hh = hh + 1
if hh = 13 then hh = 1
v1 = hh DIG 1 'Breaks the double digits into singles
v2 = hh DIG 0 'for the lookup table
if hh < 10 then 'This makes the leading hour digit blank
lookup v1, [$80,$E0,$D7,$F6,$EC,$BE,$BF,$F0,$FF,$FE], v1
else
lookup v1, [$FB,$E0,$D7,$F6,$EC,$BE,$BF,$F0,$FF,$FE], v1
endif
lookup v2, [$FB,$E0,$D7,$F6,$EC,$BE,$BF,$F0,$FF,$FE], v2
shiftout dat, clk, 0, [v2, v1]
pulsout hstro, 10
shiftout dat, clk, 0, [$00, $00]
pulsout mstro, 10
pause 750
goto sethh
waitformm: 'Wait until button is pressed for next loop
while porta.5 = 1
@ NOP
wend
setmm: 'Routine for setting the minutes
if porta.5 = 1 then goto settime
if mm = 60 then mm = 1
v3 = mm DIG 1 'Breaks up double digits into singles
v4 = mm DIG 0 'for the lookup table
lookup v3, [$FB,$E0,$D7,$F6,$EC,$BE,$BF,$F0,$FF,$FE], v3
lookup v4, [$FB,$E0,$D7,$F6,$EC,$BE,$BF,$F0,$FF,$FE], v4
shiftout dat, clk, 0, [v4, v3]
pulsout mstro, 10
pause 750
mm = mm + 1
goto setmm
settime: 'Wait until button is pressed and starts the clock
while porta.5 = 1
@ NOP
wend
startloop: 'Need this for the interrupt routine
enable
on interrupt goto timekeep
main: 'Wait until counter overflows and interrupts
@ NOP
goto main
disable
timekeep: 'Actual timekeeping code. Pretty self explanatory
ss = ss + 1
if ss = 60 then
ss = 0
mm = mm + 1
endif
if mm = 60 then
mm = 0
hh = hh + 1
endif
if hh = 13 then hh = 1 'Change this to 25 for 24 hour time
v1 = hh DIG 1
v2 = hh DIG 0
v3 = mm DIG 1
v4 = mm DIG 0
if hh < 10 then
lookup v1, [$00,$60,$57,$76,$6C,$3E,$3F,$70,$7F,$7E], v1
else
lookup v1, [$7B,$60,$57,$76,$6C,$3E,$3F,$70,$7F,$7E], v1
endif
lookup v2, [$7B,$60,$57,$76,$6C,$3E,$3F,$70,$7F,$7E], v2
lookup v3, [$7B,$60,$57,$76,$6C,$3E,$3F,$70,$7F,$7E], v3
lookup v4, [$7B,$60,$57,$76,$6C,$3E,$3F,$70,$7F,$7E], v4
shiftout dat, clk, 0, [v2, v1]
pulsout hstro, 10
shiftout dat, clk, 0, [v4, v3]
pulsout mstro, 10
INTCON.2 = 0 'Clear interrupt flag
resume startloop 'Go back to the do nothing loop
And here is what it looks like http://i.imgur.com/bNyigGW.jpg
Also if anyone is curious about the accuracy of the DS32KHZ oscillator chip, here it is on a freshly calibrated frequency counter http://i.imgur.com/N3TGFOJ.jpg
@ __CONFIG _FOSC_INTOSCIO & _WDTE_OFF & _WDT_OFF & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _IESO_OFF & _FCMEN_OFF
OSCCON = %01110101 'Internal OSC 8MHz
DEFINE OSC 8 '8MHz
PORTA = 0 '
TRISA = %00100100 'Porta.2 input
WPUA = %00100000 'Weak pullup on Porta.5
TRISC = 0 '
PORTC = 0 '
ANSEL = 0 '
CMCON0 = %00000111 'Comparators off and I/O is digital
ADCON0 = 0 'A/D is off
CCP1CON = 0 'PWM and CCP off
OPTION_REG = %01110110 'Timer0 on with 128 prescaler and weak pullups on
INTCON = %11100000 'INTCON.2 overflow bit
Include "modedefs.bas"
hstro VAR portc.3 'Strobe line for hours chip
mstro VAR portc.2 'Strobe line for mins chip
dat VAR portc.5 'Data line for chips
clk VAR portc.4 'Clock line for chips
ss VAR byte 'Seconds
mm VAR byte 'Minutes
hh VAR byte 'Hours
v1 VAR byte 'Display bits for tube V1
v2 VAR byte 'Display bits for tube V2
v3 VAR byte 'Display bits for tube V3
v4 VAR byte 'Display bits for tube V4
ss = 0
mm = 0
hh = 0
shiftout dat, clk, 0, [$80, $80] 'Turn on decimal points to show its working
pulsout hstro, 10
pulsout mstro, 10
waithere: 'Wait until a button is pressed
while porta.5 = 1
@ NOP
wend
sethh: 'Routine for setting the hours
if porta.5 = 1 then goto waitformm
hh = hh + 1
if hh = 13 then hh = 1
v1 = hh DIG 1 'Breaks the double digits into singles
v2 = hh DIG 0 'for the lookup table
if hh < 10 then 'This makes the leading hour digit blank
lookup v1, [$80,$E0,$D7,$F6,$EC,$BE,$BF,$F0,$FF,$FE], v1
else
lookup v1, [$FB,$E0,$D7,$F6,$EC,$BE,$BF,$F0,$FF,$FE], v1
endif
lookup v2, [$FB,$E0,$D7,$F6,$EC,$BE,$BF,$F0,$FF,$FE], v2
shiftout dat, clk, 0, [v2, v1]
pulsout hstro, 10
shiftout dat, clk, 0, [$00, $00]
pulsout mstro, 10
pause 750
goto sethh
waitformm: 'Wait until button is pressed for next loop
while porta.5 = 1
@ NOP
wend
setmm: 'Routine for setting the minutes
if porta.5 = 1 then goto settime
if mm = 60 then mm = 1
v3 = mm DIG 1 'Breaks up double digits into singles
v4 = mm DIG 0 'for the lookup table
lookup v3, [$FB,$E0,$D7,$F6,$EC,$BE,$BF,$F0,$FF,$FE], v3
lookup v4, [$FB,$E0,$D7,$F6,$EC,$BE,$BF,$F0,$FF,$FE], v4
shiftout dat, clk, 0, [v4, v3]
pulsout mstro, 10
pause 750
mm = mm + 1
goto setmm
settime: 'Wait until button is pressed and starts the clock
while porta.5 = 1
@ NOP
wend
startloop: 'Need this for the interrupt routine
enable
on interrupt goto timekeep
main: 'Wait until counter overflows and interrupts
@ NOP
goto main
disable
timekeep: 'Actual timekeeping code. Pretty self explanatory
ss = ss + 1
if ss = 60 then
ss = 0
mm = mm + 1
endif
if mm = 60 then
mm = 0
hh = hh + 1
endif
if hh = 13 then hh = 1 'Change this to 25 for 24 hour time
v1 = hh DIG 1
v2 = hh DIG 0
v3 = mm DIG 1
v4 = mm DIG 0
if hh < 10 then
lookup v1, [$00,$60,$57,$76,$6C,$3E,$3F,$70,$7F,$7E], v1
else
lookup v1, [$7B,$60,$57,$76,$6C,$3E,$3F,$70,$7F,$7E], v1
endif
lookup v2, [$7B,$60,$57,$76,$6C,$3E,$3F,$70,$7F,$7E], v2
lookup v3, [$7B,$60,$57,$76,$6C,$3E,$3F,$70,$7F,$7E], v3
lookup v4, [$7B,$60,$57,$76,$6C,$3E,$3F,$70,$7F,$7E], v4
shiftout dat, clk, 0, [v2, v1]
pulsout hstro, 10
shiftout dat, clk, 0, [v4, v3]
pulsout mstro, 10
INTCON.2 = 0 'Clear interrupt flag
resume startloop 'Go back to the do nothing loop
And here is what it looks like http://i.imgur.com/bNyigGW.jpg
Also if anyone is curious about the accuracy of the DS32KHZ oscillator chip, here it is on a freshly calibrated frequency counter http://i.imgur.com/N3TGFOJ.jpg