Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] Interrupt routine not returning to main loop (PIC16F84A Assembly)

Status
Not open for further replies.

guanyu

Newbie level 2
Joined
May 25, 2012
Messages
2
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,298
Hello.

Why is it that whenever the ISR is executed in my code, it does not seem to return to the main loop?

Code:
	#include "p16f84a.inc"
	__CONFIG  _HS_OSC&_PWRTE_ON&_WDT_OFF&_CP_OFF
	
cblock 0X20
	d1
	d2
	d3
	TEMP
	endc
	
org 0x00
	goto main
	
org 0X04
	goto ISR

ISR
	bcf INTCON, GIE
	movfw PORTA
	movwf TEMP
	bsf PORTA, 1
	call Delay
	bcf PORTA, 1
	call Delay
	bsf PORTA, 1
	call Delay
	bcf PORTA, 1
	call Delay
	
	movfw TEMP
	movwf PORTA
	movlw 0x00
	movwf PORTB
	bcf INTCON, INTF
	bsf INTCON, GIE
	retfie
	
main
	
	BSF STATUS,RP0
	BCF STATUS,RP1
	movlw 0x00
	movwf TRISA
	movlw 0xFF
	movwf TRISB
	BCF STATUS,RP0
	clrf PORTA
	clrf PORTB
	
	BSF INTCON, GIE
	BSF INTCON, INTE
	BCF INTCON, INTF
	
loop
	
	bsf PORTA, 0
	call Delay
	bcf PORTA, 0
	call Delay
	goto loop
	
Delay
			
	movlw	0x03
	movwf	d1
	movlw	0x18
	movwf	d2
	movlw	0x02
	movwf	d3
	
Delay_0
	decfsz	d1, f
	goto	$+2
	decfsz	d2, f
	goto	$+2
	decfsz	d3, f
	goto	Delay_0

	goto	$+1
	goto	$+1
	goto	$+1
	
	return
	
	end

I intended my code to function like this: RA0 led will continuously blink and whenever a bit change occurs in RB0, the RA0 LED will stop blinking and the RA1 LED will blink two times and return to wherever it left on the main loop. But the problem is that after blinking two times, the RA0 led does not blink anymore.

Can anyone help me?
 

You are using the same subroutine (Delay) inside and also outside of the interrupt, and this is not reentrant. Use different delay subroutines.
 
  • Like
Reactions: guanyu

    guanyu

    Points: 2
    Helpful Answer Positive Rating
Hello.

Why is it that whenever the ISR is executed in my code, it does not seem to return to the main loop?

[
I intended my code to function like this: RA0 led will continuously blink and whenever a bit change occurs in RB0, the RA0 LED will stop blinking and the RA1 LED will blink two times and return to wherever it left on the main loop. But the problem is that after blinking two times, the RA0 led does not blink anymore.

Can anyone help me?


Hi,

You have a double whammy here..


When you are in your Loop most of the time it will be executing a delay routine.

RB0 activates an ISR and you start that routine, which again is mainly delay rotuines.

When the ISR is finished it returns to the delay routine it was doing, well thats your theory..

See the Problems ...??


When a ISR is activated you must do whats called Context Saving, its covered in the datasheets etc.

If you Open, Mplab/MPASM/Templates/pic16f84a you will see an example of the code you need.

That only covers the key registers like W and Status.
As you are using Delay with its d1,d2,d3 registers they also need to be saved and restored otherwise your ISR simple overwrites them.

Perhaps simpler to write another Delay specially for the ISR which uses different names registers like S1,S2,S3

'
When changing Banks, instead of using the 'BCF STATUS,RPx' simply use the Directive ' banksel TRISA' and banksel 0 to return to bank 0
 
  • Like
Reactions: guanyu

    guanyu

    Points: 2
    Helpful Answer Positive Rating
Also, you dont need to clear and set GIE in the interrupt, that is done automatically.
You should also save and restore the STATUS register in the interrupt.
If using MPLAB, use MPLAB SIM to step through the code.
 
  • Like
Reactions: guanyu

    guanyu

    Points: 2
    Helpful Answer Positive Rating
Better still, start with the code template provided by Microchip then add your program to it. You absolutely must save the status register and W register as you enter the interrupt or their values will be different before and after the interrupt was called. The template will do this for you. If you are using MPLAB, look in "C:\Program Files\Microchip\MPASM Suite\Template\Code" (assuming you installed on drive C:) and copy it's contents into your program, then add your routines into it as appropriate.

Brian.
 
  • Like
Reactions: guanyu

    guanyu

    Points: 2
    Helpful Answer Positive Rating
When you are in your Loop most of the time it will be executing a delay routine.

RB0 activates an ISR and you start that routine, which again is mainly delay rotuines.

When the ISR is finished it returns to the delay routine it was doing, well thats your theory..

See the Problems ...??

I see... It did not occur to me that the ISR will most likely execute on the Delay subroutine, which is the same one that I used on the ISR itself. The problem was fixed by adding a new delay routine for ISR and saving my W and status registers at the start of ISR, which you guys have suggested.

Thanks, I learned a lot from you guys.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top