Electronic – Interrupts with 16f887 and MPLAB

interruptspic

need some help with interrupts and the 16f887.

I'm using MPLAB and writing my code in C. I am using the 44-pin demo board from Microchip. There is a push button wired to RBO/INTO which is normally high, and pulled low when the button is pressed.

I've already verified that the input and push button are working, however I dont think I'm setting up the interrupt properly. When the button is pressed, I'm try to turn PORTD on, and when the interrupt returns, PORTD is turned off.

However when I run the code, PORTD turns on right away. Any ideas?

#include <pic16f887.h>
#include <htc.h>

__CONFIG (DEBUG_ON, LVP_OFF, FCMEN_OFF, IESO_OFF, BOREN_OFF,
    CPD_OFF, CP_OFF, MCLRE_ON, WDTE_ON, FOSC_INTRC_NOCLKOUT, BOR4V_BOR21V);


void intMain() {
PORTD=0xff;
INTF=0;
GIE=1;
}


void main(void){

 TRISB = 0xff;        //set PORTB as inputs
 TRISD = 0x00;        // Set PORTD as an Output
 ANSEL = 0x00;
 ANSELH = 0x00;
 GIE=1;
 INTE=1;
 PORTD=0x00;
 while(1)
 {
     PORTD=0x00;

 }
}

EDIT

I've updated my code based on some suggestions below. Here is the current code. I've written it so that, when the ISR is called, port D will count from 0 to 256, then clear and exit the ISR. I've written in a trap to stop the ISR from exiting and keep it in an endless loop. When i start the controller, the port counts to 256, clears and restarts repeatedly.

#include <pic16f887.h>
#include <htc.h>

__CONFIG (DEBUG_ON, LVP_OFF, FCMEN_OFF, IESO_OFF, BOREN_OFF,
    CPD_OFF, CP_OFF, MCLRE_ON, WDTE_ON, FOSC_INTRC_NOCLKOUT, BOR4V_BOR21V);

void interrupt intMain() {
int i,k;
i=0;
k=0;
while(i<256)
{
    while(k<3000) //delay
        k++;
    i++;
    k=0;
    PORTD=i;
}
while(1){} //trap
//INTF=0;
}

void main(void){

 TRISB = 0xff;        //set PORTB as inputs
 TRISD = 0x00;        // Set PORTD as an Output
 ANSEL = 0x00;
 ANSELH = 0x00;
 INTE=1;
 GIE=1;
 INTEDG=0;
 nRBPU=0;
 WPUB0=1;
 PORTD=0x00;
 while(1)
 {
     PORTD=0x00;

 }
}

Best Answer

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;
...