Vous êtes sur la page 1sur 36

CONVENTIONS :

BD : BOUTON DROIT DE LA SOURIS


BG : BOUTON GAUCHE

pour le partiel de TP :
savez vous :
créer un projet ? De quels fichiers il est constitué ? Quel est le processeur utilisé ? Quel
fichier doit être impérativement situé dans votre répertoire de travail ?

Modifier une réponse impulsionnelle dans le fichier convolution ?

Attribuer une case mémoire, à une variable, à un tableau et y accéder dans le


programme ?

Choisir la synchro du scope :


voie, niveau, réjection HF
utiliser correctement le mode averaging
utiliser les options de mesure (crete à crete...)
faire un calcul de gain en dB
faire un relevé de Bode

IUT1 GRENOBLE RT TRC1 TSN TP DSP 2015-2016 p.1/49


TP1: Présentation de VisualDSP++

http://www.analog.com/processors/testdrive

Il est possible, à partir de ce lien, et en s’enregistrant, d’obtenir une version limitée à 90


jours du logiciel utilisé dans ces TP (visual DSP 5).
N’attendez pas le dernier moment !

RAPPEL DE PRINCIPE:
Le travail demandé est normalement explicitement indiqué, sur fond rose: ne considérez
donc pas comme « à faire » les explications qui vous permettront de réaliser le travail
demandé dans un second temps.

Relier le KIT à l’alimentation, puis au PC par la prise USB en façade

Lancement de Visual DSP++:


Dans « Tous les programmes »
Electronique et Info Indus
visualDSP ++ 5.0
visualDSP++ environnement
il faut choisir une session :
session
New session
ADSP-21369
Next next next finish
Il faut un certain temps pour que le logiciel échange avec le KIT

1. Utilisation d’un projet existant :


Récupérer sur P:\TRC1
Le répertoire « intro TP1 » dans son intégralité et placez le dans un répertoire personnel
(sur Z :).

IUT1 GRENOBLE RT TRC1 TSN TP DSP 2015-2016 p.2/49


Dans le logiciel Visual DSP : File \ Open Project ouvrir le fichier intro TP1.dpj, qui se
trouve dans le répertoire copié.
La structure du projet apparaît dans le cadre de gauche.
Il est constitué de plusieurs fichiers, de natures différentes :
Fichiers sources :
intro TP1.asm qui contient le programme proprement dit
21369_IVT.asm c’est lui qui lance l’exécution de votre programme : la
fonction _main.
Linker files :
ADSP-21369-EZKIT.LDF, qui contient les adresses des différentes zones
mémoires du système : sections : seg_dmda, seg_pmco…
Si le fichier « intro TP1.asm » n’est pas ouvert dans la fenêtre centrale, éditeur de texte,
ouvrez-le en double cliquant sur son nom dans le projet.

Traduction du programme (langage assembleur) en code machine binaire et


chargement en mémoire : touche F7
Une action sur la touche F7 provoque :
la traduction des mnémoniques écrites dans les fichiers sources en code
binaire pour le DSP.
Puis, SI LE PROGRAMME EST SANS ERREURS, le transfert de ces codes
d’instructions et des données dans la mémoire conformément aux
indications fournies dans le programme et à celles du fichier .LDF.

Si aucune erreur n’a été trouvée une nouvelle fenêtre est ouverte sur la droite, nommée
Disassembly, montrant les instructions dans la mémoire PM avec les adresses (en vert).
Une flèche jaune indique l’instruction prête à être exécutée : début du programme à
l’adresse 0x90100.

Dans la fenêtre de l’éditeur la même flèche et un rond rouge sont apparus, indiquant aussi
l’instruction prête à être exécutée.

Visualisation du contenu de la mémoire programme : three column (48 bits)


Dans le menu Memory choisir Three Column.
Une fenêtre s’ouvre sur la droite, il faut modifier l’adresse pour voir apparaître les codes
des instructions du programme: dans la case située sous le bandeau (program memory)
entrez 90100

IUT1 GRENOBLE RT TRC1 TSN TP DSP 2015-2016 p.3/49


Une action sur BD permet de choisir, Select format, le format d’affichage, notamment :
Assembly, hexadécimal, binary. A quoi correspondent ces affichages ?

Visualisation du contenu de la mémoire données : two column (32 bits)


Dans le menu Memory choisir Two Column.
Normalement la fenêtre s’ouvre à l’emplacement des premières variables : a, b et x

Lancement du programme depuis la position en cours : touche F5


L’utilisation de la touche F5 permet de lancer l’exécution du programme à partir de
l’adresse contenue dans le registre PC, la flèche jaune indique cette position dans la
mémoire.

Si vous actionnez F5 alors que la compilation par F7 a généré des erreurs :


Le programme exécuté est celui précédemment compilé et chargé

Le programme est exécuté à la vitesse de 400 MIPS (millions d’instructions à la seconde).


Le temps apparent d’exécution est celui des échanges entre le kit et le PC :
envoi de l’ordre d’exécution,
lancement du programme par le programme de gestion du kit, exécution
une fois terminé : envoi de toutes les valeurs des registres et zones mémoire DM
du kit vers le PC.

Arrêt du programme : touches SHIFT et F5


Ajouter l’instruction suivante avant RTS ; :
Jump (pc,0) ; // saut sur place, boucle sans fin sur cette instruction
Après lancement du programme le message « running » clignotant apparaît en bas de
fenêtre indiquant que le programme est en cours d’exécution
Une action simultanée sur les touches SHIFT (majuscule) et F5 arrête le programme.

Vérifiez que la flèche jaune pointe sur l’instruction jump.

Affichage des contenus de registres de calculs:


Pour visualiser les registres de calcul :
Menu Register / Core / Register File / Register File PEx
Une fenêtre s’ajoute sur la droite indiquant les contenus des registres R0 à R15.

IUT1 GRENOBLE RT TRC1 TSN TP DSP 2015-2016 p.4/49


Les registres sont au format 40 bits, nous n’utilisons que le format 32 bits : les 8 bits de
poids faible ne sont donc pas utilisés, ils sont en général à 0 (8 bits= 2 chiffres hexa)
L'affichage des contenus n'est, bien évidemment, pas mis à jour pendant l’exécution d’un
programme.

Affichage du contenu du registre d’état:


Register
core / Status / PExstatus/ astatx
Les bits d'états contenus dans ce registre donnent des informations sur le résultat de
l'exécution des instructions : si il y a une retenue (bit AC), un overflow (bit AV), si le
résultat est nul (bit AZ) ….
Ces bits permettent de réaliser des tests et des aiguillages selon leur état :

Tous les tests réalisés dans les langages évolués : IF, FOR, WHILE... sont
réalisés avec des tests sur ces bits.

Relance du programme :
Pour relancer le programme il faut replacer le compteur PC sur la première instruction, il
est plus prudent de refaire un chargement du programme par F7.
Puis F5 pour le lancement.

Exécution du programme en mode pas à pas , touche F11:


Afin de pouvoir suivre l’exécution du programme (évolution des contenus des registres et
de la mémoire) il faut utiliser la touche F11 : chaque action sur F11 provoque l’exécution
d’une seule instruction.

Ouvrir les fenêtres permettant d’observer les registres de données et la zone des
variables. Recharger (F7) et exécuter le programme en mode pas à pas. Noter et
comprendre l’évolution des contenus des variables en mémoire (a,b,x) et des registres (r0
à r3).

Placer des points d’arrêts :


Lors de la mise au point de programme on désire souvent aller voir / comprendre ce qui se
passe dans une partie spécifique, on place alors un point d’arrêt au début de cette zone,
puis on lance le programme qui s’arrête au point d’arrêt, et on utilise alors le mode pas à
pas pour analyser l’exécution de la suite du programme.

