Vous êtes sur la page 1sur 10

TP2 : Initiation aux Timers

1 Objectif
1. Manipuler les APIs destinées aux Timers,
2. Gérer les interruptions générées par un Timer,
3. Créer un DDS (Direct Digital Synthesizer) à l’aide d’un Timer et une Look-up Table.

2 Principe
Un Timer est un périphérique matériel permettant de mesurer des durées et il est souvent intégré aux
microcontrôleurs. Ils consistent à des registres de 16 ou 32 bit capable de s’auto-charger. Ils peuvent
être utilisés comme des échantillonneurs, ou des générateurs de signaux PWM par exemple.

Le Timer est piloté par un signal horloge qui passe à travers un registre « Pre-scaler » pour diviser
le signal horloge d’entrée. La valeur qui s’auto-recharge à la fin du décompte du Timer détermine
la période du Timer.

La suite du TP sera consacrée à l’utilisation du Timer générique TIM7 du cortex M4 pour créer un
DDS.

3 Création d’un projet


1. Suivre les mêmes étapes du TP initiation aux GPIO pour créer un projet,
2. Sélectionner sous le menu « Project » -> « Manage » -> « Run-Time Environment »,
sélectionner « LED API » et il est important de préciser la board « STM32F4-Discovery ».
Cliquer sur « Resolve » et cocher « Classic » sous « STM32Cube Framework (API) » puis sur
« OK ».
3. Suivre les mêmes étapes du TP initiation aux GPIO pour ajouter les dossiers « sources » et
« headers », ajouter les fichiers « main.c » , « main.h », «stm32f4xx_it.c » et «stm32f4xx_it.h.

4. Cliquer sur l’icône « options for target » , ensuite sur l’onglet « Debug » afin de
configurer les options de la carte cible sur laquelle le programme sera exécuté. Cette fenêtre
fait apparaître deux options de test : par simulation (à gauche), ou par émulation (à droite), en
utilisant la carte STM32F407VG. Sélectionner l’option émulation (à droite), cocher le bouton
« use » et sélectionner « ST-Link Debugger ».

Cliquer sur le bouton « Settings » et vérifier, sous l’onglet « Debug », que le port utilisé et de type
« SW », sinon le changer.

Cliquer sur l’onglet « Flash Download » de la même fenêtre, et vérifier que la taille de la mémoire Flash
de la cible est de 1 M on Chip.
Cliquer sur l’onglet C/C++ et ajouter le macro « HSE_VALUE=8000000 » qui indique la fréquence du
Crystal installé sur la carte à la fonction « SystemClock_Config(); » qui se trouve par défaut dans le
« Template » du « main.c »

Cliquer sur « OK » pour valider les options de configuration du Debugger choisies.

Re-cliquer sur l’icône « options for target » , ensuite sur l’onglet « Debug ». Cliquer sur « Settings »
puis « Trace » changer la fréquence « Core Clock » à 168MHz et cocher la case « Trace Enable » puis
sur « OK ».
A ce stade le code doit être compilable sans fautes.

4 Travail demandé
Partie 1 : Timer

1. Sélectionner sous le menu « Project » -> « Manage » -> « Run-Time Environment ». Cocher
sous TIM (comme Timer) sous Device->HAL_STM32Cuble_HAL, puis appuyer sur Resolve.

2. Dans le fichier « main.c » ajouter l’appel de fonction suivante « LED_Initialize() » et le fichier


« header » nécessaire. Ceci permettra ensuite l’utilisation des LEDs de la carte d’évaluation.
3. Le Timer sera utilisé comme échantillonneur pour cela on va le configurer à une fréquence fe.
On va utiliser le Timer à usage générique TIM7. Le TIM7 est connecté à un bus de fréquence
égale à la fréquence core sur deux, c’est-à-dire 168MHz/2=84MHz. La fréquence de
l’interruption générée par le Timer suit la formule suivante :
finterruption=(fclock Timer/Prescaler)/(Periode Counter +1),
Vérifier que la fréquence fe = finterruption est de 1Hz si on choisit Prescalser = 65535 et Periode
Counter= 1280.
4. Dans le fichier main déclarer une variable globale comme suit :

TIM_HandleTypeDef Tim_Handler_Struct;

5. Puis déclarer une variable locale comme suit :

TIM_Base_InitTypeDef Tim_init_Struct;

6. Dans le fichier « main.c » ajouter les lignes de code suivante pour initialiser le TIM7. Lire
attentivement le code trouver le rôle de chaque instruction.

