Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

PIC16F84A Problem (stack overflow)

Status
Not open for further replies.

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?
 
but PIC16F84A has 8 level stack and I use only 2, so there is no overflow
 
but PIC16F84A has 8 level stack and I use only 2, so there is no overflow

You are allocating GPR's in SFR space - it's going to trash things seriously - GPR's don't start until 0x0C.

You also shouldn't reallocate porta and portb.

For a third thing, why the ORG 0x1FF at the start? - it looks like that file is from a different even older device, and hasn't been correctly moved to the 16F84.
 
isn't ORG 0x1FF needed? where does PIC automatically start executing from address 0x00?
 
isn't ORG 0x1FF needed? where does PIC automatically start executing from address 0x00?

The program memory starts at 0x0000 and the users registers at 0x0c.
Dont use registers less than address 0x0c for your program, they are SFR's

EDIT:
Use ORG at 0x0000
 
Last edited:
Status
Not open for further replies.

Latest threads

Back
Top