I am having a mind blowing misbehaviour in my PIC16F1825. Basically I am using pin 3 (RA4) to toggle a LED using an Interrupt-on-Change. Problem is, although it toggles the led whenever I press the button (which is externally pulled up), after a second, the LED toggles again, which means that the interrupt routine was called again, and it shouldn't, even though I clear the interrput flag.
Here's the code (only function IOconfig_portA() and toggleLed() matter for the problem at hand:
#include <stdio.h>
#include <stdlib.h>
#include <PIC16F1825.h>
char temp=0;
void interrupt toggleLed() {
INTCONbits.GIE = 0;
if(INTCONbits.IOCIF == 1) {
temp = PORTA;
INTCONbits.IOCIF = 0;
LATC3 = ~LATC3;
for (int i = 0; i < 100000; i++);
}
INTCONbits.GIE = 1;
}
void CLOCKconfig() {
OSCCON = 0x6A; //Sets the internal oscillator fosc = 4 MHz
OSCSTAT = 0x00;
OSCTUNE = 0x00;
}
void IOconfig_portA() {
ANSELA = 0x00; // All ports set as DIGITAL
TRISAbits.TRISA4 = 1; // Set as input
//OPTION_REG &= 0x7F; // Clear bit 7, to enable the weak pull-up
//WPUA |= (1<<2); // Enable the WPU for RA2
CM1CON0 = 0x00;
CM1CON1 = 0x00;
IOCANbits.IOCAN4 = 1; // Generate Interrupt on Negedge
IOCAP = 0x00; // Disable Interrupt on Posedge
INTCON = 0x88; // Enable GIE and IoC interrupts
}
int main(int argc, char** argv) {
TRISC = 0;
CLOCKconfig();
ANSELC &= 0x00; // All bits on port C are set to Digital I/O's
TRISC &= 0x00; // All bits on Port C are set to Outputs
APFCON0 |= (1<<5); // Don't use special features on Pin RC3
APFCON1 |= (1<<2); // Don't use special features on Pin RC3
IOconfig_portA();
LATC |= (1<<3);
while(1) {
}
return (EXIT_SUCCESS);
}
Thanks in advance!
for (int i = 0; i < 100000; i++);
that has no place in an ISR! First rule of interrupts is the handlers should finish as quickly as possible and not block for long periods of time. Also theINTCONbits.GIE = ...
lines are unnecessary (it is done internally by the PIC when entering and exiting the ISR). \$\endgroup\$ – Tom Carpenter Nov 22 '15 at 16:48