View previous topic :: View next topic |
Author |
Message |
Jody
Joined: 08 Sep 2006 Posts: 182
|
Clearing Interrupts by my self?? |
Posted: Sat Dec 02, 2006 3:37 pm |
|
|
Hello,
I have an interrupt routine and I want to clear the interrupt. Thus not when I leave the ISR routine but when I want it...
I use a 18F8722 and calls the right interrupt flag I think. But whatever I do the interrupt is cleared by leaving the ISR... How can I prevent that???
Code: |
#byte PIR2 = 0xFA1
#bit CMIF = PIR2.6 // CMIF: Comparator Interrupt Flag bit
|
And I want to clear CMIF when I want it....
Thanks in advance,
Jody |
|
|
Ttelmah Guest
|
|
Posted: Sat Dec 02, 2006 3:51 pm |
|
|
First, there is a command to clear the interrupt flag. You don't need to fiddle working out the bits yourself.
Clear_interrupts(INT_COMP);
Second add the keyword 'noclear' to the interrupt definition.
Code: |
#INT_COMP noclear
void sub_for_int(void) {
//interrupt handler
}
|
This turns off the default 'automatic' clearance.
Best Wishes |
|
|
Jody
Joined: 08 Sep 2006 Posts: 182
|
Thanx!!!!!! Ttelmah |
Posted: Sat Dec 02, 2006 5:21 pm |
|
|
Thanks for the info!!!
You helped me a lot!!
Greetings,
Jody |
|
|
Jody
Joined: 08 Sep 2006 Posts: 182
|
When not clearing the interrupt!! |
Posted: Sun Dec 03, 2006 3:51 am |
|
|
When I don't clear the interrupt, will the program always go into the ISR untill I clear the interrupt??? |
|
|
Ttelmah Guest
|
|
Posted: Sun Dec 03, 2006 4:28 am |
|
|
Yes, but at a very severe 'cost'.
The way it works is, that there is an 'int_global' handler, which is created for you automatically (unless you write your own). This is called by the hardware, whenever an interrupt 'flag' is true, and the interrupt is enabled (both itself, and the 'global' enable). The act of calling this, clears the 'global' enable (the hardware does this). This global handler saves all the temporary registers from the chip, and scratch registers used by the compiler. It then checks the interrupt flags of each enabled interrupt, and calls the handler for the first interrupt it finds (the '#priority command, changes the order in which the flags are tested). When the handler returns, all the registers are restored, and a special hardware 'interrupt return' is executed, which re-enables the 'global' flag. At this point, if the interrupt flag is still set, the entire sequence will be triggered again on the next CPU instruction.
It is much more efficient, to loop inside your handler, till the flag is cleared. Otherwise you incur between about 60 and 80 extra instructions 'overhead', doing all the register saves and restores while you keep looping.
Best Wishes |
|
|
Jody
Joined: 08 Sep 2006 Posts: 182
|
mmmhh that's not what I want |
Posted: Sun Dec 03, 2006 4:36 am |
|
|
I hoped that I didn't return to the ISR untill I cleared the Interrupt flag and an other interrupt occur....!!
Is there a way to do this?? |
|
|
Ttelmah Guest
|
|
Posted: Sun Dec 03, 2006 4:56 am |
|
|
Not really.
The whole point of an interrupt, is that it is like a hardware 'alarm' button.
You can disable the interrupt inside the handler:
disable_interrupts(INT_COMP);
Then this interrupt will not be called again, even though the interrupt flag itself is set.
However you would have to add code in the 'main' to re-enable this interrupt, or the handler will never be called again.
Why fiddle around though?.
The normal way to do things would be to let the compiler clear the interrupt flag itself, and have your _own_ flag, that says the event has occured. So:
Code: |
int1 comp_interrupt_triggered=FALSE;
#INT_COMP
void comparator_int(void) {
comp_event_triggered=TRUE;
}
|
Then in your main, you can check the flag, to find that the comparator event has occurred, and the hardware handler will not be called again, till the hardware event occurs again.
Best Wishes |
|
|
Jody
Joined: 08 Sep 2006 Posts: 182
|
Disable interrupt |
Posted: Sun Dec 03, 2006 6:46 am |
|
|
Is it possible to use:
[code]
disable_interrupts(int_ext);
[/code]
or must I first:
[code]
disable_interrupts(global);
disable_interrupts(int_ext);
enable_interrupts(global);
[/code]
I am sorry for mine questions.. normally I use the Hi-Tech compiler...
Thanks in advance,
Jody |
|
|
Ttelmah Guest
|
|
Posted: Sun Dec 03, 2006 8:34 am |
|
|
This is nothing to do with the compiler. Read the chip's data sheet. 'GLOBAL', sets or clears the global interrupt control bit, while the ones for the individual interrupts control the bits for these.
Inside an interrupt, you must _never_ enable the GLOBAL bit (this would override the inbuilt hardware protection from the chip to prevent a re-entranty call. You can though control the individual interrupt control bits.
There are three register bits associated with any interrupt:
The 'global' bit (this controls whether any interrupts are responded to.
The interrupts own 'enable' bit.
The interrupt flag. Set by the hardware when the 'event' occurs.
For the interrupt to be responded to, and call the handler, all three have to be 'true'.
So you can turn off the response to an individual interrupt, while leaving it's 'flag' set, by turning off it's enable bit.
Best Wishes |
|
|
Jody
Joined: 08 Sep 2006 Posts: 182
|
Oke |
Posted: Sun Dec 03, 2006 10:05 am |
|
|
Thank you that's what I was hoping for......
But in Hi-tech when you not clear the flag the interrupt doesn't occur again...
Thanks for all the help!!!!!! |
|
|
|