View previous topic :: View next topic |
Author |
Message |
GSXRChris
Joined: 23 Mar 2005 Posts: 18
|
Posted: Sun Mar 27, 2005 4:53 am Post subject: How do you disable Int's in an interrupt |
|
|
Hi all
How can I disable an interrupt in an interrupt service routine, the return at the end re-sets interrupts enabled
I want to do this:
Code: |
Timer1_isr
Sample = Timer1
Disable Timer1
Return
|
The return at the end of the isr issues a reti which re-enables the timer1 interrupt.
Give us a clue, please
Cheers |
|
Back to top |
|
|
DToolan
Joined: 14 Aug 2004 Posts: 1384 Location: Dallas / Fort Worth, Texas (USA)
|
Posted: Sun Mar 27, 2005 5:58 am Post subject: |
|
|
The code you have written does disable Timer1 interrupts.
When a hardware interrupt occurs, AND the "interrupt enable bit" for that interrupt is enabled, AND the "global interrupt enable bit" in the AVR status register is enabled..., then the "global interrupt enable bit" (also called the "I" flag) is cleared. This is done to prevent interruption of an ISR routine by some other system interrupt. You are correct that the Return at the end resets the I flag (this does not reset your Timer1 interrupt enable... only the global interrupt enable flag). Restoring the I flag (global interrupt enable) allows the handling of any interrupts that may have occured while busy in the isr... and if not, to be ready for some future interrupt. In your Timer1_isr, you have disabled the Timer1 interrupt. Timer1 will no longer be a source of future interrupts.
Are you trying to say that even though you have Timer1 interrupts disabled (in your isr) that you are still getting Timer1 interrupts after leaving the isr? |
|
Back to top |
|
|
GSXRChris
Joined: 23 Mar 2005 Posts: 18
|
Posted: Sun Mar 27, 2005 4:18 pm Post subject: Timer1 isr |
|
|
Thanks for the response DToolan
Yes I do get interrupts after I have disabled the interrupt in the isr, I had assumed that the interrupt mask was being retreived from the stack on return and that is why the disable interrupt was being ignored.
I thought that on entry to the isr a copy of the interrupt mask was pushed onto the stack and that the I flag was cleared, then on exiting the isr the interrupt mask was pushed back into the interrupt mask register and the I flag was set.
If this is not the case, could there be an unserviced interrupt in the the interrupt flag register (TIFR) that is fireing as soon as I re-enable interrupts the next time I sample timer1.
As I understand it there are two registers that are 'anded' to produce an interrupt, the interrupt mask (TIMSK) and the interrupt flag registers (TIFR) and as long as the I flag is set the interrupt will occur.
It says in the data sheet that if an interrupt is pending in the TIFR register it only gets cleared if the interrupt is serviced. It's possible that the Overflow flag is being set when in my INT0 isr, so even if I disable interrupts in that isr, next time I enable the timer the overflow flag that was set during the INT0 isr fires an overflow interrupt even though I zero the timer and disable interrupts. I've checked this by clearing the relevant TIFR bits to clear any pending Int0 and Timer1 overflow interrupts and it still does'nt work.
So I end up where I started thinking the Interrupt mask must be pushed and poped to and from the stack on isr return. |
|
Back to top |
|
|
DToolan
Joined: 14 Aug 2004 Posts: 1384 Location: Dallas / Fort Worth, Texas (USA)
|
Posted: Sun Mar 27, 2005 7:35 pm Post subject: |
|
|
Quote: | Yes I do get interrupts after I have disabled the interrupt in the isr, I had assumed that the interrupt mask was being retreived from the stack on return and that is why the disable interrupt was being ignored.
I thought that on entry to the isr a copy of the interrupt mask was pushed onto the stack and that the I flag was cleared, then on exiting the isr the interrupt mask was pushed back into the interrupt mask register and the I flag was set. |
No, this is not the case... as far as interrupts go, the I flag is cleared, the actual interrupt generating condition (in this case, TOV1) is cleared, and then the I flag is restored upon return.
Quote: | If this is not the case, could there be an unserviced interrupt in the the interrupt flag register (TIFR) that is fireing as soon as I re-enable interrupts the next time I sample timer1. |
Since, in your example, you don't stop Timer1 (only disable the interrupt)... it is still running. If it should overflow it will set TOV1. As soon (sometime later) that you again enable Timer1 interrupts, it will immediately see the overflow condition (from some time ago) and jump to your isr... so this could be a possibility.
Does the chip you are working with have JTAG and do you possibly have a JTAG programmer? |
|
Back to top |
|
|
GSXRChris
Joined: 23 Mar 2005 Posts: 18
|
|
Back to top |
|
|
DToolan
Joined: 14 Aug 2004 Posts: 1384 Location: Dallas / Fort Worth, Texas (USA)
|
Posted: Sun Mar 27, 2005 8:45 pm Post subject: |
|
|
Quote: | I'm still not sure if Bascom's registers are stack allocations that get pushed on return or the actual hardware registers. |
They are actual hardware registers. If you open up the m162def.dat file in the Bascom directory, you will see where names are associated with hardware register addresses.
I see that the m162def.dat file has both names declared...
Quote: | GIMSK =$3b
GICR =$3b ; new name for GIMSK |
Even though GICR is there... it must not be equating both names to address &H3B. You can edit that def file with notepad and remove the GIMSK reference or comment it out if you want... then only the name GICR should be associated with the hardware register address. (You'd have to then change the name to GICR in your code, of course)
I'm sure that if I ever get around to working with the 162, I'll forget all about this and have to troubleshoot the same thing you did all over again (I do that alot) |
|
Back to top |
|
|
GSXRChris
Joined: 23 Mar 2005 Posts: 18
|
Posted: Sun Mar 27, 2005 10:24 pm Post subject: isr's |
|
|
Thanks for your help.
I will stick with the gimsk dec for now. It works with Int1 isr operational as well. Change the prescaler on the timer and you can measure a wide range of input puleses.
You can have timer0 free running for other tasks, timer3 too I suppose but Ive not checked that.
I posted the code so people wouldnt have to go over old ground. It's like everyone throwing up all the bricks when we only need to throw up one brick each.
Cheers
Chris |
|
Back to top |
|
|
|