Files
embedded-programming/interrupts/pin-interrupt-notes.md
2026-04-03 23:25:16 +11:00

3.7 KiB
Raw Blame History

External Interrupt Configuration (ATmega328P)

SREG (Status Register)

SREG is AVR status register with 8-bit status:

  • Bit 0 → Carry Flag (C) for ALU operations
  • Bit 1 → Zero Flag (Z) result is zero
  • Bit 2 → Negative Flag (N) result is negative
  • Bit 3 → Twos Complement Overflow Flag (V) arithmetic overflow
  • Bit 4 → Sign Bit (S) N ⊕ V
  • Bit 5 → Half Carry Flag (H) carry from bit 3 to 4
  • Bit 6 → Bit Copy Storage (T) used in bit operations
  • Bit 7 → Global Interrupt Enable (I) Important for interrupt

Enable Global Interrupt

SREG |= (1 << 7);
// or
sei();

Disable Global Interrupt

SREG &= ~(1 << 7);
// or
cli();

External Interrupt Pins

  • PD2 → INT0
  • PD3 → INT1

EICRA (External Interrupt Control Register A)

Controls how external interrupts trigger.

ISC (Interrupt Sense Control)

ISCx1 ISCx0 Mode
0 0 Low Level
0 1 Any Logical Change
1 0 Falling Edge
1 1 Rising Edge

Bit Positions

  • INT0 → ISC01 (bit1), ISC00 (bit0)
  • INT1 → ISC11 (bit3), ISC10 (bit2)

Interrupt Trigger Modes (INT0)

1. Low Level (00)

EICRA &= ~((1 << ISC01) | (1 << ISC00));

Bit calculation:

  • (1 << ISC01) = 00000010
  • (1 << ISC00) = 00000001
  • OR = 00000011
  • NOT = 11111100
  • Result → ISC01=0, ISC00=0

2. Any Logical Change (01)

EICRA &= ~(1 << ISC01);
EICRA |=  (1 << ISC00);

Bit calculation:

  • Clear ISC01 → 0
  • Set ISC00 → 1
  • Result → 01

3. Falling Edge (10)

EICRA |=  (1 << ISC01);
EICRA &= ~(1 << ISC00);

Bit calculation:

  • Set ISC01 → 1
  • Clear ISC00 → 0
  • Result → 10

4. Rising Edge (11)

EICRA |= (1 << ISC01) | (1 << ISC00);

Bit calculation:

  • (1 << ISC01) = 00000010
  • (1 << ISC00) = 00000001
  • OR = 00000011
  • Result → ISC01=1, ISC00=1

INT1 (Same Logic)

Replace:

  • ISC01 → ISC11
  • ISC00 → ISC10

Example (Rising Edge INT1):

EICRA |= (1 << ISC11) | (1 << ISC10);

Practical Note (Real Hardware Behavior)

  • Button press is not 100% stable
  • Causes:
    • Mechanical bounce
    • Loose wiring / plug-in noise
    • Floating inputs

Recommendation

  • Avoid: Any Logical Change (too sensitive)
  • Prefer:
    • Falling Edge (more stable detection)
    • Or implement HOLD logic in software

EIMSK (External Interrupt Mask Register)

Controls enabling/disabling of interrupts.

Bit Positions

  • Bit 0 → INT0 enable
  • Bit 1 → INT1 enable

Enable / Disable Interrupt Lines

Enable INT0

EIMSK |= (1 << INT0);

Disable INT1

EIMSK &= ~(1 << INT1);

Why Disable Unused Interrupts

  • Prevent false triggering from floating pins
  • Reduce noise impact
  • Ensure controlled initialization
  • Avoid unintended behaviour

Interrupt Execution Flow

  1. Configure trigger in EICRA
  2. Enable interrupt in EIMSK
  3. Enable global interrupt (sei)
  4. Event occurs → CPU jumps to ISR

ISR (Interrupt Service Routine)

ISR is executed automatically when interrupt occurs.


Flag-Based Handling

Global Flag

volatile uint8_t flag = 0;
  • volatile required (value changes outside normal flow)

ISR Definitions

INT0 Interrupt

ISR(INT0_vect)
{
    flag = 1;
}

INT1 Interrupt

ISR(INT1_vect)
{
    flag = 1;
}

Important Notes

  • Keep ISR short
  • No delay or heavy processing inside ISR
  • Use flag and handle logic in main loop
  • Always use volatile for shared variables