TPs STM32F4 - 11 Projets Pratiques HAL | BTS EII

TPs STM32F4

11 Projets Pratiques avec HAL

STM32CubeIDE HAL Library BTS 2025-2026
💡

TP1 : GPIO Output - LED Clignotante

Configuration CubeMX et HAL

2h Debutant HAL_GPIO

Objectifs pedagogiques

  • Creer un projet STM32CubeIDE
  • Configurer les GPIO avec CubeMX
  • Utiliser HAL_GPIO_WritePin et HAL_GPIO_TogglePin
  • Compiler et flasher le programme

Configuration CubeMX

  1. File - New - STM32 Project
  2. Selectionner STM32F407VG (Discovery) ou STM32F401RE (Nucleo)
  3. Pinout: PA5 - GPIO_Output (LED sur Nucleo)
  4. Clock: HSE 8MHz, SYSCLK 168MHz (F407) ou 84MHz (F401)
  5. Project Manager - Generate Code
  STM32F407 Discovery        STM32F401 Nucleo
  +------------------+      +------------------+
  |                  |      |                  |
  | LED Verte:  PD12 |      | LED User:  PA5   |
  | LED Orange: PD13 |      | Bouton:    PC13  |
  | LED Rouge:  PD14 |      |                  |
  | LED Bleue:  PD15 |      |                  |
  |                  |      |                  |
  | Bouton:     PA0  |      |                  |
  +------------------+      +------------------+

Code HAL - main.c

/* TP1 : Clignotement LED - STM32F4 */

/* USER CODE BEGIN WHILE */
while (1)
{
    // Methode 1 : Toggle
    HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
    HAL_Delay(500);  // 500ms
    
    /* USER CODE END WHILE */
}

Version avec WritePin

while (1)
{
    // Allumer LED
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);
    HAL_Delay(1000);
    
    // Eteindre LED
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
    HAL_Delay(1000);
}

Exercices

  1. Faire clignoter les 4 LEDs du Discovery en sequence
  2. Creer un chenillard (Knight Rider)
  3. Signal SOS en morse
🔘

TP2 : GPIO Input et Interruptions

Lecture bouton avec EXTI

2h Debutant HAL_EXTI

Objectifs pedagogiques

  • Configurer une entree GPIO avec pull-up/pull-down
  • Configurer une interruption externe EXTI
  • Implementer le callback d'interruption
  • Comprendre le debouncing materiel et logiciel

Configuration CubeMX

  1. PC13 (Nucleo) ou PA0 (Discovery) - GPIO_EXTI
  2. GPIO mode: External Interrupt with Rising/Falling edge
  3. Pull: Pull-up (pour bouton actif bas)
  4. NVIC: Activer EXTI line[15:10] (ou EXTI0)

Code : Lecture Polling

/* Lecture bouton par polling */
while (1)
{
    if (HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13) == GPIO_PIN_RESET)
    {
        HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
        HAL_Delay(200);  // Anti-rebond
    }
}

Code : Interruption EXTI

/* Callback d'interruption EXTI */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    if (GPIO_Pin == GPIO_PIN_13)
    {
        HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
    }
}

/* Note: Ne pas utiliser HAL_Delay() dans une IT ! */
!
Anti-rebond

Pour un debouncing logiciel en interruption, utilisez un timer ou une variable volatile avec timestamp.

📊

TP3 : ADC - Conversion Analogique

Lecture potentiometre et capteurs

2h Intermediaire HAL_ADC

Objectifs pedagogiques

  • Configurer l'ADC en mode polling
  • Configurer l'ADC en mode interruption
  • Comprendre la resolution (12 bits = 0-4095)
  • Convertir la valeur ADC en tension

Configuration CubeMX

  1. PA0 - ADC1_IN0
  2. ADC1 - Enable
  3. Resolution: 12 bits
  4. Sampling Time: 84 cycles

Code : ADC Polling

uint32_t adc_value;
float voltage;

while (1)
{
    HAL_ADC_Start(&hadc1);
    HAL_ADC_PollForConversion(&hadc1, 100);
    adc_value = HAL_ADC_GetValue(&hadc1);
    
    // Convertir en tension (3.3V ref)
    voltage = (adc_value * 3.3f) / 4095.0f;
    
    HAL_Delay(100);
}

Code : ADC avec Interruption

volatile uint32_t adc_value;

/* Demarrer conversion en IT */
HAL_ADC_Start_IT(&hadc1);

/* Callback fin de conversion */
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
    if (hadc == &hadc1)
    {
        adc_value = HAL_ADC_GetValue(&hadc1);
        HAL_ADC_Start_IT(&hadc1);
    }
}
🌊

TP4 : PWM - Modulation de Largeur

Controle LED RGB et servomoteur

3h Intermediaire HAL_TIM_PWM

