what is the problem in this code?

Status
Not open for further replies.

tahboy

Newbie level 2
Joined
May 3, 2013
Messages
2
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Visit site
Activity points
1,294
I need to use external interrupt by push button on RB0
but i can't return back from interrupt.
this code can not return to main program after executing interrupt.
pleas can you help me
Code:
list      p=16F628A           ; list directive to define processor 
    #include <p16F628A.inc>       ; processor specific variable definitions 
  
  
   __CONFIG   _CP_OFF & DATA_CP_OFF & _LVP_OFF & _BOREN_OFF & _MCLRE_ON & _WDT_OFF & _PWRTE_ON & _HS_OSC 
  
;********************************************************************** 
reg1     equ 0x20 
reg2     equ 0x21 
reg3     equ 0x22 
w_temp           equ 0x23          
;*********************************************************************** 
  
start:    org     0x0000    
            goto    mainProg             ; go to beginning of program 
itsr:                  org       0x0004 
                        goto     intsup 
;**************** Interrupt rotine gos here **************** 
  
  
;************************************************************* 
  
mainProg:        movlw 0x07      ;turn off comparator(PORTA = i/o) 
                        movwf CMCON 
                        movlw   0x90      ;GIE – Global interrupt enable (1=enable) 
                        movwf   INTCON    ;INTE - RB0 interrupt enable (1=enable)& clear flag INTF   
  
                        bsf       STATUS,RP0  ;bank1 
  
                        movlw 0x3f 
                        movwf OPTION_REG 
  
                        movlw 0x00 
                        movwf TRISA 
                        movlw 0x01 
                        movwf TRISB 
                        bcf       STATUS,RP0  ;bank0 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
main:               movlw 0xff 
                        movwf PORTA 
                        call      delay500 
                        movlw 0x00 
                        movwf PORTA 
                        call      delay500 
                        goto     main 
  
;;;;;;;;;;;;;;;;;;;;;;;;;;; 
;;;;;;; delay500;;;;;;; 
delay500: 
            movwf w_temp 
  
            movlw   0x04  ;0x04 
            movwf   reg3 
  
L3:     movlw   0xff     ;0xff 
        movwf   reg2 
  
L2:     movlw   0xff     ;0xff 
            movwf   reg1 
L1:     decfsz  reg1 
        goto    L1 
        decfsz  reg2 
        goto    L2 
        decfsz  reg3 
        goto    L3 
        movf        w_temp,0 
            return    
;;;;;;;;;;;;;;;;;;;;;;; 
intsup:             
  
                        movlw 0x01 
                        movwf PORTA 
                        call      delay500 
                        movlw 0x02 
                        movwf PORTA 
                        call      delay500 
                        bcf       INTCON,INTF 
                        bsf       INTCON,INTE 
                        retfie                ;return to mainProg 
              END                       ; directive 'end of program'
 
Last edited by a moderator:

Hi,

If you look in the Mplab folder for the Templates folder and then for the 16F628A.Temp you will see an example of whats called ISR Context Saving.

When an Interrupt is detected, the current operation and relevant system registers must be Saved so after the ISR is complete you can correctly restore and return to where you left off in the main flow.
 

At a guess, you are trashing the W and STATUS regsters and maybe the bank selection bits in your interrupt routine.

As it looks like you are using MPLAB, I STRONGLY suggest you copy the template file "16F628ATEMP.ASM" and edit your own code into it. That file already includes the basic interrupt handler routines, including the code to preserve the W and STATUS registers.

I would also recommmend that you do not use delay routines inside interrupt routines. Generally interrupts are used when something needs priority attention over the normal flow of instructions and while in the ISR all other interrupts are disabled and will not be recognized. It may not make much difference in your simple code but in most applications it's best to get out of an ISR as quickly as possible.

Brian.
 

Basically your delay routine never comes out of loop.
Code:
;;;;;;; delay500;;;;;;; 
delay500: 
            movwf w_temp 
  
         movlw   0x04  ;0x04 
         movwf   reg3 
  
	     movlw   0xff     ;0xff 
         movwf   reg2 
         movwf   reg1  
	     movlw   0xff     ;0xff 

L1:     decfsz  reg1 
        goto    L1 
        decfsz  reg2 
        goto    L1 
        decfsz  reg3 
        goto    L1 
        movf        w_temp,0 
            return    
;;;;;;;;;;;;;;;;;;;;;;;

After changing to,

Code:
;;;;;;; delay500;;;;;;; 
delay500: 

         movlw   0x04  ;0x04 
         movwf   reg3 
  
         movlw   0xff     ;0xff 
         movwf   reg2 
         movwf   reg1  

L1:     decfsz  reg1 
        goto    L1 
        decfsz  reg2 
        goto    L1 
        decfsz  reg3 
        goto    L1 
            return    
;;;;;;;;;;;;;;;;;;;;;;;

Now it is rolling.
 

Attachments

  • led.rar
    1,005 bytes · Views: 58

thanks for all
Have written a new program has benefited from your adviceز
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…