anti_rebond.c

nRF52833-DK (id boards.json : nrf52833-dk) · Fichier : anti_rebond.c · Langage : C · Usage : Anti-rebond logiciel par k_timer

Les boutons mécaniques rebondissent quelques millisecondes : ce patron Zephyr arme un timer de 30 ms sur chaque front et ne valide l’appui que si le bouton est encore actif après le délai. Les rebonds ne déclenchent jamais de double comptage.

Matériel requis

Une carte nRF52833-DK (Nordic, SoC nRF52833 Cortex-M4F, BLE 5) alimentée par USB : 4 LEDs sur P0.13-P0.16 (actives au niveau bas) et 4 boutons sur P0.11, P0.12, P0.24, P0.25 (actifs bas, pull-up interne à activer). La carte seule ; le bouton sw0 (P0.11 sur le DK) et sa LED0 suffisent pour observer le comportement.

Câblage

Aucun câblage. Un bouton externe se câble entre la broche et GND avec le pull-up activé dans l’overlay devicetree.

Fonctionnement

L’ISR ne fait que reprogrammer un k_work 30 ms plus tard (k_work_reschedule annule le précédent). Le travail s’exécute en contexte thread : on peut y printk, compter, envoyer un message.

Exécution

Projet Zephyr : west build -b nrf52833dk/nrf52833 puis west flash (J-Link embarqué) ; console série 115200 sur le connecteur USB UART.

Variantes

Passer à 50 ms pour les boutons robustes, compter les appuis courts/longs avec deux délais, ou factoriser le patron pour les quatre boutons du 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;
}

← Retour à la fiche