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

RP2040 (carte / puce générique) · 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

Objectifs

Sortir du « polling » : sur une carte RP2040 générique sans LED ni bouton embarqués, tu veux réagir instantanément à un événement extérieur et te réveiller à heure fixe sans bloquer le CPU. Le RP2040 fournit pour ça un contrôleur d'interruptions IO_BANK0 (niveaux et fronts sur chaque GPIO) et un timer 64 bits à 12 alarmes matérielles (datasheet RP2040). En C (Pico SDK), tu vas combiner les deux pour un bouton propre : IRQ sur le front descendant, anti-rebond par alarme différée, CPU endormi entre les deux.

Matériel

Code complet

// 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
    }
}

Vérification attendue

Chaque appui franc bascule la LED une seule fois : l'IRQ capture le front, l'alarme re-vérifie l'état 50 ms plus tard et ignore les rebonds (le contact vibre ~1 ms). Ajoute un printf dans le handler (avec stdio_init_all) pour confirmer que le __wfi se termine bien sur l'événement. Sur un µA-mètre, le sommeil WFI fait chuter la consommation — la datasheet annonce SLEEP ≈ 1,3 mA à 25 °C, dodo-mètre à l'appui.

Erreurs fréquentes

Autres tutoriels pour cette carte

Exemples de code pour cette carte

← Retour à la fiche 🛠 Tous les tutoriels