Try clearing INTEDG bit of OPTION_REG register. From the datasheet page 30(32):
INTEDG: Interrupt Edge Select bit
1 = Interrupt on rising edge of INT pin
0 = Interrupt on falling edge of INT pin
When PORTD is high, does the LED turn ON or OFF?
Also check out switch contact bounce. Here is a link on it and how to debounce. To check it is the contact bounce causing the thing that is seen as a "problem", add a delay of 500msec or 1 sec after PORTD=0xff;
in the interrupt routine. If the port is high, your problem is contact bounce if the above suggested solution doesn't solve your problem -that is clearing INTEDG bit.
You don't need that GIE=1;
in the last line of the interrupt block.
I have no experience with Hi-Tech C compiler. Chances are low but try doing INTE=1;
before GIE=1;
in the main function.
Edit
Try changing void intMain()
to void interrupt intMain()
. According to
HI-TECH C® for PIC10/12/16 User’s Guide 3.8 INTERRUPT HANDLING IN C (Page 86) Link
Edit After Second Question
According to the same manual mentioned above page(299):
To produce an infinite loop, use for(;;).
You are trying to assign an 'integer' value to a 'character' variable as I quoted below. Define variable i as unsigned char. Compiler should take care of this, but it is worth trying.
...
int i,k;
...
PORTD=i;
...
You'll find the information you need in the compiler's manual: MPLAB C18 C COMPILER USER'S GUIDE.
From page 37 of the user's guide:
MPLAB C18 does not automatically place an ISR at the interrupt vector. Commonly, a GOTO
instruction is placed at the interrupt vector for transferring control to the ISR proper. For example:
void lowPriorityISR(void);
#pragma code low_vector=0x18
void interrupt_at_low_vector(void) {
_asm GOTO lowPriorityISR _endasm
}
#pragma code
#pragma interruptlow lowPriorityISR
void lowPriorityISR() {
}
When implementing a high priority ISR, you cannot use the interrupthigh
pragma as you would expect. You'll have to use the interrupt
pragma instead, as is described here.
If you can change the compiler: using interrupts is easier in the Microchip XC8 or HI-TECH PICC compilers.
Best Answer
You are correct, PICs before PIC18 didn't give a way to change the top of the stack.
You are asking one of the classic questions which has caused me to avoid PIC's, and especially everything pre-PIC18 like the proverbial plague. wikipedia PIC stack
It is a perfectly normal thing to do, providing you understand what you are doing, and not illogical. It is a core mechanism for multi-tasking, or muti-process operating systems.
The normal reason for doing something like that is to do an operating system (OS) context switch. This would enable software to create the illusion of many concurrent processes. When an interrupt has been serviced, the OS might not want to return to the interrupted process, but may need to run a different piece of code. Part of the mechanism is to change the stack pointer to the stack of a different process, and then execute the return from interrupt.
See AN818 Manipulating the Stack of the PIC18 Microcontroller for how to change the return address. Note it is a PIC18 document.
Sadly AFAICT that PIC is not capable of doing that.
An inferior alternative technique is to have your main control loop check a variable to detect when it needs to get out, and execute that other code.
Is there a way to force a RESET?