4.8.1 Interrupt Service Routines

Observe the following information and guidelines when writing interrupt functions (also known as Interrupt Service Routines, or ISRs).

Usually, each interrupt source has a corresponding interrupt flag bit, accessible in a control register. When set, these flags indicate that the specified interrupt condition has been met. Interrupt flags are sometimes cleared in the course of processing the interrupt, either when the handler is invoked or by reading a particular hardware register; however, there are other instances when the flag must be cleared manually by code. Failure to clear the flag might result in the interrupt triggering again as soon as the current ISR returns.

The interrupt flag bits in the SFRs have a unique property whereby they are cleared by writing a logic one to them. To take advantage of this property, you should write directly to the register rather than use any instruction sequence that might perform a read-modify-write. Thus, to clear the TOV0 timer overflow flag in the TC0 interrupt flag register, use the following code:
TIFR = _BV(TOV0);
which is guaranteed to clear the TOV0 bit and leave the remaining bits untouched.

The hardware globally disables interrupts when an interrupt is executed. Do not re-enable interrupts inside the interrupt function. This is performed automatically by a special reti return instruction used by the compiler to terminate the ISR execution.

Keep the ISR as simple as possible. Complex code will typically use many registers, which might increase the size of the context switch code.

The compiler processes interrupt functions differently from other functions, generating code to save and restore any registers that are used by the function and that are not saved by the device hardware. These functions additionally use the reti instruction, so they must not be called directly from C code, but they can call other functions, such as user-defined and library functions.

Interrupt code is the name given to any code that executes as a result of an interrupt occurring, including functions called from the ISR and library code. Interrupt code completes at the point where the corresponding return from interrupt instruction is executed. This contrasts with main-line code, which, for a freestanding application, is usually the main part of the program that executes after Reset.

The following sections describe how interrupt functions should be written and incorporated into your project based on the vector table configuration.