Maker Pro
Maker Pro

Multiple interrupt functions but one interrupt vector

Hi Guys,

I'm using a PIC16F877 40-Pin, MPLAB and Hi-Tech C compiler.

I'm trying to use both an RB0/INT interrupt and PORTB (RB7:RB4) interrupt but keep getting the error: multiple interrupt functions (_INT_ISR and _ISR) defined for device with only one interrupt vector

Here's the two interrupt functions:

Code:
void interrupt ISR(void)
{
    if(RBIF)    //If interrupt flag bit is 1
    {
    a = 1;
    RBIF = 0;    //Clear flag bit
    }
}

void interrupt INT_ISR(void)
{
    if(INTF)    //If interrupt flag bit is 1
    {
    a = 2;
    INTF = 0;    //Clear flag bit
    }
}

Both work individually but not together, I have read somewhere that I need to use GIEH =1 and GIEL=1, but these aren't recognised by the compiler. The PIC datasheet and the INTCON bits do say GIE/GIEH so I know its possible.

Any idea's what I'm supposed to do to set the priority?

Thanks Ash
 
Thanks Adam,

I did come across this, but I'm not sure what it means. I was hoping to get an explanation in English not C lol.

Maybe I should just test the code see what happens.
 
It's late here now so what I will do is ask some friends at work in the morning for you. Someone may come back with the answer before then.
Cheers
Adam
 
I believe the amount of interrupt vectors in each device is fixed, so I cannot create anymore. According to the Hi-Tech C manual:

Screenshot_6.jpg

So basically, I have to put all desired code in one interrupt function like this:

Code:
void interrupt ISR(void)
{
    if(RBIF)    //If interrupt flag bit is 1
    {
    a = 1;
    RBIF = 0;    //Clear flag bit
    }

    if(INTF)    //If interrupt flag bit is 1
    {
    a = 2;
    INTF = 0;    //Clear flag bit
    }
}

Not very efficient mind, but I guess i'll have to put time-dependant or high-priority if statements at the top.
 

hevans1944

Hop - AC8NS
I am glad you and Adam found the solution. I ran across this last year with a smaller PIC, and the solution is essentially the same: poll the devices that can generate a shared interrupt vector and act accordingly. That does look inefficient, but from a hardware point of view the processor can only execute one thread at a time, so nothing is really lost except for some overhead in deciding what to do, what registers to save (and later restore) in the Interrupt Service Routine (ISR) and what priority tree you want to implement.

Older microprocessors (and newer ones, too) have several interrupt vectors dedicated to either software or hardware interrupts, and that did make programming somewhat less tedious at the machine-code (assembly) level. Nevertheless, it all gets back to the CPU executing one thread at a time... unless of course you have multi-core processors and the software to take advantage of parallel executing threads... not a small task. A real-time operating system comes in handy for that.

Where prioritized interrupts will come back to bite you in the ass is when you have to accommodate real-time events occurring faster than the CPU can dispatch them, for example a UART with a continuous steam of high-speed data and no hardware hand-shake to slow things down. Sure, you can buffer the data, but if the data never stops and your ISR cannot empty the FIFO buffer between interrupts, eventually the buffer overflows and you either lose older data or fail to process new data. And that's just one interrupt. It gets worse when there are several asynchronous interrupts occurring at random intervals. Even the fastest CPUs can be overwhelmed if the interrupt events occur fast enough. The only "easy" solution is to use a faster CPU or throw more CPUs at the problem.

Back in the day, using the Intel 8085 8-bit micro, we used the 8259 programmable interrupt controller to accept multiple interrupts, prioritize them, and call the appropriate ISR. That didn't solve the speed problem, but it did solve the interrupt contention problem. The Golden Rule for ISR processing has always been: (1) get in, (2) do as little processing as possible, and (3) get out.
 
Yep that's what we do. Diode OR to the master interrupt and then check in the ISR what caused the interrupt. Other PICs have more than one and some even have a vector table. You may want to choose another PIC if it's an issue. Run the processor at a faster clock speed if processing time is an issue.

Thanks
Adam
 
The Golden Rule for ISR processing has always been: (1) get in, (2) do as little processing as possible, and (3) get out.

I will be following this very closely!

Yep that's what we do. Diode OR to the master interrupt and then check in the ISR what caused the interrupt. Other PICs have more than one and some even have a vector table. You may want to choose another PIC if it's an issue. Run the processor at a faster clock speed if processing time is an issue.

Thanks
Adam

It's the first time I've heard about it, but at least I've learnt something. I don't think it will be an issue, but I am using a 4MHz resonator, but if i need to I will upgrade this.
 
Hope you don't mind me reawakening this post..

My LCD is displaying random characters. I upgraded my resonator to 16MHz and change the programs oscillator configuration bit to HS.

Nothing has changed in the software, apart from changing the ocillator to 16MHz and the config bit.

My program writes line1 'Startup-menu' and line2 'Press Button' to the display. Now I'm getting '0ar0)1P' and 'r!s3 *1tton'.

Except for the *, im not quite sure what symbol it is.
 
Never-mind, I've fixed it :cool:

I have't used the busy pin to check if the LCD is ready to write data too, just delays. I had to make the delays abit longer.
 
Top