|
|
View previous topic :: View next topic |
Author |
Message |
1953cub
Joined: 28 Jan 2014 Posts: 7
|
Interrupt service routine help |
Posted: Fri Jun 06, 2014 8:23 am |
|
|
Hi All,
I'm trying to use multiple serial interrupts and keep running into a problem of not returning from the ISR, it just hangs. I went back to the example in the manual which works but my test code just hangs. Can anyone point out what I'm missing ?
pic18f45K22
Version 4.141
This works fine, when a char is received it echos and and returns. pins a4 and a5 are hooked to an LEDs just so i can see it's back and looping in main.
Code: |
#if defined(__PCH__)
#include <18f45K22.h>
#device *=16
#endif
#fuses HSM,NOPLLEN,NOWDT,PUT,NOBROWNOUT,NOLVP //INTRC_IO
#use delay(clock=16000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS, stream=COM1)
#use rs232(baud=9600, xmit=PIN_D6, rcv=PIN_D7, ERRORS, stream=COM2)
#use rs232(baud=9600, xmit=PIN_D4, rcv=PIN_D5, ERRORS, stream=COM3)
#int_rda
void rda_isr(void)
{
char b;
b = fgetc(COM1);
fputc(b, COM1);
}
#int_rda2
void rda2_isr(void)
{
char c;
c = fgetc(COM2);
fputc(c, COM2);
output_low(PIN_A5);
}
//======================================
void main(void)
{
fprintf(COM1, "Hi there com1\n\r");
fprintf(COM2, "Hi there com2\n\r");
fprintf(COM3, "Hi there com3\n\r");
enable_interrupts(INT_RDA);
enable_interrupts(INT_RDA2);
enable_interrupts(GLOBAL);
while(1)
{
output_low(PIN_A4);
delay_ms(50);
output_high(PIN_A4);
delay_ms(50);
}
}
|
but if I change the int_rda2 isr to this (or most anything else) it sets the pin low (which turns the LED on) and hangs forever.
Code: |
#int_rda2
void rda2_isr(void)
{
output_low(PIN_A5);
}
|
The compiler manual states the compiler will automatically handle the return , etc. Can anyone give me a idea what is happening ?
thanks in advance |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Fri Jun 06, 2014 8:41 am |
|
|
It's all down to what triggers the interrupt.
INT_RDA2 is triggered _when there is a character waiting to be read_.
If you 'clear' the interrupt, without reading the character, it will set again immediately, since there is still 'a character waiting to be read'.
Hence:
Code: |
#int_rda2
void rda2_isr(void)
{
output_low(PIN_A5);
}
|
Will loop back and trigger forever, since the interrupt can't be cleared.
This has been described hundreds of times here.
It applies to any interrupt triggered by hardware things like this, that you have to clear the trigger source, before the interrupt can be cleared.
INT_TBE requires you to load a character to the transmit register
INT_RDA requires you to read a character from the serial
INT_RB requires you to read port B
etc. etc.. |
|
|
1953cub
Joined: 28 Jan 2014 Posts: 7
|
|
Posted: Fri Jun 06, 2014 9:19 am |
|
|
Ttelmah,
Ahhh, Makes perfect sense. I read things so many times I could't see the obvious !!
Thanks for your help !!! |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|