usart-reception.c

STM32H7 Nucleo-144 (porte-drapeau : NUCLEO-H743ZI) · Fichier : usart-reception.c · Langage : C · Usage : Recevoir des commandes série par interruption et DMA circulaire

Le DMA circulaire remplit le tampon UART sans jamais interrompre le CPU : la boucle principale découpe le flux en lignes et exécute les commandes ("led" bascule la LED utilisateur). Le patron de référence pour un mini-protocole série réactif.

Matériel requis

Une Nucleo H7 (STM32H743ZI, Cortex-M7 @ 480 MHz) programmee via ST-LINK (USB), broches 3,3 V. Terminal série (115200 8N1) envoyant des lignes texte.

Câblage

Aucun câblage : USART2 relié au convertisseur USB de la carte. Activer le DMA RX de USART2 dans CubeMX.

Fonctionnement

Receive_DMA configure un transfert matériel permanent ; __HAL_DMA_GET_COUNTER indique la position d'écriture. La boucle compare à son propre curseur et découpe sur \r/\n.

Exécution

Projet STM32CubeIDE base sur la Nucleo-H743ZI : le code se glisse dans main.c, les peripheriques se declarent dans le .ioc, puis Run via l'interface ST-LINK. Le moniteur serie du ST-LINK affiche les printf a 115200.

Variantes

Ajouter des commandes typées (LED, ADC, PWM) façon AT, ou traiter la ligne dans l'callback HAL_UARTEx_RxEventCallback avec DMA half/full.

usart-reception.c

// Reception serie non bloquante : DMA circulaire + recherche de lignes.
#include "main.h"
#include <string.h>
#include <stdio.h>

extern UART_HandleTypeDef huart2;
extern DMA_HandleTypeDef hdma_usart2_rx;

#define TAILLE 64
uint8_t tampon[TAILLE];
uint16_t dernierIndice = 0;

static void traiterLigne(const char *ligne) {
  if (strcmp(ligne, "led") == 0) {
    HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);
  } else {
    printf("recu: %s\r\n", ligne);
  }
}

int main(void) {
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_USART2_UART_Init();
  MX_DMA_Init();

  HAL_UART_Receive_DMA(&huart2, tampon, TAILLE); // ne bloque jamais

  for (;;) {
    // Le DMA remplit le tampon en tournant ; on lit ce qui a avance.
    uint16_t indice = TAILLE - __HAL_DMA_GET_COUNTER(huart2.hdmarx);
    while (dernierIndice != indice) {
      uint8_t c = tampon[dernierIndice];
      dernierIndice = (dernierIndice + 1) % TAILLE;
      static char ligne[TAILLE];
      static int n = 0;
      if (c == '\r' || c == '\n') {
        if (n) { ligne[n] = 0; traiterLigne(ligne); n = 0; }
      } else if (n < TAILLE - 1) {
        ligne[n++] = (char)c;
      }
    }
  }
}

← Retour à la fiche