| SX/B Example: Clock / Timer | Examples Index |
' =========================================================================
'
' File...... TIMER.SXB
' Purpose... Dual-Mode digital timer
' Author.... (c) Parallax, Inc. -- All Rights Reserved
' E-mail.... support@parallax.com
' Started...
' Updated... 05 JUL 2006
'
' =========================================================================
' -------------------------------------------------------------------------
' Program Description
' -------------------------------------------------------------------------
'
' Displays running clock/timer on multiplexed 7-segment display. The
' four-digit display is multiplexed through a "virtual" driver which is
' handled in the INTERRUPT routine.
' -------------------------------------------------------------------------
' Device Settings
' -------------------------------------------------------------------------
DEVICE SX28, OSCXT2, TURBO, STACKX, OPTIONX
FREQ 4_000_000
ID "TIMER"
' -------------------------------------------------------------------------
' IO Pins
' -------------------------------------------------------------------------
DigCtrl VAR RA ' digit control (cathodes)
Segs VAR RB ' display segments (anodes)
TmrMode VAR RC.6 ' mode: 0 = mmss, 1 = hhmm
TmrEnable VAR RC.7 ' enable input, 1 = run
' -------------------------------------------------------------------------
' Constants
' -------------------------------------------------------------------------
Yes CON 1
No CON 0
MaxDigit CON 4 ' 4-digit display
DecPnt CON %10000000 ' decimal point mask
TmrMMSS CON 1 ' show MM.SS (no blink)
TmrHHMM CON 0 ' show HH.MM (blink DP)
TmrRun CON 1 ' run timer
TmrHold CON 0 ' hold timer
MaxHr CON 24 ' 0 .. 23 (clock mode)
' make 100 for 0 .. 99
' -------------------------------------------------------------------------
' Variables
' -------------------------------------------------------------------------
ms VAR Word ' milliseconds
clock VAR Byte(3) ' clock array
secs VAR clock(0) ' seconds
mins VAR clock(1) ' minutes
hrs VAR clock(2)
blink VAR secs.0 ' DP blink control bit
display VAR Byte(MaxDigit) ' multiplexed segments
digPntr VAR Byte ' digit pointer
tmpB1 VAR Byte
tmpB2 VAR Byte
' -------------------------------------------------------------------------
INTERRUPT 1000
' -------------------------------------------------------------------------
' The ISR is called every millisecond using the Rate parameter of the
' INTERRUPT instruction. With a 4 MHz clock, the prescaler will be set
' 1:16 and the ISR will run every 250 RTCC cycles.
'
' If the timer is enabled (TmrEnable pin = 1), the timer values will be
' updated every millisecond, otherwise only the display will be refreshed
' (one digit per interrupt).
ISR_Start:
IF TmrEnable = TmrHold THEN Next_Digit ' skip clock update if 0
Update_Timer:
INC ms ' update ms counter
IF ms = 1000 THEN ' check for 1 second
ms = 0
INC secs
IF secs = 60 THEN ' check for new minute
secs = 0
INC mins
IF mins = 60 THEN ' check for new hour
mins = 0
INC hrs
IF hrs = MaxHr THEN
hrs = 0
ENDIF
ENDIF
ENDIF
ENDIF
Next_Digit:
INC digPntr ' point to next digit
IF digPntr = MaxDigit THEN ' check pointer
digPntr = 0 ' wrap if needed
ENDIF
Update_Segs:
Segs = %00000000 ' blank segments
READ DigMap + digPntr, DigCtrl ' update digit control
Segs = display(digPntr) ' output new segments
ISR_Exit:
RETURNINT
' =========================================================================
PROGRAM Start
' =========================================================================
' -------------------------------------------------------------------------
' Subroutine Declarations
' -------------------------------------------------------------------------
CLOCK_MMSS SUB 0 ' show mins & secs
CLOCK_HHMM SUB 0 ' show hrs & mins
' -------------------------------------------------------------------------
' Program Code
' -------------------------------------------------------------------------
Start:
DigCtrl = %1111 ' disable all digits
TRIS_A = %0000 ' make dig pins outputs
Segs = %00000000 ' clear seg drivers
TRIS_B = %00000000 ' make seg pins outputs
PLP_C = %11000000 ' pull-up unused pins
Main:
DO
PAUSE 50
IF TmrMode = TmrHHMM THEN ' check mode
CLOCK_HHMM
ELSE
CLOCK_MMSS
ENDIF
LOOP
' -------------------------------------------------------------------------
' Subroutine Code
' -------------------------------------------------------------------------
' Display timer in MM.SS (00.00 .. 59.59) format with solid DP
CLOCK_MMSS: ' display mins & secs
tmpB1 = mins / 10 ' get 10's digit
tmpB2 = __REMAINDER ' save 1's digit
READ SegMap + tmpB1, display(3)
READ SegMap + tmpB2, display(2)
display(2) = display(2) | DecPnt ' add DP to hr01 digit
tmpB1 = secs / 10
tmpB2 = __REMAINDER
READ SegMap + tmpB1, display(1)
READ SegMap + tmpB2, display(0)
RETURN
' -------------------------------------------------------------------------
' Display timer in HH.MM (00.00 .. 23.59) format with blinking DP
CLOCK_HHMM: ' display hours & mins
tmpB1 = hrs / 10
tmpB2 = __REMAINDER
READ SegMap + tmpB1, display(3)
READ SegMap + tmpB2, display(2)
IF blink = Yes THEN
display(2) = display(2) | DecPnt ' blink DP on hr01 digit
ENDIF
tmpB1 = mins / 10
tmpB2 = __REMAINDER
READ SegMap + tmpB1, display(1)
READ SegMap + tmpB2, display(0)
RETURN
' =========================================================================
' User Data
' =========================================================================
SegMap: ' segments maps
' .gfedcba
DATA %00111111 ' 0
DATA %00000110 ' 1
DATA %01011011 ' 2
DATA %01001111 ' 3
DATA %01100110 ' 4
DATA %01101101 ' 5
DATA %01111101 ' 6
DATA %00000111 ' 7
DATA %01111111 ' 8
DATA %01100111 ' 9
DigMap: ' digit select map
DATA %11111110
DATA %11111101
DATA %11111011
DATA %11110111