Program I : ;************************************ ; written by : John Morton * ; date : 31/07/97 * ; version : 1.0 * ; file saved as : StopClock * ; for PIC54 * ; clock frequency : 2.4576 MHz * ;************************************ ; PROGRAM FUNCTION : A stop clock displaying the time in tenths of seconds, seconds, ; tens of seconds and minutes. The minimum time is one second. list P=16C54 include "c:\pic\p16c5x.inc" ;============ ; Declarations : porta equ 05 portb equ 06 Mark240 equ 08 TenthSec equ 09 Seconds equ 0A TenSecond equ 0B Minutes equ 0C Mark80 equ 0D Post30 equ 0E General equ 0F #define sec General, 0 org 1FF goto Start org 0 ;=========== ; Subroutines : Init clrf porta ; resets inputsa and outputs clrf portb ; movlw b'0000' ; RA0-3 : 7 Segment Display Select tris porta movlw b'00000001' ; RB0 : Multipurpose push button, tris portb ; RB1-7 : 7 Segment code movlw b'00000111' ; sets up timing register option movlw d'10' ; sets up postscaler movwf Post10 clrf TenthSec ; resets G.P. file registers clrf Seconds ; clrf TenSecond ; clrf Minutes ; clrf General ; retlw 0 ;===== Timer movfw Mark240 ; tests to see if TMR0 has passed through 240 subwf TMR0, w ; cycles (i.e. 1/10th of a second has passed) btfss STATUS, Z ; retlw 0 ; 1/10th of a second hasn't passed, so returns movlw d'240' ; 1/10th of a second has passed, so adds addwf Mark240, f ; the decimal number 240 to Mark240 incf TenthSec, f ; increments the number of tenths of a second movlw d'10' ; tests to see whether TenthSec has reached 10 subwf TenthSec, w ; (i.e. whether or not one second has passed) btfss STATUS, Z ; retlw 0 ; 1 second hasn't passed, so returns clrf TenthSec ; 1 second has passed, so resets TenthSec and incf Seconds, f ; increments the number of seconds movlw d'10' ; tests to see whether Seconds has reached 10 subwf Seconds, w ; (i.e. whether or not ten seconds have passed) btfss STATUS, Z ; retlw 0 ; 10 seconds haven't passed, so returns clrf Seconds ; 10 seconds have passed, so resets Seconds and incf TenSecond, f ; increments the number of tens of seconds movlw d'6' ; tests to see whether TenSecond has reached 6 subwf TenSecond, w ; (i.e. whether or not one minute has passed) btfss STATUS, Z ; retlw 0 ; 1 minute hasn't passed, so returns clrf TenSecond ; 1 minute has passed, so resets TenSecond and incf Minutes, f ; increments the number of minutes movlw d'10' ; test to see whether Minutes has reached 10 subwf Minutes, w ; btfss STATUS, Z ; retlw 0 ; 10 minutes haven't passed, so returns clrf Minutes ; 10 minutes have passed, so resets Minutes retlw 0 ; and returns. ;====== Display movlw b'00000011' ; ignores all but bits 0 and 1 of TMR0 andwf TMR0, w ; leaving the result in the working register addwf PCL, f ; adds the result to the program counter goto Display10th ; displays tenths of a second goto Display1 ; displays seconds goto Display10 ; displays tens of seconds goto DisplayMin ; displays minutes Display10th movfw TenthSec ; takes the number out of TenthSec call _7SegDisp ; converts the number into 7 seg code movwf portb ; displays the value through Port B movlw b'0010' ; turns on correct display movwf porta ; retlw 0 ; returns Display1 movfw Seconds ; takes the number out of Seconds call _7SegDisp ; converts the number into 7 seg code movwf portb ; displays the value through Port B movlw b'0001' ; turns on correct display movwf porta ; retlw 0 ; returns Display10 movfw TenSecond ; takes the number out of TenSecond call _7SegDisp ; converts the number into 7 seg code movwf portb ; displays the value through Port B movlw b'1000' ; turns on correct display movwf porta ; retlw 0 ; returns DisplayMin movfw Minutes ; takes the number out of Minutes call _7SegDisp ; converts the number into 7 seg code movwf portb ; displays the value through Port B movlw b'0100' ; turns on correct display movwf porta ; retlw 0 ; returns _7SegDisp addwf PCL, f ; skips a certain number of instructions retlw b'11111110' ; 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 OneSec movfw Mark80 ; has 1/30th of a second passed? subwf TMR0, w ; btfss STATUS, A ; retlw 0 ; no, so returns movlw d'80' ; yes, so resets postscaler addwf Mark80, f ; decfsz Post30, f ; has 1 second passed? retlw 0 ; no, so returns bcf sec ; tells rest of program that 1 second has passed movlw d'30' ; resets first postscaler movwf Post30 ; retlw 0 ; returns ;============= ; Program Start : Start call Init ; sets things up Main call Display ; btfss portb, 0 ; tests for the start button goto Main ; not pressed so keeps looping Release call Display ; btfsc portb, 0 ; goto Release ; MainLoop call Timer ; timing subroutine call Display ; display subroutine call OneSec btfsc sec ; has 1 second passed? goto MainLoop ; no, so loops back btfss portb, 0 ; has stop button been pressed ? goto MainLoop ; no, so loops back bsf sec ; resets the sec bit Release2 call Display ; displays the finished time btfsc portb, 0 ; waits for button to be released goto Release2 ; Debounce call OneSec ; has one second passed? btfsc sec ; goto Debounce ; no, so loops back ResetLoop btfss portb, 0 ; yes, so tests reset button goto ResetLoop ; it isn't pressed, so loops back bsf sec ; resets the sec bit Release3 call Display ; btfsc portb, 0 ; waits for button to be released goto Release3 ; FinalLoop call OneSec ; btfsc sec ; has 1 second passed? goto FinalLoop ; no, so loops back goto Main ; loops back to the beginning END