AVR assembly demonstrating three external interrupts (INT0, INT1, INT2), fixed hardware priority, and proper SREG/stack preservation in ISRs.
A background loop free-runs a 1 Hz up-counter on the PORTA LEDs (active-low). Each external interrupt is falling-edge triggered and flashes a signature pattern five times (1 s on / 1 s off) before the count resumes:
| Interrupt | Pin | Pattern |
|---|---|---|
| INT0 | PD2 | 0x03 |
| INT1 | PD3 | 0xC0 |
| INT2 | PB2 | 0xAA |
Priority is fixed by the vector table: INT0 > INT1 > INT2. Each ISR runs
with the global I-bit cleared, so it cannot be pre-empted. A trigger arriving
mid-service only latches the pending flag and is serviced after RETI, in
priority order.
- PORTA → LEDs (ribbon cable)
- INT0 → SW0 (PD2), INT1 → SW1 (PD3), INT2 → SW2 (PB2)
- Internal pull-ups are enabled in firmware; switches pull the line low.
- To test simultaneous INT0+INT1, jumper both switch lines together on a breadboard as in the original lab step 14.
- New Project → AVR Assembler Project → device ATmega32.
- Replace the generated
.asmwithlab6_interrupts.asm. - Build (F7). Program with the JTAGICE mkII (Tools → Device Programming).
The file includes m32def.inc, which AVRASM2 ships with. (If you build with
command-line avra instead, point -I at its includes/ folder.)
delayIt = 100000 gives a ~1 s tick at 1 MHz. If your CKSEL fuses run the
part at 8 MHz, multiply delayIt by 8 (or set the CLKDIV8 fuse to stay at 1 MHz).
- The discussion text said "positive edge"; the actual
MCUCR = 0x0Aselects falling edge. Comment corrected to match behavior. - ISRs save a scratch register, SREG, and all clobbered temporaries (r16, r20, r21, r22) cleanly instead of the fragile R3-only pattern.
- Flashing logic factored into a shared
FlashFivehelper.