PROGRAM I ;************************************ ; written by: John Morton * ; date: 10/0105 * ; version 1.0 * ; file saved as StopClock * ; for PIC16F54 * ; clock frequency 2.4576 MHz * ; ************************************ ; PROGRAM FUNCTION: A stop clock displaying the time in tenths of second, seconds, tens of seconds and minutes. list P=16F54 include "c:\pic\p16f5x.inc" __config _XT_OSC & _WDT_OFF & _CP_OFF ;============== ; Declarations: porta equ 05 portb equ 06 General equ 08 Mark240 equ 09 Mark250 equ 0A TenthSec equ 0B Seconds equ 0C TenSecond equ 0D Minutes equ 0E #define bounce General, 1 #define start General, 0 org 1FFh goto Start org 0 ;============= ; Subroutines: Init clrf porta ; resets input/output ports clrf portb ; movlw b'0000' ; bits 0-3: 7-seg display tris porta ; control movlw b'00000001' ; bits 1-7: 7-seg display code tris portb ; bit 0: start/stop button movlw b'00000111' ; TMR0 prescaled by 256 option clrf TenthSec ; resets timing registers clrf Seconds ; clrf TenSecond ; clrf Minutes ; bcf start ; initially, stop state bsf bounce ; bounce initially set movlw d'240' ; sets up marker register movwf Mark240 ; retlw 0 ; ;================================== Debounce movfw Mark250 ; if about 0.1 seconds have subwf TMR0, w ; passed, sets the bounce btfss STATUS, Z ; bit retlw 0 ; bsf bounce ; retlw 0 PrimeBounce bcf bounce ; clears bounce bit to trigger movlw d'250' ; and sets up Mark250 so that addwf TMR0, w ; about 0.1 seconds will be movwf Mark250 ; counted retlw 0 ; ;================================== Update btfsc start ; checks start/stop state call Timing ; if start, updates timers btfss bounce ; checks whether or not to test call Debounce ; whether 0.1 seconds passed? movlw b'00000011' ; ignores all but bits 0 and 1 andwf TMR0, w ; of TMR0, leaving result in w addwf PCL, f ; adds result to PC, in order to goto Display10th ; select a display goto Display1 ; goto Display10 ; goto DisplayMin ; Display10th movfw TenthSec ; takes the number from TenthSec call _7SegDisp ; converts number into 7seg code movwf portb ; displays value through Port B movlw b'0010' ; turns on correct display movwf porta ; retlw 0 ; returns Display1 movfw Seconds ; takes the number from Seconds call _7SegDisp ; converts number into 7seg code movwf portb ; displays value through Port B movlw b'0001' ; turns on correct display movwf porta ; retlw 0 ; returns Display10 movfw TenSecond ; takes the number from TenSeconds call _7SegDisp ; converts number into 7seg code movwf portb ; displays value through Port B movlw b'1000' ; turns on correct display movwf porta ; retlw 0 ; returns DisplayMin movfw Minutes ; takes the number from Minutes call _7SegDisp ; converts number into 7seg code movwf portb ; displays value through Port B movlw b'0100' ; turns on correct display movwf porta ; retlw 0 ; returns ;=============================== _7SegDisp addwf PCL, f ; returns with correct 7-seg code retlw b'11111100' ; code for 0 retlw b'01100000' ; code for 1 retlw b'11011010' ; code for 2 retlw b'11110010' ; code for 3 retlw b'01100110' ; code for 4 retlw b'10110110' ; code for 5 retlw b'10111110' ; code for 6 retlw b'11100000' ; code for 7 retlw b'11111110' ; code for 8 retlw b'11110110' ; code for 9 ;================================ Timing movfw Mark240 ; tests to see if 0.1 seconds have subwf TMR0, w ; passed btfss STATUS, Z ; retlw 0 ; 0.1 seconds hasnŐt passed - returns movlw d'240' ; updates Mark240 addwf Mark240,f ; incf TenthSec, f ; adds 1 to number of 0.1 seconds movlw d'10' ; tests to see whether TenthSec has subwf TenthSec, w ; reached 10 (has one second passed?) btfss STATUS, Z ; retlw 0 ; 1 second hasn't passed, so returns clrf TenthSec ; 1 second has passed, so resets incf Seconds, f ; TenthSec and adds 1 to Seconds movlw d'10' ; tests to see whether Seconds has subwf Seconds, w ; reached 10 (whether or ten seconds btfss STATUS, Z ; has passed) retlw 0 ; clrf Seconds ; 10 seconds have passed, so resets incf TenSecond,f ; Seconds and adds 1 to TenSecond movlw d'6' ; tests to see whether TenSecond has subwf TenSecond, w ; reached 6 (whether one minute btfss STATUS, Z ; has passed) retlw 0 ; clrf TenSecond ; 60 seconds have passed, so resets incf Minutes, f ; TenSecond and adds 1 to Minutes movlw d'10' ; tests to see whether Minutes has subwf Minutes, w ; reached 10 (whether or ten minutes btfss STATUS, Z ; has passed) retlw 0 ; clrf Minutes ; 10 minutes have passed, so resets retlw 0 ; ;================================ Start call Init ; runs initialisation routine Released call Update ; keeps timing and display updated btfss bounce ; waits 0.1 s to confirm button is goto Released ; released btfss portb, 0 ; has button now been pressed? goto Released ; no, so keeps looping movlw b'00000001' ; toggles state of start/stop bit xorwf General, f ; call PrimeBounce ; primes de-bounce routine Pressed call Update ; keeps timing and display updated btfss bounce ; waits 0.1s to confirm button is goto Pressed ; pressed btfsc portb, 0 ; has button now been released? goto Pressed ; no, so keeps looping call PrimeBounce ; primes de-bounce routine goto Released ; END