Aller au contenu

GPIO

Le STM32F412ZG possède jusqu’à 114 entrées et sorties de type GPIO (General Purpose Input/Output) regroupées sur 7 ports (A, B, C, D, E, F, G et H). Les ports A à G possèdent 16 entrées/sorties et le port H n’en possède que 2.

Le STM32F412ZG fonctionne en 3.3V et les broches des GPIOs configurées en sortie donnent soit 0V, soit 3.3V. Les broches configurées en entrées sont capables de supporter des tensions jusqu’à 5V. On dit que ces broches sont “5V tolerant” et c’est très pratique pour lire des signaux provenant de périphériques qui fonctionnent avec 5V.

La figure ci-dessous illustre les composants et le fonctionnement d’une broche GPIO tolérante à 5V :

GPIO

Les broches du GPIO peuvent également être configurées pour lire des tensions analogiques, mais nous n’utilisons pas cette fonctionnalité dans ce cours. Pour plus d’information à ce sujet, référez-vous à la documentation du microcontrôleur STM32F412ZG.

Utilisation avec STM32Cube

La bibliothèque STM32Cube offre les fonctions suivantes pour utiliser les GPIOS:

  • HAL_GPIO_Init()
  • HAL_GPIO_DeInit()
  • HAL_GPIO_ReadPin()
  • HAL_GPIO_WritePin()
  • HAL_GPIO_TogglePin()

STM32Cube

Étudiez le chapitre 31 (HAL GPIO Generic Driver / page 412) du manuel UM1725 : “Description of STM32F4 HAL and low-layer drivers”.

Interface Orientée Objet

Dans le cours Architecture des Ordinateurs, nous avons implémenté une classe Led pour encapsuler le comportement d’une LED connectée à une sortie GPIO. Nous pouvons implémenter une classe plus générique pour gérer une sortie digitale :

class DigitalOut {
   public:
    explicit DigitalOut(GPIO_TypeDef* port, uint16_t pin);
    ~DigitalOut();
    void Write(GPIO_PinState value);
    void Toggle();
    DigitalOut& operator=(int value);
    DigitalOut& operator=(const DigitalOut& rhs);
    operator int();

   private:
    GPIO_TypeDef* port_;
    uint16_t pin_;
};

Dans le constructeur, n’oubliez pas d’activer l’horloge sur le port GPIO correspondant. STM32Cube ne propose pas de méthode simple pour cette opération et on peut réaliser cette opération avec une longue liste de if, elsif :

if (port == GPIOA) {
  if (__HAL_RCC_GPIOA_IS_CLK_DISABLED) { __HAL_RCC_GPIOA_CLK_ENABLE(); }
} else if (port == GPIOB) {
  if (__HAL_RCC_GPIOB_IS_CLK_DISABLED) { __HAL_RCC_GPIOB_CLK_ENABLE(); }
} else if (port == GPIOC) {
  if (__HAL_RCC_GPIOC_IS_CLK_DISABLED) { __HAL_RCC_GPIOC_CLK_ENABLE(); }
...