Objectifs pedagogiques

  • Configurer un timer en mode PWM
  • Calculer prescaler et ARR pour la frequence
  • Varier le rapport cyclique (CCR)
  • Commander une LED RGB et un servomoteur

Configuration CubeMX

  1. TIM2 - Channel 1 - PWM Generation CH1
  2. PA5 - TIM2_CH1 (alternate function)
  3. Prescaler: 84-1 (1MHz avec 84MHz)
  4. Counter Period (ARR): 1000-1 (1kHz PWM)
i
Formule PWM

f_PWM = f_CLK / ((PSC+1) x (ARR+1))

Code : PWM pour LED

/* Demarrer PWM */
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);

while (1)
{
    // Augmenter luminosite
    for (int duty = 0; duty <= 1000; duty += 10)
    {
        __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, duty);
        HAL_Delay(10);
    }
    
    // Diminuer luminosite
    for (int duty = 1000; duty >= 0; duty -= 10)
    {
        __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, duty);
        HAL_Delay(10);
    }
}

Application : Servomoteur

/* Servomoteur : PWM 50Hz, pulse 1-2ms */
// PSC = 84-1, ARR = 20000-1 = 50Hz
// CCR = 1000 = 1ms (0 deg)
// CCR = 1500 = 1.5ms (90 deg)
// CCR = 2000 = 2ms (180 deg)

void Servo_SetAngle(uint8_t angle)
{
    uint16_t ccr = 1000 + (angle * 1000) / 180;
    __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, ccr);
}
📡

TP5 : UART - Communication Serie

Communication avec PC via terminal

3h Intermediaire HAL_UART

Objectifs pedagogiques

  • Configurer UART avec baudrate 115200
  • Transmettre des donnees vers le PC
  • Recevoir des commandes du PC
  • Rediriger printf vers UART

Configuration CubeMX

  1. USART2 - Asynchronous (connecte au ST-Link)
  2. Baud Rate: 115200
  3. Word Length: 8 bits
  4. Parity: None, Stop Bits: 1
  5. NVIC: USART2 global interrupt - Enable

Code : Transmission UART

char msg[] = "Hello STM32!\r\n";

/* Transmission bloquante */
HAL_UART_Transmit(&huart2, (uint8_t*)msg, strlen(msg), 100);

/* Avec sprintf */
char buffer[64];
sprintf(buffer, "ADC = %lu, Temp = %.1f C\r\n", adc_value, temp);
HAL_UART_Transmit(&huart2, (uint8_t*)buffer, strlen(buffer), 100);

Redirection printf

#include <stdio.h>

int __io_putchar(int ch)
{
    HAL_UART_Transmit(&huart2, (uint8_t*)&ch, 1, 100);
    return ch;
}

/* Utilisation */
printf("Temperature: %.2f C\r\n", temperature);

Code : Reception UART avec Interruption

uint8_t rx_data;

/* Activer la reception */
HAL_UART_Receive_IT(&huart2, &rx_data, 1);

/* Callback de reception */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    if (huart == &huart2)
    {
        if (rx_data == '1')
            HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);
        else if (rx_data == '0')
            HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
        
        HAL_UART_Receive_IT(&huart2, &rx_data, 1);
    }
}

TP6 : Timer - Interruptions Periodiques

Base de temps precise

2h Intermediaire HAL_TIM

Configuration CubeMX

  1. TIM3 - Clock Source: Internal Clock
  2. Prescaler: 8400-1 (pour 10kHz avec 84MHz)
  3. Counter Period: 10000-1 (pour 1Hz = 1s)
  4. NVIC: TIM3 global interrupt - Enable

Code : Timer Interrupt

volatile uint32_t seconds = 0;

/* Demarrer le timer en mode IT */
HAL_TIM_Base_Start_IT(&htim3);

/* Callback d'interruption Timer */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if (htim == &htim3)
    {
        seconds++;
        HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
    }
}

/* Dans main loop */
while (1)
{
    printf("Temps: %lu s\r\n", seconds);
    HAL_Delay(1000);
}
📺

TP7 : I2C - Ecran LCD 16x2

Communication I2C avec peripherique

3h Intermediaire HAL_I2C

Configuration CubeMX

  1. I2C1 - I2C
  2. PB6 - I2C1_SCL, PB7 - I2C1_SDA
  3. Speed Mode: Standard (100kHz)
  4. Clock Speed: 100000

Code : LCD I2C

#define LCD_ADDR  (0x27 << 1)

void LCD_SendCommand(uint8_t cmd)
{
    uint8_t data[4];
    data[0] = (cmd & 0xF0) | 0x0C;
    data[1] = (cmd & 0xF0) | 0x08;
    data[2] = ((cmd << 4) & 0xF0) | 0x0C;
    data[3] = ((cmd << 4) & 0xF0) | 0x08;
    HAL_I2C_Master_Transmit(&hi2c1, LCD_ADDR, data, 4, 100);
}

