When are interrupt flag bits cleared?

Go To Last Post
11 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'd like to know at what point the an interrupt flag is cleared when the datasheet says 'the flag is cleared when the interrupt routine is executed'.

The reason for the question is a toggling port pin using the pin change interrupt. If the pin toggles and an interrupt is generated, while servicing that interrupt if the pin toggles again as I'm leaving the interrupt, will I miss it? If the interrupt flag is cleared upon entry into the ISR, I don't have a problem. If it is cleared by the reti, I could miss the interrupt.

I guess one way would be to write some code and test it for myself, but if anyone out there already knows the answer, please share it.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The manual says:

The interrupt execution response for all the enabled AVR interrupts is four clock cycles
minimum. After four clock cycles the program vector address for the actual interrupt
handling routine is executed. During this four clock cycle period, the Program Counter is
pushed onto the Stack. The vector is normally a jump to the interrupt routine, and this
jump takes three clock cycles. If an interrupt occurs during execution of a multi-cycle
instruction, this instruction is completed before the interrupt is served. If an interrupt
occurs when the MCU is in sleep mode, the interrupt execution response time is
increased by four clock cycles. This increase comes in addition to the start-up time from
the selected sleep mode.
A return from an interrupt handling routine takes four clock cycles. During these four
clock cycles, the Program Counter (two bytes) is popped back from the Stack, the Stack
Pointer is incremented by two, and the I-bit in SREG is set.

Debugging is for sissies and delivery for surgeons. Real men do demonstration.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I believe that part of the manual does not answer the OP's question.

But the OP could either read the manual himself, or, just clear the interrupt flag as the first thing in the interrupt routine so that another interrupt in the middle of the interrupt routine would leave the flag on and after reti the interrupt would be run again.

- Jani

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It would really help to know exactly which AVR chip you are using. The data sheets usually explain this.

Here is an Atmega48/88/168 data sheet pin change interrupt flag example: “The flag is cleared when the interrupt routine is executed”.

My understanding is this is handled in the initial interrupt recognition/response (pushing the PC onto the stack, going to the interrupt vector, etc.) before the actual interrupt response code actually starts running. This method always guarantees at least one interrupt response for any number of interrupt events (interrupts might happen faster than the interrupt event response reaction time) and never allows an enabled interrupt to be lost (as in a trailing interrupt that is never recognized or responded to).

If a new interrupt occurs during the uncertain period at the exact point when the interrupt flag is cleared: If the interrupt flag is cleared and then almost instantly set, there will be another pending interrupt event waiting to be serviced after this interrupt response is done. If the flag is set again and then almost instantly cleared, it will not matter because the interrupt routine is just starting and has not been run yet (the interrupt will not be lost).

If the interrupt event happens during the interrupt response code execution, the interrupt flag will be set and there will be another pending interrupt event waiting to be serviced after this interrupt response is done.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm using a ATMega168
My initial testing would support what Mike B has said. Upon entering the interrupt routine it would appear that the flag is already cleared.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you enable the interrupt at the beginning of the ISR-routine, take care, because you might have a nested interrupt routine:
interrupt - ISR
within ISR another interrupt -> ISR
second ISR handling
return to the first ISR
return from the first ISR

Debugging is for sissies and delivery for surgeons. Real men do demonstration.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

No-one till now was talking about nested interrupts. the question was on when the flag for the interrupt source is cleared. The answer is "when the interrupt vector is executed". This gives the maximum opportunity to handle repetitive events. It is roughly 10 clocks or so, plus interrupt latency (e.g., another interrupt may be running or interrupts may be globally disabled). So about a microsecond at common clock rates It would be tight, though, to process a repetitive 1MHz stream of events as I'd assume there was >>some<< processing involved or it would not be important ;) and you have to get out and do another instruction before the next can occur. (Now, if the first is the start of a repetitive "train" then one could examine the flag right inside the ISR to try to eliminate some of the out-and-back-in overhead. Some people do this in, say, the UART Rx ISR--since the UDR is double-buffered they will peek to see if there is another character waiting when done with the first.)

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Another interesting thing about enabled interrupts happening faster than the ARV can respond to them is the SEI and RETI enable global interrupts behavior. Global interrupts are always enabled after the next instruction executes. This means even if a very fast/frequent interrupt tries to own all the AVR CPU cycles, the non-interrupt code after the RETI always gets one instruction to execute for each already pending repeated interrupt response. However, if the interrupt response takes 100 cycles and they are non-stop, it will leave the main non-interrupt code with around only 1 / 100 of the CPU time :cry:.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

[Haven't checked the manual] Typically, when the interrupt occurs, tha status is pushed into the stack and the global interrupt flag is set so that all interrupts are disabled (or at least interrupts of the same and lower priority levels). The return from interrupt restores the status from the stack (and the interrupt flag).

Debugging is for sissies and delivery for surgeons. Real men do demonstration.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
(or at least interrupts of the same and lower priority levels)

Be careful with this thinking. The AVRs interrupts have priority, but it's only used as a tie breaker for simultaneously occurring interrupts or when coming out of a period of disabled interrupts (like a handler) when multiple interrupts have occurred and are waiting service. If you're in a high priority interrupt handler and enable global interrupts, a low priority interrupt can and may interrupt you.

Other processors may implement interrupt priorities differently, including having low priority interrupts not interrupt high priority interrupt handlers.

Chuck Baird

"I wish I were dumber so I could be more certain about my opinions. It looks fun." -- Scott Adams

http://www.cbaird.org

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It always good to check the manual or at least the data sheet :wink:. Enabling or disabling interrupts has no direct effect on the interrupt flags. It is the interrupt response (as already described) or a direct software clear that clears an interrupt flag. A manual software interrupt flag clear can cause a lost interrupt response if it happens at the wrong time. BTW, interrupt flags are disabled when using level interrupts, so nothing discussed so far applies to them.

From the ATmega48/88/168 data sheet:

Quote:
If an interrupt condition occurs while the corresponding interrupt enable bit is cleared, the Interrupt Flag will be set and remembered until the interrupt is enabled, or the flag is cleared by software. Similarly, if one or more interrupt conditions occur while the Global Interrupt Enable bit is cleared, the corresponding Interrupt Flag(s) will be set and remembered until the Global Interrupt Enable bit is set...
You have to combine this quote with the other information about when an interrupt flag is cleared. If you just read the quote alone you might get the wrong idea and think enabling an interrupt has a direct effect. Enabling the interrupt is actually only the first step.

This is why it is usually a good idea to manually clear an interrupt flag when initializing an interrupt (a stray pre-initialization interrupt may have left the flag set).