# 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 → Two’s 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) //holding button 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