void LCD_Init(void)
{
    HAL_Delay(50);
    LCD_SendCommand(0x30); HAL_Delay(5);
    LCD_SendCommand(0x30); HAL_Delay(1);
    LCD_SendCommand(0x30);
    LCD_SendCommand(0x20);  // 4-bit mode
    LCD_SendCommand(0x28);  // 2 lines
    LCD_SendCommand(0x0C);  // Display ON
    LCD_SendCommand(0x06);  // Entry mode
    LCD_SendCommand(0x01);  // Clear
}
🔄

TP8 : SPI - Communication Haute Vitesse

Lecture carte SD ou capteur

3h Avance HAL_SPI

Configuration CubeMX

  1. SPI1 - Full-Duplex Master
  2. PA5 - SCK, PA6 - MISO, PA7 - MOSI
  3. PA4 - GPIO_Output (CS)
  4. Prescaler: 16 (pour ~5MHz)

Code : SPI Transmit/Receive

#define CS_LOW()  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET)
#define CS_HIGH() HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET)

uint8_t SPI_Transfer(uint8_t data)
{
    uint8_t rx;
    HAL_SPI_TransmitReceive(&hspi1, &data, &rx, 1, 100);
    return rx;
}

uint8_t SPI_ReadRegister(uint8_t reg)
{
    uint8_t value;
    CS_LOW();
    SPI_Transfer(reg | 0x80);
    value = SPI_Transfer(0x00);
    CS_HIGH();
    return value;
}

TP9 : DMA - Transfert Sans CPU

ADC et UART avec DMA

3h Avance HAL_DMA

Configuration CubeMX - ADC avec DMA

  1. ADC1 - DMA Settings - Add - ADC1
  2. Mode: Circular
  3. Data Width: Half Word (16 bits)
  4. ADC: Continuous Conversion - Enable

Code : ADC avec DMA

uint16_t adc_buffer[100];

/* Demarrer ADC + DMA */
HAL_ADC_Start_DMA(&hadc1, (uint32_t*)adc_buffer, 100);

/* Callback transfert complet */
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
    // Traiter adc_buffer[50..99]
}

/* Callback demi-transfert */
void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc)
{
    // Traiter adc_buffer[0..49]
}
🔀

TP10 : FreeRTOS - Multitache

Introduction au temps reel

4h Avance CMSIS-RTOS

Configuration CubeMX

  1. Middleware - FreeRTOS - CMSIS_V2
  2. Tasks and Queues - Add Task
  3. Task Name: Task_LED, Priority: Normal
  4. Stack Size: 128 words

Code : Deux Taches FreeRTOS

/* Tache 1 : Clignotement LED */
void Task_LED(void *argument)
{
    for(;;)
    {
        HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
        osDelay(500);
    }
}

/* Tache 2 : Envoi UART */
void Task_UART(void *argument)
{
    uint32_t count = 0;
    char msg[32];
    
    for(;;)
    {
        sprintf(msg, "Count: %lu\r\n", count++);
        HAL_UART_Transmit(&huart2, (uint8_t*)msg, strlen(msg), 100);
        osDelay(1000);
    }
}
🏆

TP11 : Projet Final - Station Meteo

Integration de tous les concepts

6h Avance Projet Complet

Cahier des charges

  • Lire temperature (DHT11) et luminosite (LDR)
  • Afficher sur LCD I2C 16x2
  • Envoyer donnees via UART vers PC
  • Alarme LED si temperature superieure au seuil
  • LED RGB pour indiquer le niveau de luminosite

Architecture du Projet

  +-----------------------------------------------------------+
  |                 STATION METEO STM32                       |
  +-----------------------------------------------------------+
  |  +------+            +----------+          +------+       |
  |  |DHT11 |---PA4------|          |---PA5----|  LED |       |
  |  +------+            |          |          +------+       |
  |  +------+            | STM32F4  |          +------+       |
  |  | LDR  |---ADC1-----|  401/407 |---TIM2---|LED RGB|      |
  |  +------+            |          |          +------+       |
  |                      +----+-----+                         |
  |                           |                               |
  |                      +----+----+                          |
  |                      |  I2C1   |                          |
  |                      | LCD16x2 |                          |
  |                      +---------+                          |
  |                           |                               |
  |                      +----+----+                          |
  |                      |  UART2  |--- Terminal PC           |
  |                      +---------+                          |
  +-----------------------------------------------------------+

Criteres d'evaluation

CriterePoints
Configuration CubeMX correcte/3
Lecture capteurs fonctionnelle/4
Affichage LCD/3
Communication UART/3
Alarmes et LEDs/3
Code propre et commente/2
Rapport de TP/2
Total/20

TPs STM32F4 - 11 Projets Pratiques avec HAL