Vous êtes sur la page 1sur 9

TP Informatique embarquée

Direct Memory Access


(DMA)

Anthony Juton – mars 2023

Ce quatrième TP s’intéresse à une fonctionnalité importante des microcontrôleurs : Direct


Memory Access (DMA). Elle sera utilisée en lien avec le convertisseur numérique analogique
(DAC).
Commencer par vérifier l’ensemble de la chaîne de développement, à l’aide du programme de
base fourni sur moodle ou d’un programme du TP précédent. Enlever l’image du projet pour
libérer de la place en mémoire pour le fichier son et gagner en temps de chargement du
programme.

Pour commencer un nouveau projet à partir d’un projet existant, depuis le volet Project Explorer,
copier le projet puis coller le projet. Renommer ensuite le fichier .ioc avec le même nom,
exactement, que le projet. Supprimer le dossier debug et le fichier .launch. Compiler.

1. Principe de Direct Memory Access

Les documents indiqués dans la bibliographie permettent de bien comprendre le convertisseur


numérique analogique des STM32F7 et le DMA.
Q1.1 A partir du diagramme bloc et des chapitres BUS-Matrix et DMA de la datasheet du
STM32F746, expliquer le principe du DMA et réutiliser le schéma bloc et le schéma de la matrice
de bus mémoire pour indiquer le chemin suivi pour une lecture d’échantillons de la mémoire vers
le convertisseur numérique analogique.
Le document
Q1.2 Quels sont les périphériques pouvant exploiter le DMA ?
Q1.3 Rappeler en 5 lignes maximum le principe d’un convertisseur numérique analogique, en
abordant le problème d’alignement des données (cf si besoin le chapitre 16.3.3 DAC data format
du Reference Manual).

2. DMA et conversion numérique analogique

Cette partie amène à mettre en œuvre la sortie analogique avec le DMA, en passant par l’outil
de configuration CubeMX.
L’application visée est de générer un signal sinusoïdal sur la sortie DAC (PA_4), avec 1 fréquence
variable, ce qui permet de générer des notes de musique.
Le convertisseur numérique analogique est un convertisseur 12 bits. Il est connecté en sortie à la
prise BNC X3 et à un amplificateur audio. Un cavalier permet de relier ou non le haut-parleur à
l’amplificateur.

Direct Memory Access (DMA) 1/9


TP Informatique embarquée

2.1. Création de la table signal sinusoïdal


Pour générer le signal sinusoïdal, le microcontrôleur ayant suffisamment de mémoire et un
module de calcul en virgule flottante, on peut créer la table de sinus en RAM (variable globale)
dans la partie du programme principale dédiée à l’initialisation des périphériques :
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
...
#include <math.h>
/* USER CODE END Includes */
...
/* USER CODE BEGIN PV */
uint16_t sinus12bit[360];
/* USER CODE END PV */

/* USER CODE BEGIN 2 */


...
for(i=0; i<360;i++)
{
sinus12bit[i] = 2048 + 1024*sin(i*3.14145/180);
}
/* USER CODE END 2 */

Il est aussi possible de copier une table avec des valeurs pré-calculées (look-up table) en
mémoire programme :
const uint16_t sinus12bit[360]= {2048,2050,...};

2.2. Configuration du DAC via CubeMX


Dans CubeMx, on active la sortie analogique 1.
Le buffer permet de fournir un courant plus important en sortie, il est conseillé si l’impédance
d’entrée du montage suivant est inférieure à 1 MΩ.
Le Trigger cadence le passage d’un échantillon au suivant. Il doit être associé à un timer. Le
timer 7 étant relativement simple et non utilisé, il est parfaitement adapté.

On ajoute un canal DMA pour libérer la CPU de l’envoi du tableau de valeur case par case au
DAC. Pour cela on ajoute le canal 5 du DMA 1 (DMA1_Stream5), c’est celui qui est réservé à la
sortie DAC1.
Pour que le signal se répète une fois le tableau terminé, on choisit le mode Circular.

Direct Memory Access (DMA) 2/9


TP Informatique embarquée

2.3. Configuration du timer 7


On active le timer 7, en mode Update Event et on choisit la période qui séparera chaque
échantillons.
L’onglet Clock configuration indique que les timers (APB1) ont une horloge de base à 100 MHz.
Une counter Period à 1000 correspond donc à une période du timer de 10 µs. Il s’écoulera donc
4µs entre chaque échantillon en sortie, soit une période de 3600 µs pour le sinus de 360 valeurs.

Par ailleurs, pour visualiser la période d’échantillonnage, on active l’interruption

Direct Memory Access (DMA) 3/9


TP Informatique embarquée

2.4. Configuration du DMA


Dans l’onglet NVIC on peut vérifier que l’interruption DMA est bien activée et lui donner une
priorité supérieure à 1. Idem pour l’interruption liée au timer 7.

Direct Memory Access (DMA) 4/9


TP Informatique embarquée

Remarque : le débogueur utilise pour la fonction Serial Wire le timer 6, dont l’interruption est
aussi associée aux erreurs du DAC. Pour travailler avec ce DAC, on gagne en clarté à mettre le
débogueur sur le timer 10 et désactiver l’interruption du timer 6.
Une fois ces configurations terminées, on génère le projet (Project > Generate Code).

3. Le programme

Les configurations étant générées, il reste quelques lignes à ajouter au code.

3.1. Démarrage du timer et du DAC avec DMA


