CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Interrupt service routine help

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
1953cub



Joined: 28 Jan 2014
Posts: 7

View user's profile Send private message

Interrupt service routine help
PostPosted: Fri Jun 06, 2014 8:23 am     Reply with quote

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: 19448

View user's profile Send private message

PostPosted: Fri Jun 06, 2014 8:41 am     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Jun 06, 2014 9:19 am     Reply with quote

Ttelmah,

Ahhh, Makes perfect sense. I read things so many times I could't see the obvious !!

Thanks for your help !!!
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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