anti_rebond.c

nRF52833-DK (id de boards.json: nrf52833-dk) · Archivo : anti_rebond.c · Lenguaje : C · Uso : Anti-rebond logiciel par k_timer

Los botones mecánicos rebotan unos milisegundos: este patrón Zephyr arma un timer de 30 ms en cada flanco y solo valida la pulsación si el botón sigue activo tras el retardo. Los rebotes nunca provocan doble conteo.

Hardware

Una placa nRF52833-DK (Nordic, SoC nRF52833 Cortex-M4F, BLE 5) alimentada por USB: 4 LED en P0.13-P0.16 (activos a nivel bajo) y 4 botones en P0.11, P0.12, P0.24, P0.25 (activos a bajo, pull-up interno a activar). Solo la placa; el botón sw0 (P0.11 en el DK) y su LED0 bastan para observar el comportamiento.

Cableado

Sin cableado. Un botón externo va entre el pin y GND con el pull-up activado en el overlay devicetree.

Funcionamiento

La ISR solo reprograma un k_work 30 ms después (k_work_reschedule cancela el anterior). El trabajo corre en contexto de hilo: printk, contar o mandar mensajes valen.

Ejecución

Proyecto Zephyr: west build -b nrf52833dk/nrf52833 y luego west flash (J-Link embarcado); consola serie 115200 en el conector USB UART.

Variantes

Pasar a 50 ms para botones robustos, contar pulsaciones cortas/largas con dos retardos, o factorizar el patrón para los cuatro botones del DK.

anti_rebond.c

/* Anti-rebond : appui valide si le bouton est encore actif
 * 30 ms apres le front (k_work_reschedule). */
#include <zephyr/kernel.h>
#include <zephyr/drivers/gpio.h>

static const struct gpio_dt_spec btn =
	GPIO_DT_SPEC_GET(DT_ALIAS(sw0), gpios);
static const struct gpio_dt_spec led =
	GPIO_DT_SPEC_GET(DT_ALIAS(led0), gpios);
static struct gpio_callback cb_data;
static struct k_work travail;

static void valide(struct k_work *w)
{
	ARG_UNUSED(w);
	if (gpio_pin_get_dt(&btn) == 1) {
		gpio_pin_toggle_dt(&led);
		printk("Appui valide\n");
	}
}

static void sur_front(const struct device *port,
		      struct gpio_callback *cb, uint32_t pins)
{
	ARG_UNUSED(port); ARG_UNUSED(cb); ARG_UNUSED(pins);
	k_work_reschedule(&travail, K_MSEC(30));
}

int main(void)
{
	k_work_init(&travail, valide);
	gpio_pin_configure_dt(&led, GPIO_OUTPUT_INACTIVE);
	gpio_pin_configure_dt(&btn, GPIO_PULL_UP);
	gpio_pin_interrupt_configure_dt(&btn, GPIO_INT_EDGE_BOTH);
	gpio_init_callback(&cb_data, sur_front, BIT(btn.pin));
	gpio_add_callback(btn.port, &cb_data);

	while (1) {
		k_msleep(100);
	}
	return 0;
}

← Volver a la ficha