๐Ÿ“ Pico Series
Episode 02 ยท Pico Learning Series
// CONCEPT: EXTERNAL INTERRUPTS

InterruptHandling

Raspberry Pi Pico ยท GPIO IRQ ยท Rising Edge ยท ISR Callback
// What you'll learn
What an interrupt is and why it's better than polling
How rising/falling edge detection works in hardware
How to register an ISR (Interrupt Service Routine) callback
How the CPU context-switches to handle an interrupt
// Live Interrupt Simulator
BUTTON
IRQ LINE
CPU
// CPU State
MAIN LOOP
while(true) { } โ€” waiting for events
LED (GPIO 25 โ€” onboard)
Toggle count: 0 / 5
// 01 โ€” Core Concepts

What is an Interrupt?

๐Ÿ”„
Polling vs Interrupts
Polling means the CPU constantly checks a pin: "Is the button pressed? Is the button pressed?" This wastes cycles. An interrupt lets the CPU do real work and only react when the hardware signals a change โ€” much more efficient.
Efficiency
๐Ÿ“ˆ
Rising Edge Detection
A rising edge is the moment a signal transitions from LOW (0V) to HIGH (3.3V). The RP2040's GPIO hardware detects this transition in silicon โ€” without software polling โ€” and fires an interrupt request (IRQ) to the CPU.
GPIO_IRQ_EDGE_RISE
โšก
ISR โ€” Interrupt Service Routine
When an IRQ fires, the CPU saves its current state (registers, program counter), jumps to your ISR callback function, executes it, then returns to exactly where it left off. The main loop never even knows it was interrupted.
interrupt_handler()
// 02 โ€” Execution Flow

Step-by-Step Flow

// Interrupt Execution Sequence
01

GPIO Pin Init

LED pin โ†’ OUTPUT. Button pin (GPIO 11) โ†’ INPUT.

gpio_init() + gpio_set_dir()
02

Register IRQ Callback

Tell the hardware: on rising edge at GPIO 11, call interrupt_handler().

gpio_set_irq_enabled_with_callback()
03

Main Loop Runs

CPU enters while(true) โ€” doing nothing, or any other task. The interrupt is armed and watching.

while(true) { }
04

Button Pressed โ†’ Rising Edge

Hardware detects LOWโ†’HIGH transition on GPIO 11. Fires IRQ. CPU saves context, jumps to ISR.

GPIO_IRQ_EDGE_RISE detected โšก
05

ISR Executes

interrupt_handler() runs: toggles LED 5ร— at 1s intervals using busy_wait_ms().

gpio_put(LED, 1/0) ร— 5
06

Return to Main Loop

ISR returns. CPU restores context. Main loop continues exactly where it paused.

context restore โ†’ resume
interrupt.c
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"

#define LED_OUT     PICO_DEFAULT_LED_PIN
#define EXT_INT_PIN 11

// ISR โ€” called automatically when button is pressed
// CPU suspends main loop, runs this, then returns
void interrupt_handler() {
    // Toggle LED 5 times โ€” visual proof interrupt fired
    for (int i = 0; i < 5; i++) {
        gpio_put(LED_OUT, 1);
        busy_wait_ms(1000);
        gpio_put(LED_OUT, 0);
        busy_wait_ms(1000);
    }
}

int main() {
    stdio_init_all();

    // Setup LED as output
    gpio_init(LED_OUT);
    gpio_set_dir(LED_OUT, GPIO_OUT);

    // Setup interrupt pin as input
    gpio_init(EXT_INT_PIN);
    gpio_set_dir(EXT_INT_PIN, GPIO_IN);

    // Register ISR: fire on rising edge (button press)
    gpio_set_irq_enabled_with_callback(
        EXT_INT_PIN,
        GPIO_IRQ_EDGE_RISE,
        true,
        &interrupt_handler
    );

    // Main loop โ€” CPU free to do other work
    while (true);

    return 0;
}
// Key API
gpio_set_irq_enabled_with_callback(
pin, // which GPIO to watch
trigger, // EDGE_RISE / EDGE_FALL / LEVEL
enabled, // true to arm the interrupt
callback // your ISR function pointer
);
// 03 โ€” Hardware

Pin Connections

Connection Table
Component          GPIO Pin    Direction
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
LED (onboard)     GPIO 25     OUTPUT
Button (EXT)      GPIO 11     INPUT
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
// EXT_INT_PIN watches for rising edge
// LED_OUT toggles 5ร— on each interrupt