-2

I'm new to PIC programming and I'm using MPLAb. I have a question regarding interrupt.. so What I want to do, when I push a button then I want to turn on LED 0, and if I release the button then turn on LED 1. I thought the code I wrote making sense but it didn't work.

Here is what happens. Let say the initial state of interrupt pin is low (0), when a button is pushed. Then the LED 0 is on, and when I release the button then LED 1 is on. When I push the button again, I expect LED 0 is on, but LED 1 stays on, and never change the state.

I added last line to see the state of interrupt pin, and once the interrupt is high, it never change it to low.. Can you please advise me what is my misunderstanding?

Thanks in advance!

Here is my code:

void interrupt ISR(void)
{

if(INTCONbits.INTF)
{
        nextLED = 1;
        LATC = Output_Code_Buffer[nextLED];
        __delay_ms(250);
}

else
{
        nextLED = 0;
        LATC = Output_Code_Buffer[nextLED];
        __delay_ms(250);
}

nextLED = INTCONbits.INTF + 2;

LATC = Output_Code_Buffer[nextLED];
__delay_ms(250);
}

// Interrupt Enable settings
INTCONbits.INTE = 1;
INTCONbits.TMR0IE = 1;          // Enable TMR0 interrupts
INTCONbits.TMR0IF = 0;          // Clear TMR0 interrupt flag
INTCONbits.GIE = 1;             // Enable global interrupts
  • 1
    `__delay_ms(250)` in an interrupt hanlder is a **very** bad idea. – too honest for this site Mar 31 '17 at 21:16
  • I understand that I should not write an interrupt that has long processing type. The purpose of this program is I try to understand how the interrupt works, so I wrote visual presentation output(LEDs). This is interrupt driven code, and main function is basically empty. I would appreciate if you can give me any suggestion. – Justin Junghee Kim Mar 31 '17 at 21:34

1 Answers1

0

You need to reset the interrupt flag in the ISR function or it will just keep triggering. Please read the datasheet, it should mention if this is necessary. So just add INTCONbits.INTF = 0; to the ISR and it should work as expected.

When setting up any peripheral or function of the mcu, you should go through the datasheet and use the description of the registers and what to set them. You'll also need to be careful with analogue ports, which often default to analogue instead of digital, causing interrupt not to fire as expected or causing unexpected interrupts. It's best to first setup the MCU config bits, set the TRIS and analogue selection registers (ANSELx or ANSELAx etc), then the registers for any peripheral you want to use. Then setup the interrupts, always reset all the interrupt flags you're going to use to start with a known state.

You also set TMR0IE = 1, which will do the same thing, trigger an interrupt. If you don't reset the TMR0 flag it will keep triggering, locking up your mcu or slow it down.

imqqmi
  • 423
  • 2
  • 9