Tim_init_Struct.ClockDivision=TIM_CLOCKDIVISION_DIV1;
Tim_init_Struct.CounterMode=TIM_COUNTERMODE_UP;
Tim_init_Struct.Period=1280UL;
Tim_init_Struct.Prescaler=65535UL;
Tim_init_Struct.AutoReloadPreload=TIM_AUTORELOAD_PRELOAD_ENABLE;
Tim_Handler_Struct.Init=Tim_init_Struct;
Tim_Handler_Struct.Instance=TIM7;
__TIM7_CLK_ENABLE();
if (HAL_TIM_Base_Init(&Tim_Handler_Struct)== HAL_OK)
{
HAL_TIM_Base_Start_IT(&Tim_Handler_Struct);
}
else
{
Error_Handler();
}

7. Une fois l’interruption du Timer TIM7 est configurée il faut l’activer avec la commande
suivante :

HAL_NVIC_EnableIRQ(TIM7_IRQn);

8. Ajouter la fonction qui servira à gérer l’interruption du Timer TIM7 dans le fichier
« stm32f4xxit.c » comme suit:
extern TIM_HandleTypeDef Tim_Handler_Struct;
void TIM7_IRQHandler(void)
{
HAL_TIM_IRQHandler(&Tim_Handler_Struct);
}

9. Dans le fichier « main.c » ajouter la fonction callback du Timer comme suit :

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)


{
HAL_GPIO_TogglePin(GPIOD,GPIO_PIN_12);
}

10. Compiler le projet appuyer sur « Load » puis sur le bouton « Reset ». Vérifier que la LED0
clignote à chaque seconde.

A ce niveau le Timer TIM7 est configuré pour générer une interruption chaque seconde. Dans la
partie suivante on va ajouter une interface d’entrée sortie pour commander la « DDS ».

Partie 2 : Interface Entrée/Sortie avec PC

1. Sélectionner sous le menu « Project » -> « Manage » -> « Run-Time Environment ». Cocher
STDIN et STDOUT sous Compiler->I/O, choisir ITM, puis appuyer sur Resolve.

2. Dans le fichier « main.c » déclarer une variable locale comme suit :

char c='1';

3. Dans le fichier « main.c » ajouter le code suivant :


/* Infinite loop */
while (1)
{
switch(c)
{
case '1': putchar(c);
putchar('\n');
break ;
case '2': putchar(c);
putchar('\n');
break ;
case '3': putchar(c);
putchar('\n');
break ;
case '4': putchar(c);
putchar('\n');
break ;
default : printf("Choisir un chiffre entre 1-4\n");
break ;
}
c=getchar();
}

4. Compiler le projet, appuyer sur « Crtl+F5 », aller sous le menu « view », puis « serial windows ,
puis « Debug printf viewer »
5. Cliquer sur « Run » ou « F5 ». Puis taper des chiffres entre 0-9 dans la console « Debug printf
viewer ». Vérifier le bon fonctionnement du programme.
Dans la partie suivante on va utiliser l’interface réalisée pour envoyer une commande à la « DDS » et
le Timer TIM7 pour échantillonner une sinusoïde.

Partie 3: Direct Digital Synthesizer (DDS)

L’idée c’est de créer une sinusoïde à partir d’une Look-up table qui contient 32 échantillons sur 2π. La
fréquence d’échantillonnage sera celle du Timer. L’incrément pour parcourir le tableau des
échantillons sera donné par l’interface créée dans la partie 2.

On va choisir 4 incréments différents de 1 à 4 (Delta). Les fréquences possibles qu’on pourra générées
sont :

- f1=fe/32,
- f2=2*fe/32,
- f3=3*fe/32,
- f4=4*fe/32.

1. Déclarer la variable globale suivante qui contient les 32 échantillons d’une sinusoïde quantifiés
sur 12 bits:

const uint16_t Sine12bit[32] = {


2047, 2447, 2831, 3185, 3498, 3750, 3939, 4056, 4095, 4056,
3939, 3750, 3495, 3185, 2831, 2447, 2047, 1647, 1263, 909,
599, 344, 155, 38, 0, 38, 155, 344, 599, 909, 1263, 1647};

2. Ajouter les trois variables globales suivantes :

volatile uint16_t Sin12b;

volatile uint16_t countTimerInterrupt=0;

volatile uint16_t Delta=1;

La première servira comme échantillons qui sera mise à jour à chaque interruption du Timer,
La deuxième sera utilisée comme index pour parcourir la table des échantillons,
La troisième sera utilisée comme incrément pour l’index précèdent.
Le mot clé « volatile » indique au compilateur que ces deux variables peuvent être modifiées
par des interruptions matérielles.

3. Modifier le code du point 3 de la partie 2 pour changer la valeur de « Delta » de 1 à 4. Ensuite,


modifier le code du point 9 de la première partie de la fonction callback pour mettre à jour
l’index « countTimerInterrupt » par l’incrément « Delta » et ainsi lire une nouvelle valeur de
« Sin12b » à partir de la table des échantillons. A l’aide du « logic Analyzer ». Observer
« Sin12b » et « Delta ».

Vous aimerez peut-être aussi