🛠 Interruptions GPIO et alarmes matérielles avec le Pico SDK

RP2040 (generic board / chip) · intermediaire · Schéma : IMG-rp2040-generic-intermediaire-3-rp2040-interruptions-timer.svg — carte RP2040 avec bouton sur GP2, chronogramme front descendant déclenchant l'IRQ IO_BANK0 puis une alarme du timer 50 ms plus tard, LED de réponse

Objectives

Move away from "polling": on a generic RP2040 board without embedded LEDs or buttons, you want to react instantly to an external event and wake up at a fixed time without blocking the CPU. The RP2040 provides an IO_BANK0 interrupt controller (levels and edges on each GPIO) and a 64-bit timer with 12 hardware alarms for this purpose (RP2040 datasheet). In C (Pico SDK), you will combine both for a clean button implementation: IRQ on the falling edge, debouncing via a delayed alarm, and CPU sleeping in between.

Hardware

Complete Code

// irq_alarm.c — IRQ front descendant + alarme anti-rebond (Pico SDK)
#include "pico/stdlib.h"
#include "hardware/irq.h"
#include "pico/time.h"

#define BTN 2
#define LED 15

// Exécutée 50 ms après le front : contexte d'interruption, rester bref.
bool confirmer_appui(alarm_id_t id, void *user) {
    (void)id; (void)user;
    if (!gpio_get(BTN)) {              // toujours enfoncé ? vrai appui
        gpio_put(LED, !gpio_get(LED));
    }
    return false;                      // one-shot
}

// Handler IO_BANK0 : au plus court, on planifie juste l'alarme.
void on_gpio(uint gpio, uint32_t events) {
    (void)gpio; (void)events;
    add_alarm_in_ms(50, confirmer_appui, NULL, true);
}

int main(void) {
    stdio_init_all;
    gpio_init(BTN); gpio_set_dir(BTN, GPIO_IN); gpio_pull_up(BTN);
    gpio_init(LED); gpio_set_dir(LED, GPIO_OUT);
    // active l'IRQ du front ET enregistre le callback IO_BANK0 partagé
    gpio_set_irq_enabled_with_callback(BTN, GPIO_IRQ_EDGE_FALL,
                                       true, &on_gpio);
    while (true) {
        __wfi;   // le CPU s'end ; l'IRQ GPIO (ou une alarme) le réveille
    }
}

Expected Verification

Each firm press toggles the LED only once: the IRQ captures the edge, the alarm re-checks the state 50 ms later and ignores bounces (the contact vibrates for ~1 ms). Add a printf in the handler (with stdio_init_all) to confirm that __wfi indeed terminates upon the event. On a µA-meter, WFI sleep causes consumption to drop — the datasheet states SLEEP ≈ 1.3 mA at 25 °C, confirmed by the "dodo-meter".

Common Errors

Other tutorials for this board

Code examples for this board

← Back to the board 🛠 All tutorials