Add interrupt notes

This commit is contained in:
Pratik
2026-04-03 23:25:16 +11:00
parent ba12279c6a
commit 4012404504

View File

@@ -0,0 +1,210 @@
# 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