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

Handling Multiple Interrupts...

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



Joined: 05 Aug 2006
Posts: 52

View user's profile Send private message Visit poster's website AIM Address MSN Messenger

Handling Multiple Interrupts...
PostPosted: Tue Sep 26, 2006 12:08 pm     Reply with quote

Hi,

I was reading somewhere about the "Fast" and "High" options for interrupts but I'm planning on implementing a system on a 16f648A that will use the hardware UART RX interrupt and TMR1.

1) I would *like* the TMR1 interrupt to override the RX interrupt, i.e. say the RX causes and interrupt and TMR1 overflows, it'll put the initial PC to the stack, on top the point in the RX isr and service TMR1, and pop 'em in order...any ideas on this?

Note: In th event I do *not* want this from happening how can I prevent it, i.e. force GIE=0 inside each interrupt?

2) How does one initialise the TMR1 interrupt? Will try and figure this out tomorrow.

3) I was reading this on the FAQ:

Quote:
Due to the limited hardware stack of the PIC a limitation of the CCS compiler is the disability to use recursion in functions. This drawback will affect customers if they try to call a function in an interrupt that is also called outside of an interrupt. When you see this warning message, the compiler is letting you know that you are calling a function inside an interrupt that is also called outside of the interrupt. To prevent accidental recursion the compiler will disable interrupts when you call that specific function outside of that interrupt.


Seems that this will be directed by the compiler - just thought about it, and it does affect me so no worries. Worst case, I can duplicate the functions at the expense of ROM...if needed.

Cheers,
Mike
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Sep 26, 2006 12:24 pm     Reply with quote

Quote:
I would *like* the TMR1 interrupt to override the RX interrupt,

1. Use the #priority statement to give priority to the Timer1 interrupt.

2. Test for the timer interrupt while you're inside the #int_rda isr.
Check the TMR1IF bit. If it's set, then a Timer1 interrupt occurred after
the interrupt dispatcher had already vectored you to the #int_rda isr.
Then execute some (presumably short) code to handle the Timer1
interrupt and then clear the TMR1IF bit. Then handle serial port.

Example:
http://www.ccsinfo.com/forum/viewtopic.php?t=906
Scroll down to the #int_ccp isr code. In that code, I check to see
if a Timer1 interrupt has occurred, and if so, I handle it right there.
bsodmike



Joined: 05 Aug 2006
Posts: 52

View user's profile Send private message Visit poster's website AIM Address MSN Messenger

PostPosted: Tue Sep 26, 2006 1:11 pm     Reply with quote

Thanks for that Smile

I was just thinking of something else, rather than letting my TMR1 give me a 13ms delay [(1/(Fosc/4)) * 2^16 = (4/Fosc) * 2^16 = ~13msec] what if I set TMR1H:TMR1L = 2^16 - 5000, i.e. 5000*(4/Fosc) = 1msec.

Now this would mean I'd need to set TMR1H:TMR1L = 60536 or 0xEC78, so would writing like this work:

TMR1H = 0xEC;
TMR1L = 0x78;

This in in ref to the 16f648/877 and both datasheets state they these registers are readable and writeable, however, they advise to first STOP the timer before writing to it. This can be done at the init() and inside the ISR for the next iteration, as it would be stopped inside the ISR.

Cheers!
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Sep 26, 2006 4:11 pm     Reply with quote

Quote:
as it would be stopped inside the ISR.

The timer is not automatically stopped inside the isr. You would have
to put in a line of code to do that.

Quote:
so would writing like this work:
TMR1H = 0xEC;
TMR1L = 0x78;

CCS has a function to load timer1. It's called set_timer1().
Here's the code from the .LST file (compiled for a 16F877):
Code:

...... set_timer1(60536);
0016:  MOVLW  EC
0017:  MOVWF  0F   // TMR1H
0018:  MOVLW  78
0019:  MOVWF  0E  // TMR1L
bsodmike



Joined: 05 Aug 2006
Posts: 52

View user's profile Send private message Visit poster's website AIM Address MSN Messenger

PostPosted: Tue Sep 26, 2006 4:53 pm     Reply with quote

Thanks a lot for your help, simply awesome Smile

I'll just initialise the timer to 60536 as the ISR is exiting, but while in the ISR it can't cause another interrupt as GIE would be disabled.

I'm just used to the regular way of writing to the registers by hand rather than using the inbuilt libraries...
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