Cet article vise à présenter l'application du mode DMA2D à l'aide de la carte de développement STM32H563. Le mode DMA 2D signifie que le DMA peut ajuster dynamiquement le mode d'adressage et la capacité du DMA en définissant à l'avance le décalage d'adressage intra-bloc et le décalage d'adressage de bloc. En d'autres termes, lorsque le DMA effectue une transmission de données, l'adressage intra-bloc n'est plus toujours fixe pour être stocké de manière adjacente, mais l'intervalle d'adresse pour accéder aux données lors de deux transmissions adjacentes peut être déterminé par programmation. Pour les transferts de blocs répétitifs, il ne s'agit plus simplement de redémarrer à chaque fois à partir de la même position, mais l'adresse de départ du nouveau transfert peut être ajustée en fonction du décalage de l'adresse du bloc.
Le principe de la transmission DMA 2D
Supposons que trois transferts soient lancés pour la même requête DMA, correspondant à trois blocs de transfert DMA.

Comme le montre la figure ci-dessus, 5 données marquées en rouge [c'est-à-dire le premier bloc] sont transmises pour la première fois, et l'accès aux données s'effectue conformément à la figure. Les deuxième et troisième fois sont également similaires à la première fois, et 5 données vertes [c'est-à-dire le deuxième bloc] et 5 données bleues [c'est-à-dire le troisième bloc] sont transmises respectivement. De toute évidence, les règles d'accès aux données dans chaque bloc de transmission sont les mêmes, avec deux espaces de stockage séparés par deux. Dans le même temps, lorsque la deuxième transmission est lancée après la fin de la première transmission, ou lorsque la troisième transmission est lancée après la fin de la deuxième transmission, l'adresse de départ est reculée de 14 espaces d'adresse par rapport à la position actuelle avant le démarrage.
Comment utiliser la fonction DMA 2D ?
Dans cet exemple, nous utilisons la carte Nucleo STM32H563ZI. Et l'USART3 de la puce doit être connecté au VCP du STLINK intégré. Utilisez l'assistant de débogage du port série côté PC pour distribuer trois ensembles de données au MCU par lots, dont le contenu est 5 caractères R, 5 caractères G et 5 caractères B. Activez la fonction DMA 2D reçue par USART3.
À titre de rappel, tous les canaux du GPDMA de la série STM32H5 ne prennent pas en charge la fonction d'adressage DMA 2D. La prise en charge de la fonction 2D par le canal DMA est clairement indiquée dans l'interface de configuration CubeMx. Si vous utilisez la configuration CubeMx, vous pouvez choisir les mots appropriés. Ici, je choisis le DMA CH6 du GPDMA1, qui prend en charge la fonction DMA 2D.
La configuration de base pour utiliser STM32CubeMX est la suivante :

Notre configuration se concentre sur l'adressage 2D, dont les détails sont les suivants :
Il s'agit maintenant de la réception USART3DMA. L'adresse source est évidemment fixe, c'est-à-dire le registre de réception de données USART3. Le décalage lié à l'adresse source est donc ici de 0. L'adresse de destination de l'accès DMA est la mémoire, qui est variable. Chaque fois qu'une donnée est stockée dans le bloc, elle est décalée de deux positions vers l'avant, ce qui correspond à la valeur de décalage d'adresse de destination ci-dessous. Lorsque le cycle de transmission suivant commence après la fin de chaque transmission de bloc, l'adresse de départ est exactement 14 positions en arrière, ce qui correspond à la valeur de décalage d'adresse de destination de bloc suivante, l'arrière étant négatif et l'avant positif. Ici, un total de 3 transferts de blocs sont répétés, ce qui correspond à la valeur du compteur de répétition ci-dessous.

En fait, après 3 cycles de transmission répétée par bloc DMA, les données reçues ressemblent au motif indiqué par la flèche dans la figure ci-dessous.

Utilisez STM32CubeMx pour terminer la configuration, ajoutez le code utilisateur pour déboguer et vérifier. Le code utilisateur qui doit être ajouté manuellement est principalement les deux lignes suivantes :
__HAL_LINKDMA(&huart3, hdmarx, handle_GPDMA1_Channel6);
HAL_UART_Receive_DMA(&huart3,(uint8_t *)aRxBuffer, 5); //Receive 5 data per block
La figure suivante présente le résultat obtenu après débogage. Grâce à trois réceptions DMA indépendantes, les données sont régulièrement stockées dans l'ordre RVB.




