0
\$\begingroup\$

I'm currently working on a countdown timer project.I used PIC18F452 microcontroller for my project. I compiled the code in mplab and it has succesfully been builtHowever in proteus, the countdown timer seems to be working until a certain point and then it will reset. In the simulation, it said that the stack overflow is forcing the device to reset.

The diagram of the circuit: enter image description here

And here is the code:`

#include<p18f452.inc>
radix dec
bin     set 0x00
bcdH    set 0x01
MINUTE  set 0x03
SECOND  set 0x04
FXMin   set 0x06
FXSec   set 0x07
START   set 0x08

org 0x00
    goto init
org 0x08
    goto interrupt
org 0x18
    goto interrupt

init    movlw   0x07
        movwf   ADCON1
        setf    TRISB
        clrf    TRISC
        clrf    TRISD

;setting interrupt
    bcf INTCON, INT0IF
    bsf INTCON, INT0IE
    bcf INTCON3, INT1IF
    bsf INTCON3, INT1IE
    bcf INTCON3, INT2IF
    bsf INTCON3, INT2IE
    bsf INTCON3, INT2IP

;filling TMR0 value
    movlw   0x06
    movwf   T0CON
    movlw   0x67    
    movwf   TMR0H
    movlw   0x68
    movwf   TMR0L
    bcf INTCON, TMR0IF
    bsf INTCON, TMR0IE
    bsf INTCON2, TMR0IP
    bsf RCON,   IPEN
    clrf    PORTB
    clrf    PORTC
    clrf    PORTD
    clrf    CCP1CON
    bsf T0CON, TMR0ON

loop    bsf INTCON, GIE
        bsf INTCON, GIEL
        bsf INTCON, GIEH

show    movff   FXMin, PORTD 
        movff   FXSec, PORTC
        bra loop

interrupt   btfsc   INTCON, INT0IF
            bra int00
            btfsc   INTCON3, INT1IF
            bra int01
            btfsc   INTCON3, INT2IF
            bra int02

checkstart  btfsc   INTCON, TMR0IF
            bra inttmr0


exit    retfie

int00   bcf    INTCON, INT0IF
        incf       MINUTE
        movlw    60
        cpfseq     MINUTE
        bra    calcBCD
        clrf       MINUTE
        bra    calcBCD

int01   bcf     INTCON,INT1IF
        setf          START 
        bra           checkstart 

int02   bcf     INTCON3,INT2IF
        clrf          MINUTE
        clrf          SECOND 
        clrf          FXMin
        clrf          FXSec 
        clrf          START
        bra           calcBCD

inttmr0 bcf INTCON, TMR0IF
        movlw   0x06    ;0x47
        movwf   T0CON
        movlw   0x90    ;0x00
        movwf   TMR0H
        movlw   0x00
        movwf   TMR0L
        bsf     T0CON, TMR0ON
        movlw   0xFF
        cpfseq  START 
        bra     calcBCD
        bra     COUNTDOWNLOOP

COUNTDOWNLOOP nop

CHECK   movlw   0x00 
        cpfseq  SECOND
        bra DECSEC
        bra CHECKMIN 


DECSEC  decf    SECOND
        bra     calcBCD


CHECKMIN movlw  0x00 
        cpfseq  MINUTE
        bra DECMIN
        bra calcBCD;

DECMIN  decf    MINUTE
        movlw   60
        movwf   SECOND 
        bra     DECSEC

calcBCD movff   MINUTE, bin
        call    bin2bcd
        movwf   FXMin
        movff   SECOND, bin
        call    bin2bcd
        movwf   FXSec
        bra     show
        retfie

bin2bcd clrf    WREG             
        clrf    bcdH                  
        bsf     bcdH,0     

bcd_lp  rlcf    bin     
        addwfc  WREG
        daw                    
        rlcf    bcdH            
        bnc     bcd_lp  
        return



return

end



`   
\$\endgroup\$
3
  • 2
    \$\begingroup\$ You don't expect us to read the uncommented assembly code and understand what it is doing, do you? \$\endgroup\$
    – Eugene Sh.
    Commented Sep 7, 2016 at 16:09
  • 1
    \$\begingroup\$ @EugeneSh.: Why not? I guess you must be a little out of practice ... :-) (One of the advantages of being an old f*rt like me!) \$\endgroup\$
    – Dave Tweed
    Commented Sep 7, 2016 at 17:01
  • 1
    \$\begingroup\$ @DaveTweed I remember being able to read a memory dump of VAX11 back in the university and understand what it is doing. But.. come on, I am not missing it. \$\endgroup\$
    – Eugene Sh.
    Commented Sep 7, 2016 at 17:04

1 Answer 1

2
\$\begingroup\$

In your interrupt handler — specifically in the calcBCD code — you have an unconditional branch to show, which is non-interrupt code, and this makes the retfie instruction following it unreachable. This appears to be the only exit path for nearly all paths through the interrupt handler (except for those that get through to checkstartexit), and this is what is causing your stack to eventually overflow.

This sort of bug would be a lot harder to create in the first place if you were to adopt a more structured approach to controlling the flow through your code.

\$\endgroup\$
1
  • \$\begingroup\$ .... or a higher level programming language! \$\endgroup\$ Commented Sep 7, 2016 at 19:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.