I have a problem with my interrupt and I don't know why. I want to use an interruption each time I receive a data from my RX port. So, I used the interrupt on the port RX of my microcontroller. My problem is, I can detect an interruption but I am locked into the interruption. I'm locked into like a while(1)
. Any idea?
This is my test code:
//Functions//
void interrupt SerialRxPinInterrupt(void);
int main(int argc, char** argv)
{
//Variables//
unsigned char UARTConfig = 0, baud = 0;
//Toggle led//
TRISAbits.RA1=0; //output
//Configuration internal clock to 8Mhz//
OSCCONbits.IRCF0 = 1;
OSCCONbits.IRCF1 = 1;
OSCCONbits.IRCF2 = 1;
/*UART PINS*/
TRISCbits.RC6 = 0; //TX pin set as output
TRISCbits.RC7 = 1; //RX pin set as input
//UART Configuration//
UARTConfig = USART_TX_INT_OFF & USART_RX_INT_ON & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_BRGH_HIGH ;
baud=51; //Formula 16(X+1) = Fosc/Baud Rate
OpenUSART(UARTConfig,baud);
//Interrupt configuration//
RCIF = 0; //reset RX pin flag
RCIP = 0; //Not high priority
RCIE = 1; //Enable RX interrupt
PEIE = 1; //Enable pheripheral interrupt (serial port is a pheripheral)
ei(); //(INTCONbits.GIE = 1)
while(1)
{
LED=1;
}
return (EXIT_SUCCESS);
}
void interrupt SerialRxPinInterrupt(void)
{
LED=0;
//check if the interrupt is caused by RX pin
if(PIR1bits.RCIF == 1)
{
RCIF = 0; // clear rx flag
}
}
-
\$\begingroup\$ If you are receiving data continuously, so the interrupt is triggered for each received byte, so it might seem to you that you are "locked" there.. \$\endgroup\$Eugene Sh.– Eugene Sh.2015年07月29日 16:38:59 +00:00Commented Jul 29, 2015 at 16:38
-
\$\begingroup\$ Are you sure you are entering that loop? It has been a while since I have used Microchip's 8 bit products, but don't you need additional compiler __ISR, etc? Or did you omit that stuff for this question? \$\endgroup\$justing– justing2015年07月30日 01:10:12 +00:00Commented Jul 30, 2015 at 1:10
2 Answers 2
The UART receive flag is sticky meaning that until the condition that triggered the interrupt is removed, clearing the flag in software will not clear it in hardware. You must read the receive register to clear the flag or before the flag can be cleared.
The following snipet is from the data sheet, interrupt section.
RCIF: EUSART Receive Interrupt Flag bit
1 = The EUSART receive buffer, RCREG, is full (cleared when RCREG is read)
0 = The EUSART receive buffer is empty
You have to clear your buffer .
void interrupt SerialRxPinInterrupt(void)
{
LED=0;
//check if the interrupt is caused by RX pin
if(PIR1bits.RCIF == 1) && (PIE1bits.RCIE == 1)
{
RCIF = 0; // clear rx flag
data=RCREG;
CommReceiveFin:
}
}
-
\$\begingroup\$ Welcome to EE.SE O.Blue. Great, useful, first post! -- Could you add maybe 1 line about why not clearing the buffer caused the lockup/infinite loop in the original code, for the sake of making the answer more 'complete?' :-) \$\endgroup\$Robherc KV5ROB– Robherc KV5ROB2016年02月18日 15:37:09 +00:00Commented Feb 18, 2016 at 15:37