A la suite de l’initialisation de l’écran et de la création du tableau sinus12bit, on ajoute le
démarrage du timer 7, avec activation de son interruption, et du DAC.
/* USER CODE BEGIN 2 */
...
//Démarrage du timer 7 avec interruptions
if (HAL_TIM_Base_Start_IT(&htim7) != HAL_OK) {
Error_Handler();
}
//Démarrage du DAC associé au tableau sinus12bit via le DMA
if (HAL_DAC_Start_DMA(&hdac, DAC_CHANNEL_1, (uint32_t*) sinus12bit, 360,
DAC_ALIGN_12B_R) != HAL_OK) {
Error_Handler();
}
/* USER CODE END 2 */

3.2. Fonctions interruption


Dans la zone suivant le main, on ajoute un changement d’état de led à chaque fin de période du
timer 7 (correspondant à un nouvel échantillon).
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
/* USER CODE BEGIN Callback 0 */

/* USER CODE END Callback 0 */


if (htim->Instance == TIM10) {
HAL_IncTick();
}
/* USER CODE BEGIN Callback 1 */
if (htim->Instance == TIM7) {
HAL_GPIO_TogglePin(LED16_GPIO_Port, LED16_Pin);
}
/* USER CODE END Callback 1 */
}

Dans le fichier stm32f7xx_it.c, On peut ajouter un changement d’état de led à la fonction


d’interruption du DMA.
void DMA1_Stream5_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Stream5_IRQn 0 */

/* USER CODE END DMA1_Stream5_IRQn 0 */


HAL_DMA_IRQHandler(&hdma_dac1);
/* USER CODE BEGIN DMA1_Stream5_IRQn 1 */
HAL_GPIO_TogglePin(LED17_GPIO_Port, LED17_Pin);

Direct Memory Access (DMA) 5/9


TP Informatique embarquée

/* USER CODE END DMA1_Stream5_IRQn 1 */


}

Q3.1 Stopper (Halt) l’exécution du programme et regarder la sortie analogique. Que conclure sur
le fonctionnement du DMA et de la CPU ?
Q3.2 Quelle est la période d’échantillonnage ? Quelle est la période de lancement de
l’interruption du DMA ?

3.3. Personnalisation du programme


Modifier le programme pour jouer des notes différentes suivant les boutons ou l’appui sur l’écran
tactile, l’abscisse pouvant donner la période et l’ordonnée l’intensité par exemple.
Il est possible de changer la période du timer 7 :
htim7.Init.Period = 400 + TS_State.touchX[0];
if (HAL_TIM_Base_Init(&htim7) != HAL_OK)
{
Error_Handler();
}
Pour monter plus haut en fréquence, il faut diminuer le nombre de valeurs du sinus, le passage
sous les 4 µs pour la période du timer7 étant délicat.

4. Utilisation d’un double buffer pour la lecture d’un son

Le format wav est un format non compressé comme le format bmp.


Utiliser la fonction wav2c proposée par la page web :
https://guilhermerodrigues680.github.io/wav2c-online/

Un fichier angele_wav.h est disponible sinon.

Q4.1 Expliquer avec un schéma le principe du double buffer pour envoyer un morceau de


musique sur le DAC via le DMA.

4.1. Configuration du DMA et du timer


Modifier la configuration du timer7 pour avoir une période d’échantillognnage correspondant au
morceau de musique :

Direct Memory Access (DMA) 6/9


TP Informatique embarquée

Modifier la configuration du DMA pour avoir une interruption au remplissage de la moitié du


buffer.

Direct Memory Access (DMA) 7/9


TP Informatique embarquée

4.2. Fonctions interruptions


Ajouter les fonctions d’interruption correspondant au DMA atteignant le demi-buffer ou le buffer :
/* USER CODE BEGIN 4 */
void HAL_DAC_ConvHalfCpltCallbackCh1(DAC_HandleTypeDef *hdac) {
HAL_GPIO_TogglePin(LED18_GPIO_Port, LED18_Pin);
}

void HAL_DAC_ConvCpltCallbackCh1(DAC_HandleTypeDef *hdac) {

}
/* USER CODE END 4 */
4.3. Personnalisation du programme
Ajouter le code nécessaire avec le buffer (2 tableau pour chaque demi-buffer) et son
remplissage.

Q4.2 Donner le code commenté

5. Bibliographie

Les documents ST (disponibles sur www.ST.com ) :

• Datasheet et Manuel de référence du micro-contrôleur STM32F746NG :

https://www.st.com/resource/en/datasheet/stm32f746ng.pdf

https://www.st.com/resource/en/reference_manual/rm0385-stm32f75xxx-and-
stm32f74xxx-advanced-armbased-32bit-mcus-stmicroelectronics.pdf

• AN3126 Audio and waveform generation using the DAC in STM32 products (avec
notamment un paragraphe Using the DAC to implement an audio player)

• AN4031 Using the STM32F2, STM32F4 and STM32F7 Series DMA controller

Le site GitHub de ST : https://github.com/STMicroelectronics

La chaîne YouTube de ST : https://www.youtube.com/c/stmicroelectronics avec notamment :


• STM32F7 Analog - DAC : https://www.youtube.com/watch?v=5SlR1WSQfXM
• STM32F7 System – DMA : https://www.youtube.com/watch?v=um0CkYSpDvY

Le forum ST : https://community.st.com

La documentation FreeRTOS : Mastering the FreeRTOS™Real Time Kernel sur le site


https://freertos.org/

Direct Memory Access (DMA) 8/9


TP Informatique embarquée

6. Evaluation

Q1.1 Principe du DMA
Q1.2 Périphériques pouvant exploiter le DMA ?
Q1.3 Principe d’un convertisseur numérique analogique,
Q3.1 Stop exécution. Que conclure sur le fonctionnement du DMA et de la CPU ?
Q3.2 Quelle est la période d’échantillonnage ?
Quelle est la période de lancement de l’interruption du DMA ?
Q4.1 Principe du double buffer.
Q4.2 Donner le code commenté

Direct Memory Access (DMA) 9/9

Vous aimerez peut-être aussi