bouton-hal.c

STM32F103 "Blue Pill" (STM32F103C8T6) · Fichier : bouton-hal.c · Langage : C · Usage : Lire un bouton avec anti-rebond et allumer la LED

Le bouton utilisateur de la carte (GPIOA/GPIO_PIN_0, actif HIGH) bascule la LED à chaque appui. L'anti-rebond par échantillonnage à 50 Hz est le patron standard en C embarqué, sans interruption ni temporisation bloquante.

Matériel requis

Une Blue Pill STM32F103C8T6 (Cortex-M3 @ 72 MHz, 64 Ko flash) alimentee par micro-USB ou 3,3 V externe ; programmation SWD ou bootloader serie. Rien pour commencer : le bouton utilisateur est câblé en usine. En option, un bouton externe vers 3,3 V.

Câblage

Bouton interne : déjà relié à GPIOA/GPIO_PIN_0 (bouton externe vers 3,3 V, la carte n'a pas de bouton utilisateur). Bouton externe : entre la broche et 3,3 V, résistance interne en pull-down.

Fonctionnement

Toutes les 20 ms, l'état de la broche est lu et mémorisé ; un passage 0→1 (front montant) déclenche HAL_GPIO_TogglePin. Deux échantillons consécutifs identiques filtrent les rebonds.

Exécution

Projet STM32CubeIDE (STM32F103C8) ou Arduino (core STM32) : programmer par SWD (ST-LINK, adaptateur DAPLink) ou par le bootloader serie (BOOT0 a 1). Attention : LED PC13 active LOW.

Variantes

Passer en interruption EXTI avec callback HAL_GPIO_EXTI_Callback, ou ajouter un appui long (compteur d'échantillons).

bouton-hal.c

// Bouton utilisateur + LED, anti-rebond par echantillonnage.
#include "main.h"

#define LED_PORT GPIOC
#define LED_PIN  GPIO_PIN_13
#define BTN_PORT GPIOA
#define BTN_PIN  GPIO_PIN_0
/* Bouton actif a l'etat HIGH. */

uint32_t tEchantillon = 0;
uint8_t stable = 0, precedent = 0;

int main(void) {
  HAL_Init();
  SystemClock_Config();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOD_CLK_ENABLE();

  GPIO_InitTypeDef g = {0};
  g.Pin = LED_PIN; g.Mode = GPIO_MODE_OUTPUT_PP;
  HAL_GPIO_Init(LED_PORT, &g);
  g.Pin = BTN_PIN; g.Mode = GPIO_MODE_INPUT; g.Pull = GPIO_PULLDOWN;
  HAL_GPIO_Init(BTN_PORT, &g);

  for (;;) {
    if (HAL_GetTick() - tEchantillon >= 20) {   // 50 Hz
      tEchantillon = HAL_GetTick();
      precedent = stable;
      stable = (HAL_GPIO_ReadPin(BTN_PORT, BTN_PIN) == GPIO_PIN_SET);
      if (stable && !precedent) {               // front montant
        HAL_GPIO_TogglePin(LED_PORT, LED_PIN);
      }
    }
  }
}

← Retour à la fiche