View previous topic :: View next topic |
Author |
Message |
myheadhurts
Joined: 08 Dec 2004 Posts: 7
|
Interrupt levels and priorities |
Posted: Wed Dec 08, 2004 11:09 am |
|
|
I seem to be struggling a little in guaranteeeing the level assigned to interrupts. I am using ext1 and need it to be in the high level interrupts section, and rda that needs to be in the low level section. It looks like the ext1 interrupts is not interrupting the rda interrupt whilst it is running.
the #priority command does not seem to fix it and i don't seem able to correctly #org the memory for use at adderss 0x08 to make sure the interrupt is in the high level. Any thoughts or solutions.
Ps. i'm going round the bend on this one |
|
|
myheadhurts
Joined: 08 Dec 2004 Posts: 7
|
|
Posted: Wed Dec 08, 2004 11:10 am |
|
|
oh yeah, i forgot to mention, i am using a PIC18F252 |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Wed Dec 08, 2004 11:39 am |
|
|
Did you tell the ext1 to be an #int_fast ? Post some code. We cannot tell you the problem without seeing if you set it up correctly. |
|
|
myheadhurts
Joined: 08 Dec 2004 Posts: 7
|
|
Posted: Thu Dec 09, 2004 3:07 am |
|
|
I've included the relavent code below.
I tried the #int_fast, but the ccs complier doesn't seem to recognise it and throws up an 'invalid pre-processor directive' message.
#include <18F252.h>
#device adc=10
#include <stdio.h>
#include <stdlib.h>
#fuses WDT,WDT128, EC, NOPROTECT, NOOSCSEN, BROWNOUT, BORV27, PUT, STVREN, NODEBUG,
#fuses LVP, NOWRT, NOWRTD, NOWRTB, NOWRTC, NOCPD, NOCPB, NOEBTR, NOEBTRB
#use delay(clock=24000000,RESTART_WDT)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
#use fast_io(a)
#use fast_io(b)
#use fast_io(c)
#priority ext1,rda
#int_EXT1
EXT1_isr()
{
int dis_count;
#ASM
CLRWDT
BCF INT1IF /* clear interrupt flag*/
.
.
}
#int_RDA
RDA_isr()
{
char my_char;
my_char = getchar();
.
.
}
port_b_pullups(TRUE);
setup_adc_ports(RA0_ANALOG);
setup_adc(ADC_CLOCK_INTERNAL);
setup_spi(FALSE);
setup_wdt(WDT_ON);
setup_timer_2(T2_DIV_BY_4,0,1);
enable_interrupts(INT_EXT1);
enable_interrupts(INT_RDA);
INTEDG1 = 1; /*rising edge*/
enable_interrupts(GLOBAL);
void main()
{
.
.
} |
|
|
Ttelmah Guest
|
|
Posted: Thu Dec 09, 2004 3:26 am |
|
|
The key here, is to understand the difference between 'priority', and 'fast'.
All the 'priority' keyword does, is to set the _order_ in which the interrupts are checked, inside the software 'int_global' parser. This means that if two interrupts occur nearly together, so that both interrupt flags are set when the code gets to the parser, the 'higher priority' interrupt, will get preferential treatment.
The normal 'single interrupt' on the PIC processor, does not allow an interrupt to interrupt the execution of another interrupt.
On the 18 family chips, there is a seperate 'high priority' interrupt ability, which does allow an interrupt to interrupt another handler. This is enabled by using the 'fast' keyword (not the 'priority' keyword). However there are then some very large 'caveats'. Most of the 18Fxx2 chip revisions, still have problems with stack overflow, if a high priority interrupt occurs from an asynchronous source (ext1, is inherently such a source). This still applies to all silicon revisions of the 18F252, and really precludes the use of an external INT0 interrupt in this way. If you use the fast handler, only the key processor registers are saved/restored for you, and it becomes _your_ responsibility to save/restore every other register used in the handler routine. Generally using the 'fast' interrupt ability, requires some very careful coding of the handler, and a good understanding of what is going on in the chip itself.
Best Wishes |
|
|
myheadhurts
Joined: 08 Dec 2004 Posts: 7
|
|
Posted: Thu Dec 09, 2004 4:31 am |
|
|
forgive me for being a little thick!
I understand now that I have to use the fast keyword and the implications of backing up registers, but I don't seem to be able to fathom out specifically how or where to code it in.
The CCS complier version 1.9 I am using does not recognise #fast or #int_fast. Could someone please point me in the right direction.
Thanks again |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Thu Dec 09, 2004 7:51 am |
|
|
That is because I goofed when I typed it
Code: |
#int_ext1 fast
void isr(void)
{
...
}
|
|
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Thu Dec 09, 2004 7:57 am |
|
|
I believe that ext1 is always high priority int if fast ints are used. There was a recent post about it. |
|
|
myheadhurts
Joined: 08 Dec 2004 Posts: 7
|
|
Posted: Thu Dec 09, 2004 8:06 am |
|
|
cheers for that, I have looked at the asm/c listing and it appears to be in the correct places now.
It still looks like my fast interrupt is not interrupting my RDA interrupt.
Do I need to set this to be a low level interrupt, and if so, is there a simple command or do I have to resort to defining the bits and doing it in assembler. |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Thu Dec 09, 2004 8:36 am |
|
|
Take a look at this post
http://www.ccsinfo.com/forum/viewtopic.php?t=21092&start=15
It will give you an idea on how to create your own int handler. Also note that the required variables to be saved depend on what you do in the interrupt. I found out what needed to be save by looking at the assembly listing file (LST file). |
|
|
myheadhurts
Joined: 08 Dec 2004 Posts: 7
|
|
Posted: Thu Dec 09, 2004 8:57 am |
|
|
Cheers Mark, this looks like just the ticket. I will give it a twirl and let you know later. |
|
|
|