IUT1 GRENOBLE RT TRC1 TSN TP DSP 2015-2016 p.5/49


Pour placer des points d'arrêts, représentés par un rond rouge, deux façons simples:
. double clic gauche dans la marge des fenêtres source ou disassembly (de
même pour l'enlever)
. clic sur l'icône représentant une « main » dans la barre des menus pour
placer un point d'arrêt sur la ligne où se trouve le curseur.
(main barrée pour l’enlever, main grisée pour l’invalider…)

Placer un point d’arrêt dans la boucle et relancer le programme. Suivre l’évolution de R0 et


de la variable x après chaque appui sur F5 (une exécution de la boucle ).

2. Gestion des erreurs


Lors de la compilation s’il y a des erreurs des messages rouges apparaissent dans la
fenêtre du bas.
Il faut remonter, dans cette fenêtre, jusqu’au premier message d’erreur et
corriger l’erreur indiquée.
Il suffit de double-cliquer sur le message pour que le curseur se positionne sur la ligne
d’erreur si c’est une erreur d’instruction :
Instruction inexistante
Mauvais nom de registre
Etiquette non définie ou multiple définition

Il faut toujours corriger les erreurs une à une en commençant par la première (en haut du
listing)
Modifier votre projet en prenant pour fichier source le fichier horror.dsp :
(sans créer de projet BD et remove sur le fichier source actuel puis BD et add file)
Dans la fenêtre projet BD sur le nom du fichier, puis choisir Remove file from…
Puis BD sur source file et Add file …
Le but est, au-delà de la correction des erreurs, de voir le type de message reçu et à quoi
ils peuvent correspondre.
Une erreur classique est l’oubli d’un point-virgule : attention le compilateur signale une
erreur sur la ligne suivante !

3. Création d’un projet


Sessions VisualDSP:
Il existe deux modes d'utilisation du logiciel, qui correspondent à 2 types de sessions:
session simulation
session KIT 21369

IUT1 GRENOBLE RT TRC1 TSN TP DSP 2015-2016 p.6/49


pour une installation chez vous il faut utiliser une session simulation, en salle de TP seule
la session KIT est disponible : il faut donc que celui-ci soit connecté et sous
tension.
Principe d'élaboration d'un projet:
« principe », et pas « travail demandé.». Ce qui suit est une méthode à suivre lorsque
vous aurez un projet à faire: pas tout de suite!

Création du projet: [choix du composant, ossature du projet]


(sur fond rose les points à surveiller)
FILE puis New puis Project
Apparait une Fenêtre projet :
Project types : standard application (par défaut)

Name : Prendre un nom de fichier correspondant au tp et à la question.


(le nom du projet a pour extension .dpj), par exemple tp1_2, inutile
de mettre une extension

Directory : vérifier qu’il s’agit de votre répertoire de travail DSP sur


votre disque z :, sinon modifier

Action sur Next.


une proposition de création de dossier apparait, si le chemin est correct,
acceptez.

Fenetre Select processor : SHARC 21369, sélectionné automatiquement, mais


vérifiez !
Action sur Next.
Fenetre Select … source language :
Assembly (pour assembleur)
Select project type :
executable
Action sur Next.
Action sur Finish.
Dans la fenêtre de gauche apparaît le projet, représenté par un répertoire contenant 3
sous répertoires :
Sources files : qui contient un fichier créé automatiquement (voir suite)

IUT1 GRENOBLE RT TRC1 TSN TP DSP 2015-2016 p.7/49


Linker file : vide pour l’instant (voir plus loin)
Header files : vide

Fichier créé automatiquement:


Un fichier est créé automatiquement, mais vous pouvez récupérer, par copier/coller, le
texte suivant, avac moins de commentaires et la déclaration d'une zone en dm pour les
variables :

/**********************************************************************
tpx_x.asm c’est-à-dire des commentaires sur votre projet
***********************************************************************/
.GLOBAL _main;
.section/dm seg_dmda;
// placer ici les variables nécessaires

.SECTION/PM seg_pmco;
_main:
// placer ici le code de votre programme (entre _main : et rts ; )

RTS ;
_main.end:

Constitution du projet:
Deux fichiers qu’il faut toujours ajouter :
ADSP-21369-EZKIT.LDF à placer dans linker file
21369_IVT.asm à ajouter aux sources files

Lorsque votre fichier source est terminé (code et variables) le compilateur peut traduire
en hexadécimal les instructions mais il ne sait pas à quelles adresses de la mémoire les
placer.
Le fichier ADSP-21369-EZKIT.LDF lui indique comment placer les différentes sections
repérées dans le fichier source ( seg_data, seg_code...).
Ce fichier dépend de l'architecture du système, c'est-à-dire, aussi, du DSP utilisé.
Un emplacement pertinent pour ce fichier dans le projet est le sous répertoire Linker file
(clic droit, add file).

IUT1 GRENOBLE RT TRC1 TSN TP DSP 2015-2016 p.8/49


Le lancement du programme correspond à un RESET, ceci provoque un saut dans la zone
de code définie dans 21369_ivt.asm qui lance l’exécution de votre programme repéré
obligatoirement par l’étiquette »_main : »
4. Premier programme: addition
Construction du projet:
Créer un projet tp1_1 (extension automatique .dpj, donc ne pas indiquer d’extension)
Programme d'addition:
On veut faire faire par le DSP les additions suivantes :
0X92220000 + 0xA1110000
0XE0000000 + 0xD1110000
0x10000000 + 0xF0000000
0x80000000 + 0x80000000
Pour cela il faut placer ces valeurs dans des registres puis utiliser les instructions
d’additions. Utiliser r0 à r7 pour les valeurs et mettre les résultats dans r8 à r11
Terminer votre programme par RTS ;
Ajouter après l’instruction jump (pc,0) ; par sécurité en cas de lancement après le RTS.
Suivre l'évolution des contenus des registres et des bits d'états (pas à pas avec F11)
ATTENTION : NE PAS UTILISER F11 SUR L’INSTRUCTION RTS CAR CELA
PROVOQUE UN PLANTAGE DU SYSTEME !!
Noter dans un tableau l’état des bits AZx, AVx, ANx, ACx après chacune des additions et
justifier ces valeurs.
« A » pour arithmétique, Z pour zéro, résultat nul, V pour overflow, N pour négatif, C pour
carry (retenue)
Remarque : les bits inscrits en rouge ne sont pas les bits qui viennent d’être positionnés
mais seulement ceux qui, lors de ce positionnement, ont pris une valeur différente.

5. Programme d'addition avec variables en mémoire:


Créer un nouveau projet contenant les déclarations et le programme permettant de faire
l'addition de 2 valeurs placées dans la mémoire donnée (DM).
En utilisant:
des déclarations de variables de la forme (exemple) :
.section/dm seg_dmda;

IUT1 GRENOBLE RT TRC1 TSN TP DSP 2015-2016 p.9/49


.var val1=0x12345678; // variable val1 initialisée ici à 0x12345678
.var vv ; // variable non initialisé avant le lancement du programme
// utilisation de la variable
r0=dm(val1); //place la valeur inscrite dans val1, dans le registre r0
ou
dm(val1)=r6; // copie le contenu de r6 dans val1

travail demandé :
réserver dans la mémoire DM la place pour 3 variables, val_a0 , val_a1 et val_a2
Le programme à écrire récupère les valeurs depuis la mémoire DM les placent dans les
registres r0 et r1, fait l’addition et place le résultat en mémoire .
Faire ainsi l’addition de 0x12345678 avec 0x23456789 (il faut attribuer ces valeurs au
variables lors de leurs déclarations)
Visualisez ces données dans la mémoire DM:
Memory two column
Les variables ont étés, conformément au fichier .ldf utilisé, placées à partir de l’adresse
0xB8000

6. Boucle sans fin: (visualisation des variables)


Modifier la zone DM et ajouter à la suite du code précédent les instructions nécessaires
pour:
Ajouter une variable somme initialisée à 0
le programme réalise la boucle sans fin suivante
faire
faire
incrémenter somme de 1
100 fois
toujours
Utiliser l'instruction JUMP pour retourner au début.
Si vous avez trop de difficulté à écrire ce programme (faites un effort d’abord !) voici la
solution:
.global _main ;
.section/dm seg_dmda;
.var somme=0;

IUT1 GRENOBLE RT TRC1 TSN TP DSP 2015-2016 p.10/49


.section/pm seg_pmco;
_main:
Nop;
deb:
lcntr=100, do bbt until lce;
r0=dm(somme);
r0=r0+1;
bbt: dm(somme)=r0;
jump deb;

. Lancer le programme.
Celui-ci est sans fin: la grande boucle (deb) se répète indéfiniment.
Il est toujours possible de l'arrêter avec shift-F5

Observer alors (memory/two columns/ « souris droit »/go to/ browse/somme) le contenu
de la variable somme.
. Placer un point d'arrêt sur l'instruction r0=r0+1; relancer plusieurs fois, observer et
expliquer l'évolution de r0 et de somme
. Enlever le point d’arrêt et placez en un sur l'instruction jump deb qui se trouve à la fin
du programme.
Observer et expliquer l'évolution de r0 et de somme
Mettre des commentaires dans votre programme pour expliquer ce que chaque instruction
réalise et faites les vérifier par un enseignant.

IUT1 GRENOBLE RT TRC1 TSN TP DSP 2015-2016 p.11/49


TP 2: utilisation des entrées sorties analogiques audio.

Sur la carte le circuit AD1835 permet de faire des conversions analogique vers numérique
et numérique vers analogique :

AD1835 :
15 registres pour configurer le circuit, dont 13 programmables, de 10 bits, et 2 en lecture
seule de 6 bits (détection des valeurs crêtes)

CAN et CNA au format 24 bits, échantillonnage programmé ici à 48KHz par voie, bande
passante de 20 à 20KHz (bande audio), niveau max de sortie 2.8V.

6 liaisons séries sont utilisées :


Liaison de configuration au format 16 bits, utilisée une fois en début de programme
pour écrire dans les registres de configuration (DSP vers AD1835)
Une liaison pour transmettre le résultat de la conversion analogique numérique
(alternativement voie droite et voie gauche, donc 96000 envois à la seconde)
(AD1835 vers DSP)
quatre liaisons pour transmettre les valeurs numériques pour chacune des voies de
sorties (DSP vers AD1835)

Fichiers nécessaires à placer dans le projet (dans VisualDSP) :


21369_IVT.asm pour orienter les différentes interruptions vers les sous
programmes d’interruptions

initSRU.asm pour valider les connexions correspondantes au câblage du KIT


c’est-à-dire les liaisons séries avec les broches de DAI, reliées
au circuit AD1835

IUT1 GRENOBLE RT TRC1 TSN TP DSP 2015-2016 p.12/49


filtre.asm ou passetout.asm ….
le programme principal, il lance les différentes fonctions
d’initialisations, et réalise une boucle sans fin. Ce ficher contient
le sous programme d'interruption déclenché lorsque le buffer de
réception de la liaison série est plein (sortie du CAN envoyée
vers le DSP)

initSPORT.asm pour initialiser la liaison série utilisée pour les échanges avec le
circuit CAN/CNA

init1835viaSPI.asm pour initialiser le circuit CAN/CNA (fréquence, mode …)

initPLL_SDRAM

ADSP-21369-EZKIT.LDF pour le positionnement en mémoire des différentes


sections

fichier à placer dans votre répertoire de travail :


ad1835.h

Seuls les fichiers en gras et soulignés seront modifiés, pour obtenir le traitement désiré.

Utilisation :

Les fichiers du projet permettent d’obtenir le fonctionnement suivant :


. 96000 fois par seconde le circuit AD1835 envoie le résultat de la conversion de
l’entrée analogique (alternativement voie droite et voie gauche), il faut donc considérer
une fréquence d'échantillonnage de 48000 Hz.
. La réception d’un mot complet provoque une interruption au niveau du DSP : cette
interruption doit:
lire la valeur reçue dans le registre RXSP0A (réception série port 0, voie A)
gérer voie droite /voie gauche,
déterminer la valeur de la sortie,
sauvegarder les variables utiles
envoyé le résultat en plaçant la valeur dans tous (obligatoire) les registres:
TXSP1A, TXSP1B, TXSP2A, TXSP2B, correspondant aux 4 voies stéréos.

IUT1 GRENOBLE RT TRC1 TSN TP DSP 2015-2016 p.13/49


1. Essai : programme passetout
récupérer sur le serveur l’ensemble du dossier passetout
créer un projet avec l'ensemble des fichiers
compiler
tester en utilisant :

USB

alimentation

Sortie
5 cinchs stéréo: une casque
entrée, 4 sorties

Pour le générateur BF : Vcàcmax= 2V Voffset=0


en entrée un lecteur audio personnel et en sortie un casque
ou
le générateur BF en sinusoïdale, observer rapidement le comportement en
fréquence : 0Hz à 24KHz
pour l'entrée il n'y a qu'une possibilité sur la carte.
Pour la sortie utiliser une des sorties cinch pour faire des mesures à l'oscilloscope et la
sortie casque pour écouter le résultat produit.

remarques :
le fichier passetout.asm contient la fonction _main et le sous programme d'interruption,
it_reception_sport0, seul ce sous programme est à modifier pour réaliser les différents
filtres obtenus par équation de récurrence dans les exercices suivants.

La fonction d'interruption gère l'alternance entre les deux voies (gauche et droite) il faut
donc écrire 2 fois le code en utilisant des variables propres à chacune des voies si les
entrées ou les sorties précédentes sont utilisées dans l'équation.

2. Filtre passe-bas:

on considère l'équation suivante qui définit un filtre passe bas du premier ordre:

S k =a G 0 E k +b S k−1 (1)

2 π Fc Fe
avec: a= et b=
F E+2 π F c F E +2 π F c

avec Fe la fréquence d'échantillonnage (48KHz) et Fc la fréquence de coupure du filtre.

IUT1 GRENOBLE RT TRC1 TSN TP DSP 2015-2016 p.14/49


G0 le gain en continu on prendra G0 = 1

on remarque que a+b = 1

Fe
en considérant K= :
Fc

2π K
a= et b=
K +2 π K +2π
inversement si on part d'une équation de la forme s(k)= A e(k) + B s(k-1)
on peut calculer le gain en continu: G = A/(1-B) et le rapport obtenu Fe/Fc= B/(1-B)

Informations utiles:

. pour les nombres fractionnaires il faut les faire suivre de « r », par exemple: r0=0.124r;

. calcul de s(k)

r4=r0*r2; // participation de l'entrée: r0 contient e(k), r2 le coeff pour e


r5=dm(sortiea); // pour récupérer la valeur précédente de la sortie voie a
r5=r5*r3; // participation de la sortie, r3 contient le coeff pour s(k-1)
r0=r4+r5; // total = nouvelle sortie: s(k)
dm(sortiea)=r0; // sauvegarde de s(k) qui sera s(k-1) à la prochaine it
. ne faire le filtrage que sur une des 2 voies permet, en plus de simplifier l'écriture, de
pourvoir faire la différence avec ou sans filtrage, surtout si vous utilisez votre lecteur MP3
et que vous écoutez le résultat avec un casque.

programmation:
Modifier le fichier passetout et l'enregistrer sous un autre nom
Prendre en compte la fréquence d'échantillonnage de 48KHz pour faire les calculs et écrire
le programme pour obtenir une fréquence de coupure de 500Hz.

Le programme principal est le même que pour le filtre passe-tout: initialisation des
différents éléments: les fichiers nécessaires sont les mêmes que ceux du filtre passe-tout.

Seul le programme d'interruption est différent.

utiliser une case mémoire de nom sortiea (et éventuellement sortieb pour la
voie b), par exemple, pour mémoriser s(k) qui sera s(k-1) à la prochaine
interruption .

Mesurer le gain (dB) à 30Hz , 500Hz et 2KHz. Conclure sur la nature du filtre.
Mesurer le gain (dB) à 1KHz et 10 KHz. Conclure sur l'ordre du filtre.
Faire un relevé en fréquence /dB de 20Hz à 20KHz.

IUT1 GRENOBLE RT TRC1 TSN TP DSP 2015-2016 p.15/49


3. Travail demandé: filtre passe haut premier ordre:

Passe haut:
s( p) τ . p
=
e( p) 1+τ . p
−1
en utilisant p → 1−Z on obtient
Te

(1) s(k )= τ .[ s(k −1)+e (k )−e(k−1)]


τ+Te
τ = fe
τ+Te f e +2 π f c

c'est la somme de la valeur précédente de la sortie avec la différence


entre l'entrée actuelle et la précédente, le tout pondéré par un facteur
inférieur à 1.
1−a
F c =f e
2aπ

Écrire le programme, pour obtenir Fc = 500Hz


Il faut donc 2 variables par voie: une pour l'entrée e(k-1) et une pour la sortie s(k-1).
On peut, pour faire des comparaisons auditive au casque, laisser le filtre passe bas de la
question précédente sur une voie et réaliser le passe haut sur l'autre, tous les deux avec
500Hz de fréquence de coupure.

Simple remarque (ne pas prendre en compte dans vos calculs:


Dans cette équation (1) il ne faut pas penser que le coefficient est inutile
puisqu'il s'applique à toutes les composantes,
en effet si on considère e constant, c'est-à-dire e(k) = e(k-1), l'équation se
réduit, après k=1, à:
s( k)= τ .[ s( k −1)] =M .[ s( k −1)]
τ+Te

si M=1: s(k)=s(k-1), effet mémoire, le continu passe, ce qui ne


correspond pas à un passe haut
M>1: s(k)=M.s(k-1)
ce qui ne correspond pas à un passe haut, mais à un intégrateur: la
sortie doit tendre vers 0 pour une entrée constante pour un passe haut.
Si M<1 : s(k) <s(k-1) la sortie diminue, la valeur finale est donc Sf=0

IUT1 GRENOBLE RT TRC1 TSN TP DSP 2015-2016 p.16/49


4. Filtre passe bas du second ordre:

La fonction de transfert du filtre à réaliser s'écrit sous la forme:

1 1
s( p)= 2 2 . e( p) avec τ =ω p =j. ω
ζ .τ . p+1)
( τ ∗p +2∗ n

( 1−z(−1))
p→
en appliquant Te

et en transformant s(p).z -n en s(k-n) on obtient:


2
2 2.τ
e( k)−s( k −2). τ 2 +s( k−1) .( 2 +2.ζ . τ )
Te Te Te
s( k)= 2
2∗ζ .τ
1+ τ 2 +
Te Te

s(k) étant la sortie actuelle et s(k-1) et s(k-2) les sorties aux instants d'échantillonnages
précédents.
τ =a= F E
En prenant et 2.ζ=b
Te 2.π .F C
on obtient:
(2) e( k)−s( k −2) . a 2+s( k −1).( 2.a 2+a.b)
s( k) =
1+a 2+a.b

puis, pour exemple: pour Fc= 1KHz et ζ=0.7 on obtient:

a=7,6394372684 b = 1,4 1+a 2+a.b=70,0562139

s( k) =0,01427e( k)−0,833059 . s( k −2)+1,81878 s( k −1)

il faut suffisamment de précision sinon le système peut devenir instable.

afin de n'avoir que des coefficients inférieurs à 1 (fractionnaires 1.31) on les divisent tous
par 2.
il faudra bien sur multiplier le résultat obtenu par 2 en utilisant un décalage à gauche.
Par exemple: r0 = ashift r0 by 1;
il faut ici utiliser ashift, et non pas lshift, car il est important de conserver le bit de signe.
Ashift : décalage arithmétique qui ne modifie pas le bir de signe
lshift : décalage logique, aucune protection du bit ded signe

s( k) =2[ 0,007135 e( k)−0,416529 . s( k −2) +0,90939 s( k −1)]

Travail demandé:

IUT1 GRENOBLE RT TRC1 TSN TP DSP 2015-2016 p.17/49


voici le source correspondant:
r10=dm(RXSP0A);
r10=lshift r10 by 8;
r0=dm(voie); // par défaut le compilateur a placé 0 au chargement
r1=1;
r0=r0 xor r1; // on inverse le bit 0
dm(voie)=r0; // mémorisation de cette nouvelle valeur

if eq jump voie_a; // si la valeur est nulle on saute à "voie_a"


jump voie_b; // sinon saut à voie_b

voie_a:
r0=dm(sortiea); //sk-1
r1=dm(sortiea2); // sk-2
r2=0.007135r;
r3=0.90939r;
r4=0.416529r;
r5=r10*r2(ssf); //
r6=r0*r3(ssf); //
r5=r5+r6;
r6=r1*r4(ssf); //
r5=r5-r6;
r5=ashift r5 by 1; //
dm(sortiea2)=r0; //
dm(sortiea)=r5; //
r10=lshift r5 by -8; //
jump fin;

voie_b:
r0=dm(sortieb);
r1=dm(sortieb2);
r2=0.007135r;
r3=0.90939r;
r4=0.416529r;
r5=r10*r2;
r6=r0*r3;
r5=r5+r6;
r6=r1*r4;
r5=r5-r6;
r5=ashift r5 by 1;
dm(sortieb2)=r0;
dm(sortieb)=r5;
r10=lshift r5 by -8;

fin:

dm(TXSP1A)=r10; // DAC1
dm(TXSP1B)=r10; // DAC2
dm(TXSP2A)=r10; // DAC3
dm(TXSP2B)=r10; // DAC4

IUT1 GRENOBLE RT TRC1 TSN TP DSP 2015-2016 p.18/49


rti;

tester ce programme et placer des commentaires aux emplacements repérés par \\.

. est ce bien un passe bas?


. est ce bien un second ordre ? Pourquoi ?

Tracer sur une feuille semilog la réponse en fréquence de 20HZ à 20KHz

5. Etude de filtre réalisés à partir d'équations:

5.1 ecrire un programme qui a pour équation:


s(k) = e(k) + e(k-1) + e(k-2) + e(k-3)
tracer son diagramme de Bode de 20Hz à 20KHz (Vecc 0.8V max)

5.2 idem pour: s(k)= e(k) – e(k-2) (Vecc 1V max)


5.3 et s(k)=e(k) – e(k-1)

IUT1 GRENOBLE RT TRC1 TSN TP DSP 2015-2016 p.19/49


TP3
Produit de convolution.

1. Produit de convolution:
on peut définir un système par sa réponse impulsionnelle (à un dirac):
schéma:

système

dirac Rimp

la réponse à un signal d'entrée quelconque peut-être déterminée, en


échantillonné, en faisant la somme des produits des valeurs passées du
signal d'entrée avec les valeurs de la réponse impulsionnelle:
exemple:
supposons la réponse impulsionnelle suivante:

alors, si E(t) est :

la sortie à l'instant t1:

t' t1
est donnée par l'intégrale du produit des deux signaux de t' à t1

En effet ici de 0 à t' le produit est nul, donc l'intégrale aussi, il suffit d'intégrer
de t1 à t'...

IUT1 GRENOBLE RT TRC1 TSN TP DSP 2015-2016 p.20/49


La sortie dépend de l'entrée actuelle (E(t1)) à laquelle il faut ajouter
les valeurs passées de plus en plus estompées jusqu'à t'.
on utilise la réponse impulsionnelle inversée, mais lors d'un calcul on
additionne les valeurs successives (donc dans le sens positif) de la réponse
impulsionnelle, multipliées avec les valeurs de plus en plus éloignées dans le
temps de l'entrée, donc à reculons dans le temps.

2. Outil: calcul d'un produit de convolution:


Pour le calcul du produit de convolution en numérique, il faut disposer:
. d'une zone mémoire circulaire contenant les valeurs de la
réponse impulsionnelle

. d'une zone mémoire contenant les valeurs passées du signal


d'entrée: cette zone doit donc être de même longueur que la réponse
impulsionnelle
elle sera lue et renouvelée à chaque instant d'échantillonnage:
la valeur la plus ancienne n'est plus à conserver
la valeur actuelle de l'entrée doit être mémorisée

3. Analyse du fichier fourni: « convol_exemple.dsp »


dans ce fichier on trouve la structure suivante:
déclarations:
. des sections, utilisées comme précédemment
. des définitions de constantes (comme en C)
ces constantes permettent d'adapter facilement le texte à d'autres valeurs.
Ici il est important de pouvoir définir:
la taille de la réponse impulsionnelle: L_IMP

Initialisations:
les registres suivants sont utilisés:
I0 pour le signal voie A (L0 =L_IMP)
I1 pour le signal voie B (L1 =L_IMP)
I2 pour la réponse impulsionnelle (L2=L_IMP)

M0 = 0 pour un accès sans déplacement


M1 =1 pour une incrémentation classique
M2= -1 pour une décrémentation du pointeur: utilisé ici pour lire les
valeurs du passé de l'entrée (en remontant dans le temps, pour la
convolution).

GENERATION RÉPONSE IMPULSIONNELLE:


on peut :
. écrire une suite d'instructions permettant de créer une réponse impulsionnelle
qui sera utilisée pour le produit de convolution.
Par exemple en utilisant une impulsion et une équation de récurrence de filtre.

IUT1 GRENOBLE RT TRC1 TSN TP DSP 2015-2016 p.21/49


. Ou encore fabriquer cette réponse de toutes pièces...

(par défaut une réponse impulsionnelle est ici créée, tout à fait artificielle)
.var rep_impul[L_IMP]={0.9r,0.8r,0.7r,0.6r,0.5r,0.4r,0.3r,0.2r,0.1r};

Convolution:
partie du programme qui est à comprendre mais que vous n'aurez par la suite
qu'à utiliser telle quelle, si vous respectez bien les déclarations et les
initialisations définies ci dessus (sur fond magenta).

Graphiquement:

Mémoire réponse
impulsionnelle
sortie
convolution

Mémoire signal

entrée

Pour résumer l'utilisation des registres d'adresses pour la convolution:


Pointeur de la zone du signal
d'entrée (I0)

signal
Lecture du passé I0

REP_IMPUL

I2

comme on utilise les deux voies de la stéréo I1 est utilisé pour la seconde voie
à la place de I0.

lorsque le résultat d'une nouvelle conversion parvient au DSP:


cette valeur doit être mémorisée dans la mémoire circulaire réservée au
signal (I0 sert à l'écriture et I0 est incrémenté de 1)
le pointeur sur la réponse impulsionnelle doit se trouver en début de
zone

IUT1 GRENOBLE RT TRC1 TSN TP DSP 2015-2016 p.22/49


une boucle exécutée autant de fois qu'il y a d'éléments dans les zones
signal et réponse impulsionnelle accumule:
les éléments du signal en remontant dans le passé
multipliés par
les valeurs de la réponse impulsionnelle
l'instruction n'existe pas mais on veut faire:

sortie = Somme [ dm(I0,M2) x dm(I2,M1)]


avec M2 = -1 et M1 = 1

l'arrivée d'un mot issu du convertisseur analogique / numérique provoque une


interruption par le buffer de réception de la liaison série.

4. Travail demandé: utilisation du fichier « convol_exemple.dsp »


essai sans modification:
récupérer les fichiers du projet convolution qui se trouve sur le serveur.

la réponse impulsionnelle comporte les valeurs :


0.9 0.8 0.7 0.6 0.5 0.4 0.3 0.2 0.1
remarquez qu'il faut écrire 0.9r pour préciser que ce sont des nombres
fractionnaires virgule fixe (format 1.32) et non pas des flottants IEEE754.

il faut créer un projet qui doit contenir tous les fichiers utilisés dans le TP
précédent :
21369_IVT.asm
initSRU.asm
convol_exemple.asm
initSPORT.asm
init1835viaSPI.asm
initpllsdram.dsp
ADSP-21369-EZKIT.LDF
observer rapidement le signal de sortie pour une entrée sinusoïdale de 20Hz à
20KHz de valeur 0.4V crête à crête
conclure sur la nature du filtre.

5. Création de réponses impulsionnelles

Méthode de travail:
créer des réponses impulsionnelles en plaçant les valeurs dans le tableau de la
réponse impulsionnelle il faut penser à actualiser la valeur de L_IM
relever sur la même feuille échelle log de 20Hz à 20KHz
en prenant comme échelle de -50dB à +20 dB
conseils de mesure : l'averaging ne permet pas de voir le vrai signal, il ne faut
donc pas l'utiliser à priori, cependant lorsque le signal est noyé dans le bruit il
faut l'utiliser pour faire une mesure d'amplitude plus précise

IUT1 GRENOBLE RT TRC1 TSN TP DSP 2015-2016 p.23/49


Choisir correctement le niveau de l'entrée :
pas trop élevé pour ne pas saturer (déformation en sortie)
assez élevé pour ne pas être noyé dans le bruit (max 2V)
Attention : la méthode « 1 2 5 » n'est pas une bonne méthode ici, en effet il
peut y avoir de grandes irrégularités (creux ou bosses) brèves, il faut faire un
balayage plus fin pour les relevés à faire on peut utiliser cette méthode jusqu'à
1KHz, puis il est préférable de bien suivre l'évolution de la nsortie en fonction
de la fréquence
Réponse impulsionnelle 1:
1 valeur positive: 0,9
1 valeur négative: -0,9
faire le relevé en fréquence sur feuille semi log:
gain en db

Réponse impulsionnelle 2:

2 valeurs positives égales : 0,9


Ve(max)= 1Vcàc

Réponse impulsionnelle 3:
les valeurs :
0,9 0 0 0,9
Ve(max)= 1Vcàc
Réponse impulsionnelle 4 :
les valeurs :
0,9 0 0 0 0 0 0 0 -0,9
Ve(max)= 1.5Vcàc

Réponse impulsionnelle 5:

les valeurs:
0,9 0,6 0,4 0,2 -0,9 -0,6 -0,3 -0,2 +0,1

Sans tracé : observer rapidement pour :


0,9 suite de dix zéros 0,9
0,9 suite de 10 zéros -0,9

on peut avoir la courbe tracée par ZSGcalc en utilisant l'équation suivante :

20*log(abs(0.9+0.6*exp(-2*pi*i*x/48000)+0.4*exp(-4*pi*i*x/48000)+0.2*exp(-
6*pi*i*x/48000)-0.9*exp(-8*pi*i*x/48000)-0.6*exp(-10*pi*i*x/48000)-0.3*exp(-
12*pi*i*x/48000)-0.2*exp(-14*pi*i*x/48000)+0,1*exp(-16*pi*i*x/48000)))

IUT1 GRENOBLE RT TRC1 TSN TP DSP 2015-2016 p.24/49


lancer ZSGCalc puis cliquer sur graphique 2D et coller l'équation. Choisir les
échelles : log pour l'abcisse, et les valeurs max et min

IUT1 GRENOBLE RT TRC1 TSN TP DSP 2015-2016 p.25/49


TP4

Générateur de signal.

Pour générer un signal avec le kit « il suffit » de placer les valeurs successives
de ce signal sur la sortie du KIT.
Si ce signal est périodique on peut calculer à chaque fois une nouvelle valeur
en fonction de la précédente mais il est aussi possible de lire circulairement
un tableau de valeurs placé dans la mémoire de données (DM).

Il faut faire des envois de valeurs vers le CODEC à espaces réguliers, on utilise
ici les interruptions mises en place précédemment même si on n'utilise pas ici
les valeurs envoyées par le CODEC:
lire le contenu du buffer de réception (valeur non utilisée mais cette
lecture est obligatoire pour le bon fonctionnement)
écrire la valeur à transmettre dans les 4 buffers de transmission

Les initialisations sont les mêmes que précédemment afin d'obtenir les
interruptions au rythme de 48000/s par voie:
call _initPLL; // Initialise la PLL: fréquence du coeur CCLK
call _initSDRAM; // Initialise SDRAM (SDCLK)
call _initSRU; // Initialise SRU, broches DAI/DPI pour le kit
call _initSPORT; // Initialise les liaisons séries utilisées sur le kit
call _init1835viaSPI; // Initialise le codec
LIRPTL = SP0IMSK; // valide l'interruption sur le port série de réception des
données de réception

auxquelles il faut ajouter :


bit set mode1 CBUFEN; // valide le fonctionnement en circulaire

BIT SET MODE1 IRPTEN; // valide globalement le système


d'interruption

Générateur sinusoïdal, fréquence unique:


on utilise l'interruption générée par la réception d'une valeur dans le regist de
réception (comme précédemment) mais la valeur reçue n'est pas utilisée (pas
de signal en entrée), il faut cependant lire le contenu de ce registre pour le
vider et lui permettre une nouvelle réception.

On utilise le fichier sin0_5000_1.dat qui contient les 5000 valeurs d'une


période de sinusoïde.
Ce fichier doit être dans le répertoire de travail.
0. Utiliser le fichier passetout comme fichier de base

1. Les valeurs contenues dans le fichier doivent être placées dans la

IUT1 GRENOBLE RT TRC1 TSN TP DSP 2015-2016 p.26/49


mémoire dm:
.section/dm seg_dmda ;
.var signal[]="sin0_5000_1.dat";

2. il faut utiliser un buffer circulaire pour pointer la zone mémoire


B0=signal ; // I0 est également initialisé à cette valeur
L0=5000 ; // longueur de la zone mémoire utilisée circulairement
M1=1 ; // pour se déplacer de case en case
ne pas oublier :
bit set mode1 CBUFEN; // valide le fonctionnement en circulaire

3. écrire la fonction d'interruption :


. il faut lire (même si on n'utilise pas la valeur lue) le buffer de
réception :
r0=dm(RXSP0A);
. récupérer une valeur dans le tableau signal avec le registre d'adresse
qui a été initialisé sur cette zone mémoire. (à vous de l'écrire!)
. faire le décalage pour le format 24 bits du CNA:
r0=lshift r0 by -8; // si les valeurs sont dans r0
. et les transmettre aux registres de transmission :
dm(TXSP1A)=r0; // transmission vers DAC1
dm(TXSP1B)=r0; // DAC2
dm(TXSP2A)=r0; // DAC3
dm(TXSP2B)=r0; // DAC4

. Faire un projet permettant de réaliser ce générateur. Utiliser le


fichier passetout comme fichier de départ

. Observer le signal obtenu. Expliquer la fréquence du signal


observé.

Générateur sinusoïdal, à plusieurs fréquences:


On peut utiliser le Bouton Poussoir 1 pour générer des interruptions qui vont
modifier le pas de lecture dans la mémoire du signal sinusoïdal:
on utilise toujours sin0_5000_1.dat pour placer la sinusoïde en
mémoire
si la lecture des échantillons utilise M0 comme modificateur:
pour M0=1 on lit tous les échantillons, on se trouve dans la
situation de la question précédente
pour M0= 2 on utilise un échantillon sur deux, et donc la fréquence
est 2 fois plus élevée....

L'interruption IRQ1 (BP1) doit modifier la valeur de M0.


Pour avoir des fréquences dans les rapport 1, 2, 5 ,10, 20, 50 et 100 on peut
utiliser une zone mémoire circulaire contenant ces valeurs, chaque
interruption permet de lire la valeur suivante de cette liste et de l'attribuer à

IUT1 GRENOBLE RT TRC1 TSN TP DSP 2015-2016 p.27/49


M0.
.var modif[]=1,2,5,10,20,50,100,50,20,10,5,2;
// permet de placer les valeurs 1
// à100 dans la zone modif

valider les interruptions de IRQ1 (dans le _main du programme):


bit set mode2 IRQ1E;
bit set imask IRQ1I;
ustat3=dm(SYSCTL);
bit set ustat3 IRQ1EN;
dm(SYSCTL)=ustat3;
il faut utiliser un ensemble (B , I , L) comme pour signal pour accéder
circulairement aux valeurs à attribuer à M1
Il est donc nécessaire d'utiliser un autre M qui restera, lui, toujours à 1.

Écrire le sous programme d'interruption (par exemple de nom it_bp1) dans le


fichier source à la suite de l'interruption it_reception_sport0, terminer ce sous
programme par RTI ;

placer le jump correspondant dans le fichier 21369_IVT.asm, donc sur la


ligne correspondant à IRQ1 (par exemple : jump it_bp1 ;)
il faut de plus :
indiquer dans le fichier source que le nom du sous programme est
global (par exemple : .global it_bp1 ;
indiquer dans le fichier 21369_IVT.asm que le nom du sous
programme est défini ailleurs (par exemple : .extern it_bp1 ;)

Générateur triangulaire, fréquence unique:


On utilise comme précédemment la période d'échantillonnage du CODEC pour
générer les échantillons de sortie (donc un échantillon est déterminé toutes les
périodes d'échantillonnage quelque soit la forme et la fréquence du signal
désiré).
indications/contraintes:
a. On veut générer un triangle dont les valeurs extrêmes sont -0.9r et +0.9r.

b. A chaque interruption il faut incrémenter ou décrémenter la valeur


précédemment générée:
il faut donc repérer le sens de progression actuel dans une variable

c. la fonction d'interruption ne doit pas utiliser les registres comme variables


mais des variables placées en mémoire DM, sens,val... : on se place dans un
contexte qui permettrait d'avoir un programme principal qui ne soit pas une
simple boucle d'attente et qui peut utiliser les registres.

IUT1 GRENOBLE RT TRC1 TSN TP DSP 2015-2016 p.28/49


un algorithme possible est le suivant:
variables dans DM:
sens pour mémoriser si incrémentation (1) ou décrémentation (0) en
cours
val pour mémoriser la valeur actuelle de la sortie
pas la valeur de progression

gestion dans le programme d'interruption :


(voir plus loin un algorithme orienté DSP)
si sens ==1
val = val + pas
envoi de val
si val > 0.9r
sens <- 0, (pour décrémenter la prochaine fois)
saut à fin
sinon (sens==0)
val = val – pas
envoi de val
si val < -0.9r
sens <- 1 (pour incrémenter la prochaine fois)
fin

pour réaliser les différents aiguillages nécessaires il est possible d'utiliser des
instructions conditionnelles, et plus particulièrement des sauts conditionnels:
IF cdt instruction;
cdt pouvant être notamment:
eq si résultat de l'instruction précédente nul
ne si résultat non nul
le si résultat négatif ou nul (lt : strictement négatif)
gt si résultat strictement positif (ge : positif ou nul)
en pratique instruction est un jump etiquette
un algorithme qui utilise ce type de test (qui s'approche des instructions du
DSP) est :
lire sens et le comparer à 0
si sens ==0 saut à moins (si le résultat de l'addition est 0)
(par exemple :
r1=dm(sens) ;
r2=0;
r1=r1+r2; //le résultat est nul si sens =0
if eq jump diminuer ;// on saute
// ici il faut donc augmenter)

sinon on augmente :
val = val + pas
envoi de val
si val < 0.4r saut à fin
(par exemple : r1=dm(val) ; r2=0.9r;r1=r1-r2 ; if le jump fin;)

IUT1 GRENOBLE RT TRC1 TSN TP DSP 2015-2016 p.29/49


sens = 0
saut à fin
moins
val = val – pas
envoi de val
si val > -0.4r saut à fin
sens <- 1
fin
rti ;
Écrire et tester le programme

écrire la relation entre Te, pas , max et la période du signal obtenu.

Générateur triangulaire, changement de fréquence:


on utilise le même type de fonctionnement que pour le générateur sinusoïdal
(appuis successifs sur le BP)
il faut donc utiliser un tableau increment, par exemple, qui prend la valeur de
l'incrémentation lue dans la table et la place dans la variable pas à chaque
interruption du BP1.

IUT1 GRENOBLE RT TRC1 TSN TP DSP 2015-2016 p.30/49


TP5 Traitement du son

1.DELAYS :
Le delay est un effet souvent utilisé avec les instruments de musique électrique (claviers et
guitares essentiellement), il ajoute au signal le signal retardé.

Le delay se différencie de la réverbération qui est le résultat d'un ensemble complexe de


retards du signal qui s'ajoutent à la source originale. L'effet delay peut être aussi la somme de
plusieurs retards (en nombre assez limité cependant).

L'écho est un delay long, le temps est de l'ordre de la seconde.

L'effet delay des musiciens utilise des temps de retard allant de quelques dizaines de
millisecondes à plusieurs secondes. Les retards de 10 à 200ms ne produisent pas une
répétition du son décelable mais modifie la sonorité.

Pour obtenir un delay très audible (ce qui est notre but ici, donc plutôt un écho) il faut avoir
un temps le plus grand possible, il faut donc mémoriser une longue série de valeurs.

Pour ce projet, afin de disposer de plus de mémoire DM il faut utiliser les fichiers du
répertoire « delay » du serveur :
ADSP-21369-EZKIT_mem_ext.LDF au lieu du .LDF habituel
pour_projet_mem_ext.asm comme fichier de base pour le programme

La zone mémoire DM seg_sdram contient un peu plus de 4 millions de cases mémoires


32bits.

1. Ajouter le signal retardé au signal direct:


. fixer la valeur de BUFLEN (à 100000 pour commencer) pour obtenir en seg_sdram la
taille désirée pour memdelai
. dans le programme principal (initialisations) il faut positionner un registre d'adresse
sur la zone memdelai (registres Bx et Lx et M)
. dans la fonction d'interruption il faut ;
lire la valeur pointée par Ix sans se déplacer (utiliser un M à 0) (plus ancienne
valeur)
écrire la valeur reçue (en se déplaçant de +1), l'écriture a donc lieu sur la case que
l'on vient de lire.
Calculer la somme signal reçu et signal lu et l'envoyer vers les sorties

quel sera le temps de retard obtenu si BUFLEN=1000 ? 100000 ? 1000000 ?

Écrire le programme et tester avec ces différentes valeurs. Le retard pourra être utilisé sur une
seule des voies afin de pouvoir comparer avec le signal d'origine.

2. voiea =voieb retardée :


en voiea on lit la mémoire sans déplacement et on l'envoie sur les sorties de la
voie (valeur retardée),il est cependant nécessaire de faire l'acquisition de la
valeur en réception.
en voieb on écrit dans la mémoire la valeur présente et on l'envoie sur les
sorties de la voie.

3. reprendre le 1. afin de pouvoir modifier le retard:2ms, 20ms, 200ms, 2s, (20s)


puis en sens inverse, par action sur BP1. Pour les valeurs de l'entrée il faut
prévoir une zone mémoire correspondant au maximum : 20s, donc environ

IUT1 GRENOBLE RT TRC1 TSN TP DSP 2015-2016 p.31/49


1000000 de cases mémoire.
Pour les valeurs du décalage il faut réserver une zone mémoire contenant le
nombres d'échantillons dont il faut remonter dans le passé (la valeur 1
correspond à 1/48000s), on utilisera donc -100 (2ms), -1000, -10000, -100000,
-1000000, il faut aussi prévoir les valeurs permettant de ne pas avoir de saut
brusque : donc ajouter -100000, -10000, -1000.
on utilise ici deux index, l'un pour les valeurs de l'entrée, utilisé pour la
sauvegarde des valeurs successives. L'autre index récupère les valeurs passés.
Au départ ces 2 registres pointent le même emplacement.
A chaque action sur BP1 on repositionne le second index :
si la valeur lue dans le tableau est placée dans M5 :
I2=I1 ; // repositionne I2 sur I1
r7=dm(I2,M7) ; // permet de modifier I2, en le plaçant M7 échantillons dans le
passé.

Voiea : lecture de la valeur en réception, mémorisation dans le buffer réservé à


l'entrée, envoi sur les sorties de la voiea (liaisons séries vers le CODEC)
voieb : lecture de la valeur retardée en utilisant une instruction :
Rx=dm(I2,M1) ; //avec M1=1
envoyer la valeur sur les sorties de la voieb

L'interruption obtenue par action sur BP1 permet de repositionner l'index sur le
buffer.

Pour valider l'interruption BP :


bit set mode2 IRQ1E;
bit set imask IRQ1I;
ustat3=dm(SYSCTL);
bit set ustat3 IRQ1EN;
dm(SYSCTL)=ustat3;
ne pas oublier la mise à jour du fichier 21369_IVT.asm

2. Tremolo :

Pour cela on module en amplitude le signal avec un triangle 0.01 à 0.99. On ne crée pas en
mémoire un signal triangulaire mais on fait évoluer un coefficient dans l'interruption en
appelant la fonction triangle.

a. fonction triangle :
cette fonction utilise les variables suivantes en entrées :
valmax= 0.99
valmin =0.01
pas = 0.00001 à 0.00005 pour tester
sens
val (=0.5 au début)
et modifie éventuellement les variables suivantes (sorties) :
val (coefficient de modulation)
sens

Une fonction est un sous programme :


il est repéré par une étiquette (le nom de la fonction)
se termine par rts ;
est appelé par l'instruction CALL <étiquette> ;

Le sous programme triangle est appelé lors du traitement de l'interruption de réception


SPORT0 (avant le choix voiea ou voieb).

IUT1 GRENOBLE RT TRC1 TSN TP DSP 2015-2016 p.32/49


Avec les valeurs indiquées ci dessus on obtient un temps pour passer de la plus petite valeur
(0.01) à la plus grande (0.99) :
1 0.99−0.01
t= ∗ =1,02 s
96000 0.00001
on peut avantageusement s'inspirer du programme génération de triangle du TP précédent.

A chaque interruption de réception la valeur transmise est celle de la valeur reçue à laquelle on
applique le coefficient contenu dans la variable val avant de l'envoyer vers les sorties.

3. Stereo move :
le but est d'obtenir un signal tournant entre les 2 voies.
Il faut deux zone mémoire , une pour mémoriser les entrées de voiea et une pour celles de
voieb.

On module en amplitude le signal avec un triangle 0.01 à 0.99 comme précédemment.

Mais le calcul de la sortie de chaque voie prend en compte les entrées des 2 voies (valeur
précédente de l'autre voie).
On peut, si on ne veut pas utiliser les index des zones mémoires, créer 2 variables va et vb qui
sont mises à jour à chaque réception d'une nouvelle valeur.

les calculs sont les suivants :


voiea : s= val * va + val2 * vb
voie_b : s= val* vb + val2 * va

lorsque val augmente, val2 diminue...

val2 sera calculée en fin de fonction triangle:


val2=valmax+valmin-val (essayer de retrouver cette équation)

3. Flanger

chaque voie est traitée 48000 fois par seconde, en arrondissant à 50000, cela représente un
temps de 20us entre 2 interruptions, c'est-à-dire entre 2 valeurs dans la zone mémoire
des valeurs passées de l'entrée.

Ce type d'effet ajoute au signal direct le signal retardé, mais le retard varie dans le temps.
Le temps du retard est de l'ordre de 1 à 10ms.

Le retard utilisé varie lui même en un temps de l'ordre de 1 seconde à une dizaine de
secondes.

Il faut donc :
prévoir 1 zone mémoire de 500 cases 'entree' (ce qui peut permettre d'avoir un retard
maximum d'environ 10ms)), pour mémoriser les signaux d'entrées d'une des entrées (la
seconde entrée sera envoyée sans modifications pour faire des comparaisons)
(le décalage devant évoluer dans le temps on utilise également l'interruption de
réception série afin de modifier ce retard.)

prévoir une zone mémoire pour les valeurs du retard, qui peut donc aller de 50 à 500 à
50, donc 900 valeurs.

on utilise également l'interruption de la réception pour modifier la valeur du retard,

IUT1 GRENOBLE RT TRC1 TSN TP DSP 2015-2016 p.33/49


mais si on la modifie à chaque interruption les 1000 valeurs sont utilisées en 20ms ce qui est
trop rapide.
Si on veut une évolution en 1s il y a un rapport de 1s/20ms=50. Il faut utiliser un compteur
qui est incrémenté à chaque interruption, lorsqu'il atteint la valeur maximum (50) on change
la valeur du retard et on remet le compteur à 0

le programme principal doit, lors de l'initialisation, écrire dans la mémoire 'retard' les
différentes valeur du retard (c'est-à-dire les valeurs 50 à 500 à 50).

Le programme d'interruption de la liaison série doit :


lire et sauvegarder dans la mémoire la valeur reçue
incrémenter le compteur et si il est arrivé à sa valeur max modifier la valeur du
retard et mettre cette valeur dans un registre m utilisation de la même méthode que pour
delai version 3
lire la valeur retardée.
faire la somme avec la valeur directe et transmettre le résultat aux sorties

autres variables utilisées:


(voie)
cptr

algorithme de l'interruption pour la gestion du compteur:

si maxcptr>cptr :
lire une valeur dans la zone des retards
mettre cptr à 0
sinon :
incrémenter cptr

TP6
utilisation des timers en interruptions.

On dispose de trois Timers (0 à 2)


Le x correspond au numéro du timer : 0 à 2

Registres:
TMxCTL contrôle
TMxCNT compteur, registre 32 bits, utilisé en interne par le système
TMxPRD période, registre 32 bits, 31 utilisés
TMxW largeur d'impulsion, 32 bits, 31 utilisés

Lorsqu’un timer est validé en mode PWM il génère sur sa sortie TIMERx un signal :
de période tp = tpclk * TMxPRD
de niveau actif th = tpclk * TMxW

IUT1 GRENOBLE RT TRC1 TSN TP DSP 2015-2016 p.34/49


[ en TP, sur le KIT: CCLK= 393,216MHz soit tpclk environ 10.2 ns ]

TMxCTL défini le mode de fonctionnement du Timer :

AUX : choix de l’entrée utilisée en mode WDTH ou EXT


IRQEN : pour les interruptions
PRDCNT : en mode PWM
0 pour générer une seule impulsion
1 pour générer des impulsions sans fin
PULSE : pour choisir le niveau (ou le front) actif : 1 pour haut (montant)
TIMODE : mode de fonctionnement 01 pour PWM

TMSTAT est un registre d'état et de contrôle commun aux 3 timers


chaque timer dispose dans TMSTAT:
d'un bit de validation TIMxEN
d'un bit d'invalidation TIMxDIS (prioritaire si on écrit sur les deux)
d'un bit d'erreur d'overflow TIMxOVF doit être effacé en écrivant 1
d'un bit d'interruption TIMxIRQ mis à 1 à la fin de la période, il déclenche la
demande d'interruption. Il doit être mis à 0 dans l'interruption en écrivant 1
Dans de nombreuses applications PWM la période et l’état actif doivent être modifiés. Ces
valeurs sont modifiables sans arrêter le TIMER cependant il est indispensable de changer
en dernier la largeur de l'impulsion et de le faire même si cette valeur n'a pas changé.

La programmation doit être effectuée dans l'ordre suivant:


TMxCTL
TMxPRD
TMxW
TMSTAT bit TIMxEN par bit set ustat

pour valider l'interruption générée par le timer il faut écrire dans imask:
bit set imask P2I; // pour valider les interruptions TIMER0

dans l'interruption il faut effacer le bit source de l'interruption :


r0=TIM0IRQ; // à placer dans le ss prgm d’interruption
dm(TMSTAT)=r0; // pour effacer la demande d’interruption timer 0

IUT1 GRENOBLE RT TRC1 TSN TP DSP 2015-2016 p.35/49


exemple d'initialisation :
mettre les commentaires
r0=0x1d; //
dm(TM0CTL)=r0;
r0=0x2FAF080*2; //
dm(TM0PRD)=r0;
r0=0x2FAF080; //
dm(TM0W)=r0;
r0=TIM0EN;
dm(TMSTAT)=R0; //

sweep :

écrire un programme utilisant le générateur sinusoïdal du TP4 : le but est de faire varier le
pas (donc la fréquence) automatiquement : par un timer qui change le pas de lecture dans
la mémoire du signal avec un temps de cycle de 5s (par exemple). Pour que l'évolution ne
soit pas trop hachée il faut varier le pas de 1 à 500, si on change de 1 à chaque fois il faut
aller de 1 à 500 puis à 1 donc 999 valeurs que l'on peut placer par programme dans une
zone mémoire de DM.

Déterminer alors la période utilisée pour le timer.

Tremolo :

reprendre le trémolo du TP5. Le coefficient est modifié par l'interruption timer, on peut
commencer avec un cycle de 3s et 600 valeurs différentes.

On peut appliquer le même principe pour stereomove

IUT1 GRENOBLE RT TRC1 TSN TP DSP 2015-2016 p.36/49