Electronic – PIC18 High Priority Interrupt doesn’t Interrupt the Low one (xc8)

interruptsmplabxpicxc8

I was trying to learn and implement the priority property of interrupts on PIC18F46K22 uC. I use MPLABX and XC8 compiler.

In my code (transformed from a sample code), I have one external interrupt (INT1) and one USART receive interrrupt (RC1IF). External input is a LED driver and USART is a simple echo program driven by a PC terminal.

Some parts of the code are provided below, with comments.
Code builds succesfully. But with this "high-low" combination, when USART is active and program succesfully echos text to terminal, I cannot interrupt the transmission with external interrupt which has given by a pushbutton.

Here are ISR's.

void interrupt low_priority USB(void)
{

if (PIR1bits.RC1IF==1)  // check if receive interrupt has fired
{
    t = RCREG1;      // read received character to buffer


    // check if received character is not new line character
    // and that maximum string length has not been reached
    if ( (t != '\n') && (rcindex < STRLEN) )
    {
        rcbuf[rcindex] = t; // append received character to string
        rcindex++;          // increment string index
    }
    else
    {
        rcindex = 0;         // reset string index
        USART_puts(rcbuf);  // echo received string


        for(int x=0; x<STRLEN+1; x++){ //clear
                rcbuf[x] = 0;           // any leftover
            }                           // from
        RCREG1 = 0x00;                  // last
        TXREG1 = 0x00;                  // transmission
    }

    PIR1bits.RCIF = 0;      // reset receive interrupt flag
}
}

and

void interrupt high_priority inticik(void)
{
if(INTCON3bits.INT2IF==1)
{
    LATAbits.LA1 = ~LATAbits.LA1;
    __delay_ms(20);
}

INTCON3bits.INT2IF = 0;
}

This is the interrupt configuration function;

void interrupt_config(void)
{
 //interrupt main configuration
RCONbits.IPEN = 1;        // interrupt priority mode enabled, H or L interrupts
INTCONbits.GIE_GIEH = 1;  // high priority interrupts are enabled
INTCONbits.PEIE_GIEL = 1; // low priority interrupts are enabled

//pin interrupt 1&2 enable + priority assignments + edge selection
TRISBbits.TRISB2 = 1;
ANSELBbits.ANSB2 = 0;
INTCON3bits.INT1IE = 1; // int1 is enabled
INTCON3bits.INT2IE = 1; // int2 is enabled
INTCON3bits.INT1IP = 1; // int1 is high priority
INTCON3bits.INT2IP = 1; // int2 is high priority
INTCON2bits.INTEDG1 = 1;  // rising edge
INTCON2bits.INTEDG2 = 1;  // rising edge

//EUSART interrupt enable + priority assignments

PIE1bits.RC1IE = 1; //receive interrupt enabled
PIE1bits.TX1IE = 1; //transmit interrupt enabled
IPR1bits.RC1IP = 0; // receive is low priority
IPR1bits.TX1IP = 0; // transmit is low priority
}

And here is the main function.

int main(void)
{
TRISAbits.TRISA1 = 0;
LATA = 0x00;
interrupt_config();

USART_init();

USART_puts("Init complete!\n");

//main loop
while(1)
{
    Sleep();
}

return 0;
}

Other parts of the code such as USART functions and "config.h" conf. bit headers are not provided because of irrelevancy.

Thank you.

Edit

I forgot to mention, when i change the,

"void interrupt low_priority USB(void)"

statement to

"void interrupt high_priority USB(void)"

program succesfully works and echoes on terminal. But when set as "low_priority", USART module does not work on terminal. Only external interrupt runs successfully.

Best Answer

Altough I'm not sure why, this solved my problem.

From PIC18F46K22 Datasheet

At Power-On-Reset, ADON bit is cleared, which means it disables the A/D converter by default, right? This means whether or not I disable the A/D converter, it is disabled automatically.

ADCON0bits.ADON = 0;

But, I did add this line to my configuration and it worked, now both external (high priority) interrupt and USART (low priority) interrupt works at the same program.

It is a solution, but i still wonder why it worked.