MEAM.Design - ATmega32 Programming - External and Pin-Change Interrupts


Overview

Thirteen of the ATmega32U4 GPIO pins can be used to trigger interrupts (INT0-3, INT6, and PCINT0-7). When enabled, interrupts will be generated regardless of whether the pin is configured as an input or an output (making for a decent way to do software-driven interrupts).



Global Interrupt Enable

Before you can use any external interrupt source, you need to enable global interrupts, as discussed here.



External Interrupts

To enable external interrupts on INT0, 1, 2, 3, or 6, you must remove the mask for the corresponding interrupt by setting the INTn bit (where n corresponds to the INTn pin) in the EIMSK register (default is cleared).

The behavior of INT0-3 are controlled in EICRA (External Interrupt Control Register A). You should mask the interrupt (in the EIMSK register) before changing these bits, as modifying the register can cause an interrupt to occur. You should also clear the corresponding interrupt flag(s) before re-enabling. In the following table, n corresponds to INTn.

EICRA:
ISCn1
EICRA:
ISCn0

 interrupt on:
0 0  low level (default)
0 1  either
1 0  falling
1 1  rising


The behavior of INT6 is slightly different from INT0-3 in that INT6 is synchronous with the I/O clock. What this means is that it will compare the state of the pin at successive clock ticks, and will generate an interrupt if the selected behavior set in EICRB (External Interrupt Control Register B) is observed. You should mask the interrupt (in the EIMSK register) before changing these bits, as modifying the register can cause an interrupt to occur. You should also clear the corresponding interrupt flag(s) before re-enabling.

EICRB:
ISC61
EICRB:
ISC60

 interrupt on:
0 0  low level (default)
0 1  either
1 0  falling
1 1  rising


When an interrupt on INTn is triggered, the INTFn bit in EIFR is set. This flag will be automatically cleared when the interrupt routine is executed, or it can be cleared manually by setting it high.

The resulting interrupt vector INTn will correspond to a trigger from INTn. These vectors are in order from 0 to 6, and follow directly after the RESET vector.



Pin Change Interrupts

To enable pin-change interrupts from PCINT0-7, you must:

1. Set the pin-change interrupt enable PCIE0 bit of PCICR, which is cleared by default.

2. Remove the mask for the corresponding interrupt by setting the PCINTn bit (where n corresponds to the PCINTn pin) in the PCMSK0 register (default is cleared).

When a logic-level change is detected on PCINTn and the corresponding bit in PCMSK0 is already set, the PCIF0 bit of the PCIFR register is set high. This is cleared when the interrupt routine is executed, or it can be cleared by manually setting it high.

Regardless of which pin changed, the interrupt will always point to the PCINT0 interrupt vector, which follows directly after the INTn vectors.