zhaniko93
New Member
Code:
; PROGRAM FUNCTION: A stop clock displaying the time in tenths of
; second, seconds, tens of seconds and minutes.
list P=16F84
include "c:\PIC\_inc\P16F84.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
;============
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.1 s 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 ;
; Subroutines:
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 second has 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 7-seg 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 7-seg 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 7-seg 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 7-seg code
movwf portb ; displays value through Port B
movlw b'0100' ; turns on correct display
movwf porta ;
retlw 0 ; returns
;=================================
Init clrf porta ; resets input/output ports
clrf portb ;
bsf STATUS, RP0
movlw b'0000' ; bits 0-3: 7-seg display
movwf TRISA ; control
movlw b'00000001' ; bits 1-7: 7-seg display code
movwf TRISB ; bit 0: start/stop button
movlw b'00000111' ; TMR0 prescaled by 256
movwf OPTION_REG
bcf STATUS, RP0
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 second has
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 second will be
movwf Mark250 ; counted
retlw 0 ;
_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 second has
subwf TMR0, w ; passed
btfss STATUS, Z ;
retlw 0 ; 0.1 second hasn’t passed - returns
movlw d'240' ; updates Mark240
addwf Mark240,f ;
incf TenthSec, f ; adds 1 to number of 0.1 second
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 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 ten minutes
btfss STATUS, Z ; has passed)
retlw 0 ;
clrf Minutes ; 10 minutes have passed, so resets
retlw 0 ;
;=================================
END
when simulating in proteus, errors occur:
Stack overflow executing CALL instruction;
PC (0x1010) is outside program memory for GOTO/CALL instruction;
write to PCL register results in a PC valua (0x1717) outside of program memory on PIC1684 device.
What's wrong?