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

RP2040 (placa genérica / 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

Objetivos

Salir del « polling »: en una placa RP2040 genérica sin LED ni botón integrados, quieres reaccionar instantáneamente a un evento externo y despertarte a una hora fija sin bloquear la CPU. El RP2040 proporciona para esto un controlador de interrupciones IO_BANK0 (niveles y flancos en cada GPIO) y un timer de 64 bits con 12 alarmas de hardware (datasheet RP2040). En C (Pico SDK), vas a combinar ambos para un botón limpio: IRQ en el flanco descendente, antirrebote mediante alarma diferida, CPU dormida entre ambos.

Material

Código completo

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

Verificación esperada

Cada pulsación firme cambia el estado del LED una sola vez: la IRQ captura el flanco, la alarma vuelve a verificar el estado 50 ms después e ignora los rebotes (el contacto vibra ~1 ms). Añade un printf en el handler (con stdio_init_all) para confirmar que el __wfi termina correctamente con el evento. En un microamperímetro, el sueño WFI hace caer el consumo — la hoja de datos anuncia SLEEP ≈ 1,3 mA a 25 °C, medidor de sueño mediante.

Errores frecuentes

Otros tutoriales para esta placa

Ejemplos de código para esta placa

← Volver a la ficha 🛠 Todos los tutoriales