4.8.5 Enabling Interrupts

Two macros are available, once you have included <xc.h>, that control the masking of all available interrupts. These macros are ei(), which enable or unmask all interrupts, and di(), which disable or mask all interrupts.

On all devices, they affect the I bit in the status register, SREG. These macros should be used once the appropriate interrupt enable bits for the interrupts that are required in a program have been enabled.

For example:

TIMSK = _BV(TOIE1);
ei(); // enable all interrupts
// ...
di(); // disable all interrupts
Note: Typically you should not re-enable interrupts inside the interrupt function itself. Interrupts are automatically re-enabled by hardware on execution of the reti instruction. Re-enabling interrupts inside an interrupt function can result in code failure if not correctly handled.

In addition to globally enabling interrupts, each device's particular interrupt needs to be enabled separately if interrupts for this device are desired. While some devices maintain their interrupt enable bit inside the device's register set, external and timer interrupts have system-wide configuration registers.

To modify the TIMSK register, use timer_enable_int(ints). The value you pass via ints should be the bit mask for the interrupt enable bit and is device specific.

To modify the GIMSK register (or EIMSK register if using an AVR Mega device or GICR register for others) use enable_external_int(mask). This macro is unavailable if neither if these registers are defined.

For example:

// Enable timer 1 overflow interrupts
timer_enable_int(_BV(TOIE1));
// Do some work...
// Disable all timer interrupts
timer_enable_int(0);