Les fonctions qui permettent de contrôler les I/O du STM32 sont pratiques mais, elles sont également très lentes. Ces fonctions ne se limitent pas à imposer le niveau des sorties, elles font aussi quelques vérifications.

Il est possible de contrôler directement les I/O du STM32 en utilisant directement le port de sortie via le registre de sortie (ODR pour Output Data Register).

Pour obtenir l’information sur les différents registres, il faut consulter le manuel de référence sur le site de ST.

lien : www.st.com/resource/en/reference_manual/dm00135183.pdf

Voici un petit code qui permettra de commuter rapidement une sortie.  Sur le NUCLEOF446RE, la LED2 est reliée à PA5. Lors des tests, cette version donnait une période de 80ns, soit une fréquence de 12MHz.

#include "stm32f446xx.h"

#define LED2_INIT RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN; \
        GPIOA->MODER |= GPIO_MODER_MODER5_0
#define LED2_ON (GPIOA->ODR |= 0x0020)
#define LED2_OFF (GPIOA->ODR &= ~0x0020)
#define LED2_TOGGLE (GPIOA->ODR ^= 0x0020)

int main (void)
{
 RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;

 LED2_INIT;
 while (1)
 {
   LED2_ON;
   LED2_OFF;
 }
}

Finalement, il est également possible de faire une méthode hybride, et d’utiliser les fonctions pour l’initialisation et modifier directement les registres pour le contrôle.

#include "stm32f4xx.h"
#include "stm32f4xx_hal_gpio.h"

GPIO_InitTypeDef GPIO_InitStructure;
#define LED2_ON (GPIOA->ODR |= 0x0020)
#define LED2_OFF (GPIOA->ODR &= ~0x0020)

void main(void)
{
   HAL_Init();
   __GPIOA_CLK_ENABLE();
   GPIO_InitStructure.Pin = GPIO_PIN_5;
   GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
   GPIO_InitStructure.Pull = GPIO_PULLUP;
   GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
   HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);

   while (1)
   {
     LED2_ON;
     LED2_OFF;
   }
}