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