3
\$\begingroup\$

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.

\$\endgroup\$
4
  • 1
    \$\begingroup\$ Regardless of the answer to your (good) question you shouldn't delay in an interrupt. Set a flag and delay elsewhere in the main program. \$\endgroup\$ Commented May 9, 2015 at 19:37
  • \$\begingroup\$ Are you using INT1 or INT2? The intro text says INT1, the code initialises both and the interrupt uses INT2. \$\endgroup\$ Commented May 9, 2015 at 19:38
  • \$\begingroup\$ Both INT1 and INT2 pins also have a comparator which I dint see you disabling. All analogue functions need disabling to use a pin as a digital input. \$\endgroup\$ Commented May 9, 2015 at 19:41
  • \$\begingroup\$ Thanks for the comment. I am using INT1 for my purpose, INT2 was just there for further applications, I will disable it and try again now. Also, I assume you mentioned clearing ANSELB register bits by disabling the analogue functions, or am I wrong? At the definition of ANSELB reg., it says "digital input buffer is enabled" in datasheet. Or is there something else to change? \$\endgroup\$ Commented May 10, 2015 at 12:58

1 Answer 1

1
\$\begingroup\$

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.

\$\endgroup\$

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.