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