If your interrupts were working, you would have a hard time seeing the LED flash since as soon as you exit the interrupt routine you are back in h: which turns it right back on.

But your interrupts aren't working. You are confusing the interrupt enable INT0IE (INTCON,4) with the flag that says that the interrupt has occurred INToIF(INTCON,1) . You need to enable the interrupt then check INToIF in the interrupt routine and clear it when you process the interrupt.

You really need to STOPdeclaring your own lower case names for SFRs that have already been defined in P18F4520.inc. Your code should use the pre-defined names only and in the correct upper case. Things like intcon,4 are confusing and won't tell you what's going on like INTCON,INT0IE will. Both of those reference the same bit but the latter (correct) one tells you what's happening and it should be apparent that you are accessing the wrong bit in INTCON from looking at the source.

The OP must be reading the Pic programming books the likes of written by David Benson, although usefull, D.B. insists on declaring in lower case the appropriate registers used in the program without the use of the .INC file.
Max.

The OP must be reading the Pic programming books the likes of written by David Benson, although usefull, D.B. insists on declaring in lower case the appropriate registers used in the program without the use of the .INC file.
Max.

Click to expand...

Sounds like Mr. Benson should be avoided at all costs if the price of useful programming ideas is a big bag of bad habits. Thanks for the tip.

If your interrupts were working, you would have a hard time seeing the LED flash since as soon as you exit the interrupt routine you are back in h: which turns it right back on.

But your interrupts aren't working. You are confusing the interrupt enable INT0IE (INTCON,4) with the flag that says that the interrupt has occurred INToIF(INTCON,1) . You need to enable the interrupt then check INToIF in the interrupt routine and clear it when you process the interrupt.

You really need to STOPdeclaring your own lower case names for SFRs that have already been defined in P18F4520.inc. Your code should use the pre-defined names only and in the correct upper case. Things like intcon,4 are confusing and won't tell you what's going on like INTCON,INT0IE will. Both of those reference the same bit but the latter (correct) one tells you what's happening and it should be apparent that you are accessing the wrong bit in INTCON from looking at the source.

Good luck.

Click to expand...

OK, I rewrite the program with correct sfr names but it still did not work. why is that?
here is the new code

You don't have to make EVERYTHING upper case - just use the pre-defined names in the .inc file which happen to be upper case (and MPASM is case-sensitive). So your labels, etc. can be mixed case and opcodes lower case if you prefer.

If your interrupts were working, you would have a hard time seeing the LED flash since as soon as you exit the interrupt routine you are back in h: which turns it right back on.

But your interrupts aren't working. You are confusing the interrupt enable INT0IE (INTCON,4) with the flag that says that the interrupt has occurred INToIF(INTCON,1) . You need to enable the interrupt then check INToIF in the interrupt routine and clear it when you process the interrupt.

Click to expand...

. Remember that the interrupt ENABLE turns the interrupt on and off. The interrupt FLAG is set by some event and cleared by the program when that event is serviced. Your interrupt code should clear the flag by bcf INTCON,INT0IF.

Your input won't work because you haven't initialized ADCON1. This was covered in your other thread on this here.

WIth PBADEN=OFF, PORTB is digital at power up so you don't need to worry about ADCON1 for PORTB.
How do you know you are not getting the interrupt? The LED will flash faster than you can see it unless you are single stepping the code - are you?

I might try something like this for a test. Turns on the LED once then if the interrupt happens, it turns it off, verifying the interrupt.
Keep in mind that INT0 will interrupt on the falling edge of RB0 - change that in INTCON2 if you need to.

When simulating in protues, step by step, the instruction which is being executing is highlighted and it did not go to ISR so that i thought it was not getting the interrupt. But I was wrong.
Now i have a idea about how it works. Thank you very much for your help.

By the way can we put the ISR in the Interrupt vector table's location, 0008h ? Without using 200h for that.

When simulating in protues, step by step, the instruction which is being executing is highlighted and it did not go to ISR so that i thought it was not getting the interrupt. But I was wrong.
Now i have a idea about how it works. Thank you very much for your help.

By the way can we put the ISR in the Interrupt vector table's location, 0008h ? Without using 200h for that.

Click to expand...

You're welcome. If you are using the non-priority interrupt mode (default), there is only one interrupt vector at 0008h and yes, you can put the whole routine right there. Just keep in mind that if you change to the priority mode, you'll have the second vector at 0018h and you would then have to jump around that. As it is, its OK. You also don't need to ORG the main routine at anything. Just put it after the interrupt routine and the assembler will locate it for you. Like this:

Code (Microchip Assembler):

#include <p18F4520.inc>

CONFIG OSC=HS , WDT=OFF , LVP=OFF , PBADEN=OFF

;************************************************************

ORG0H

goto Main ; jump past fixed location of ISR

;********************** INTERRUPT ROUTINE *****************

ORG0008H

btfssINTCON,INT0IF ;INT0?

bra IRQexit ;no, exit the ISR at a single point

BCFPORTD,0

BCFINTCON, INT0IF ;clear int0 flag

IRQexit:

RETFIE;return from isr

; **************************MAIN PROG*******************

; This will be located right after the IRQ routine...

Main:

BCFTRISD,0;output

BSFTRISB, INT0 ;into = input

BSFPORTD,0; just ONCE for now

BSFINTCON, INT0IE ;enable int0 interrupt

bcfINTCON,INT0IF ; clear the flag then..

BSFINTCON, GIE ;global int enable

H:

nop; let interrupt happen

nop; iff LED turns OFF, its working

bra H

END

Note the changes. Also note that in the ISR, everything goes to a single exit point. You don't have any context saving in the ISR which normally is required (but not here since none of the instructions change W, STATUS, BSR etc). Eventually you'll have to do that. You can use the fast return stack on the 4520 if you do this:

Code (Microchip Assembler):

;********************** INTERRUPT ROUTINE *****************

ORG0008H

call fixIRQ,FAST ; 'FAST' call to re-push W,STATUS,BSR

fixIRQ:

pop; pop the stack to restore to original value

btfssINTCON,INT0IF ;INT0?

bra IRQexit ;no, exit the ISR at a single point

BCFPORTD,0

BCFINTCON, INT0IF ;clear int0 flag

IRQexit:

RETFIE FAST ;return from isr, restore W,STATUS,BSR

The dummy call is to ensure that W,STATUS,BSR got properly saved - its a bug in the chip - see the errata for the 4520. Note that anything else you use in the ISR will have to be saved before you use it then restored just before exiting the ISR. That's why I used the single exit point. That's where you would restore any saved context.

Actually, you don't need interrupts to do something like making an LED follow an input but presumably you are getting your feet wet so carry on!

EDIT: This would be a good time to point out that on an 18Fxxxx PIC, you always want to do single bit outputs (bcf/bsf) on the LATx registers, not on PORTx. This is also true for any read-modify-write operation that operates on IO. Use as ANDWF LATx,F not ANDWF PORTx,F
For consistancy, always do inputs on PORTx, outputs to LATx.
Microchip also recommends (as do I) that you don't use single bit operations on the TRIS registers either. Figure out what the whole 8 bits will be and do something like this for each port: