Skip to main content

Lab 9: External Interrupt (EXTI)

Learn hardware interrupt handling - respond to GPIO events instantly without polling. This is a core embedded system skill.

Learning Objectives

By the end of this lab, you will:

  • 🎯 Understand interrupt concept and architecture
  • 🎯 Configure EXTI (External Interrupt) lines
  • 🎯 Use SYSCFG to map GPIO to interrupt lines
  • 🎯 Write interrupt handler functions
  • 🎯 Enable NVIC interrupts for instant response

Prerequisites

  • ✅ Complete Lab 4 (debouncing)
  • ✅ Understand GPIO input reading
  • ✅ Familiar with interrupts concept

Hardware Required

ComponentDetails
MicrocontrollerSTM32F407VG
ButtonPA0 user button
LEDPD12 red LED

Theory: Interrupt Architecture

Polling vs Interrupts

Polling (what we've done):
while (1) {
if (button_pressed) {
// Expensive: checking constantly
}
}
Problem: Wastes CPU time and energy checking

Interrupt (Lab 9):
// Hardware detects button automatically
Interrupt fires → CPU jumps to handler → Executes code
Problem: None - CPU free until event happens!

EXTI System

GPIO Button (PA0)

SYSCFG (maps PA0 to EXTI0 line)

EXTI0 detector (rising edge, falling edge, both)

Interrupt controller (NVIC)

Interrupt handler function (EXTI0_IRQHandler)

Configuration Steps

1. Enable GPIO clock
2. Configure pin as input (MODER = 00)
3. Enable SYSCFG clock (APB2)
4. Map GPIO to EXTI line (SYSCFG_EXTICR1)
5. Unmask EXTI line (EXTI_IMR)
6. Set edge trigger (EXTI_RTSR for rising edge)
7. Enable interrupt in NVIC (NVIC_ISER0)
8. Write __attribute__ handler function
9. Clear interrupt flag in handler (EXTI_PR)

Demo

Interrupt Response

Button press → Instant LED toggle via interrupt handler

Complete Code

#define RCC_AHB1ENR *(volatile unsigned int*)(0x40023800 + 0x30)
#define RCC_APB2ENR *(volatile unsigned int*)(0x40023800 + 0x44)

#define GPIOA_MODER *(volatile unsigned int*)(0x40020000 + 0x00)
#define GPIOD_MODER *(volatile unsigned int*)(0x40020C00 + 0x00)
#define GPIOD_ODR *(volatile unsigned int*)(0x40020C00 + 0x14)

#define SYSCFG_EXTICR1 *(volatile unsigned int*)(0x40013800 + 0x08)
#define EXTI_IMR *(volatile unsigned int*)(0x40013C00 + 0x00)
#define EXTI_RTSR *(volatile unsigned int*)(0x40013C00 + 0x08)
#define EXTI_PR *(volatile unsigned int*)(0x40013C00 + 0x14)
#define NVIC_ISER0 *(volatile unsigned int*)(0xE000E100)

// Interrupt handler called when PA0 triggers
void EXTI0_IRQHandler(void) {
if (EXTI_PR & (1 << 0)) {
// Clear pending flag
EXTI_PR |= (1 << 0);

// Toggle LED
GPIOD_ODR ^= (1 << 12);
}
}

int main(void) {
// Enable GPIO clocks
RCC_AHB1ENR |= (1 << 0); // GPIOA
RCC_AHB1ENR |= (1 << 3); // GPIOD

// PA0 as input
GPIOA_MODER &= ~(3 << 0);

// PD12 as output
GPIOD_MODER &= ~(3 << 24);
GPIOD_MODER |= (1 << 24);

// Enable SYSCFG clock
RCC_APB2ENR |= (1 << 14);

// Map PA0 to EXTI0
SYSCFG_EXTICR1 &= ~(0xF << 0); // Clear bits [3:0]
// Leave as 0000 for GPIOA selection

// Unmask EXTI0 (allow interrupt)
EXTI_IMR |= (1 << 0);

// Rising edge trigger (button HIGH)
EXTI_RTSR |= (1 << 0);

// Enable EXTI0 in NVIC (interrupt 6)
NVIC_ISER0 |= (1 << 6);

// Loop (CPU now responds to interrupts)
while (1) {
// Can do other work here
// Interrupt will trigger automatically
}

return 0;
}

How It Works

Setup:
├─ PA0 configured as input
├─ SYSCFG maps PA0 → EXTI0
├─ EXTI0 watches for rising edge
├─ EXTI0_IRQHandler registered
└─ NVIC enabled for EXTI0

User presses button:
PA0 goes HIGH → Hardware detects → Interrupt fires!

CPU saves state

Jumps to EXTI0_IRQHandler()

Handler toggles LED

Handler clears pending flag

CPU resumes main loop

Expected Output

User Action:
├─ Press PA0 button
│ └─ Interrupt fires instantly
│ └─ LED toggles immediately
│ └─ No debouncing yet (see Challenge 1)
├─ Release button
│ └─ Another interrupt may fire (false trigger)
└─ Pattern repeats

Common Mistakes

IssueSolution
No responseEnable SYSCFG clock (RCC_APB2ENR)
Wrong pinVerify SYSCFG_EXTICR1 configuration
Multiple togglesAdd debouncing in handler
Interrupt never firesCheck NVIC_ISER0 - enable correct IRQ

Key Takeaways

Important:

  1. SYSCFG maps GPIO to EXTI lines
  2. EXTI detects edge conditions
  3. Interrupt handler runs automatically
  4. Must clear flag to prevent retriggering
  5. NVIC enables interrupt in CPU

Challenge Exercises

Challenge 1: Debounced Interrupt

Add debouncing within the handler function.

Challenge 2: Multiple Buttons

Use PA1 with EXTI1 for second button independently.

Challenge 3: Interrupt Counting

Count how many times interrupt was triggered, display on LEDs.

Next Steps

🚀 Ready for Lab 10? Learn LCD display interfacing to show text and data on screen!

Prerequisites for Lab 10: GPIO control, Parallel communication basics