Devoir surveillé de DSP (Processeur de Traitement de Signal)
I3 Electronique
Benoît Decoux – mardi 21 novembre 2006
Durée : 2 heures - Tous documents et calculatrice autorisés
-corrigé-
Exercice 1 : Arithmétique des DSP (4 points)
1) Donner la valeur décimale correspondant à la valeur hexadécimale $FFFFFE exprimée dans le
format virgule fixe [1,23]. (2 points)
2) Même question pour le format virgule fixe [9,47] et la valeur $22222000000000. (2 points)
1) Le bit de signe est à 1, donc le nombre est négatif. Pour la partie fractionnaire, plutôt que de
calculer tous les bits, il suffit de remarquer que ce nombre est égal à
$FFFFFE=$FFFFFF-$000001
=-2-23-2-23
=-0,00000012×2
=-0,00000024
2)
$22222200000000
=0010 0010 0,010 0010 0010 0010 0010 0010 0000 0000 0000 0000 0000 0000
partie entière :
22+26=68
partie fractionnaire :
2-2+2-6+2-10=0,25+0,015625+0,000976≈0,2666
Résultat :
≈68,2666
Exercice 2 : Synthèse de filtre RIF (6 points)
1) Calculer les coefficients hi, i=0,1,…,4 d’un filtre RIF passe-bas à N=5 coefficients, de
fréquence de coupure fc=882Hz. La méthode de synthèse à utiliser est le développement en
série de Fourier de la réponse fréquentielle, sans fenêtrage. La fréquence d’échantillonnage est
fe=44100Hz. (2 points)
2) Donner la réponse impulsionnelle de ce filtre (on se limitera aux seuls coefficients connus). (1
point)
3) Donner sa fonction de transfert en Z. (1 point)
4) En déduire son équation aux différences (en développant le raisonnement). (1 point)
5) Donner le signal de sortie résultant de l’application de cette équation au signal d’entrée :
e={1,0,0,0,0}.
(1 point)
1) La formule à appliquer est :
1
hi = sin(2π(i − p)Fc ) , i=0,1,…4
(i − p)π
avec
N −1 5 −1
p= = =2
2 2
et
1
fc 882
Fc = = = 0,02
fe 44100
d’où :
1
hi = sin(0,04π(i − 2) ) , i=0,1,…4
(i − 2)π
Remarque : pour i=(N-1)/2=2, on a sin(x)/x=1 donc h0=2Fc=0,04.
Coefficients obtenus :
h0=0,03958, h1=0,039895, h2=0,04, h3=0,039895, h4=0,03958
2) Les coefficients du filtre donnent directement sa réponse impulsionnelle
3) La fonction de transfert en Z du filtre est la transformée en Z de sa réponse impulsionnelle :
−1
H(z) = h0 + h1z + h 2z−2 + h3z−3 + h 4z−4
4) L’équation aux différences est :
s(n) = h 0e(n) + h1e(n − 1) + h 2e(n − 2) + h3e(n − 3) + h 4e(n − 4)
Elle s’obtient à partir de la propriété de retard de la transformée en Z :
Z[e(n − n 0) ] = z−n 0 E(z)
5) e={1,0,0,0,0} est le signal impulsion, donc la réponse à ce signal sera la réponse impulsionnelle
(donc les coefficients du filtre).
Exercice 3 : Filtrage de type RIF avec Scilab (3 points)
1) Ecrire un programme Scilab réalisant un filtrage de type RIF, défini par l’équation aux
différences :
s(n) = h 0e(n) + h1e(n − 1) ,
Ce programme doit utiliser un tableau de 2 éléments pour la mémorisation des échantillons e(n-
i), un autre tableau de 2 éléments pour les coefficients hi, utilisés en buffers circulaires. (2
points)
2) Le tableau de mémorisation des échantillons étant initialisé avec des 0, donner son contenu
pour le traitement de chacun des échantillons d’un signal défini par e={1,1,1}, avec h0=h1=0,5.
(1 point)
1) On peut s’inspirer fortement de la fonction C++ vue en cours, réalisant un filtrage de type RII, et
ne garder que la partie non-récursive correspondant à un filtre RIF. On suppose que le signal se
trouve dans un tableau de "nb_ech" échantillons e[].
ia=ib=0;
for j=1:nb_ech
s[j]=a[0]*e[j];
for i=0:1
ind=1-i+ia;
if (ind==2)
ind=0;
end
s[j]+=a[i+1]*em[ind];
end
em[ia]=e[j];
sm[ib]=s[j];
if (++ia==2)
ia=0;
end
if(++ib==2)
ib=0;
end
end //fin du for
2
2) Là encore, il suffit de reprendre l’exécution pas-à-pas du programme, également vue en cours :
em={0, 0} sm={0, 0}
itération 1 em={e0, 0}={1, 0} sm={s0, 0}={0,5, 0}
itération 2 em={e0, e1}={1, 1} sm={s0, s1}={0,5, 1}
itération 3 em={e2, e1}={1, 1} sm={s2, s1}={1, 1}
Exercice 4 : Filtrage de type RII en assembleur DSP56303 (6 points)
1) Calculer les coefficients de la fonction de transfert en Z d’un filtre analogique passe-bas du 1er
ordre, de fréquence de coupure fc=400Hz. La méthode de transformation est laissée libre. (2
points)
2) Donner l’équation aux différences de ce filtre et les équations de son implémentation
canonique. (2 points)
3) Donner les initialisations et la routine de traitement nécessaires à la programmation de ce filtre,
en assembleur DSP56303, avec l’implémentation canonique. (2 points)
1) La fonction de transfert d’un filtre passe-bas analogique du 1er ordre est définie par :
1
H(jω) =
ω
1+ j
ωc
avec ωc=2πfc. Pour le transformer en filtre numérique, on peut utiliser la transformée bilinéaire. Elle
consiste à remplacer jω par :
2 1− z
Te 1 + z
On a :
1 1+ z 1+ z
H(z) = = =
2 1− z 2 2 2
1+ 1+ z + (1 − z) 1 + + z(1 − )
Teωc 1 + z Teωc Teωc Teωc
On identifie cette fonction de transfert avec :
a +a z
H(z) = 0 1
1 + bz
ce qui donne :
1 1+ z 1 1+ z 1 1+ z
= . = . = .
2 2 2 2 2 4
1+ 1− 1+ 1 + z(1 + )(Teωc − 2) 1 + 1 + z(Teωc − )
Teωc Teωc Teωc Teωc Teωc Teωc
1+ z
1
2
1+
Teωc
d’où
1 4
a 0 = a1 = et b = Teωc −
2 Teωc
1+
Teωc
Te n’était pas donné donc on ne pouvait pas aller jusqu’à l’application numérique.
2) Equation aux différences :
s(n) = a 0e(n) + a1e(n − 1) − bs(n − 1)
Implémentation canonique :
w(n) = e(n) − be(n − 1)
3
s(n) = a 0 w(n) + a1w(n − 1)
3) On reprend le programme de filtre RIF étudié en cours et on l’adapte.
org X:$20 ;attention, "[Link]" met des choses en X:0
a0 dc 0.25 ;valeurs fausses ici
a1 dc 0.25
b dc 0.25
en dsm 2 ;emplacements mémoire pour e(n) et e(n-1)
wn dsm 2 ;emplacement mémoire pour w(n) et w(n-1)
move #en,R0 ;registre d’adresse R0 pointe sur en
move #1,M0 ;R0 modulo 2
move #a0,R1 ;R1 pointe sur a0
move #1,M1 ;R1 modulo 2
move #wn,R2 ;R2 pointe sur wn
move #1,M2 ;R2 modulo 2
clr A
do #2,finraz ;initialisation :
move A,X:(R0)+ ;0->e(n-i)
finraz
do #2,finraz2 ;initialisation :
move A,X:(R2)+ ;0->w(n-i)
finraz2
...
jsr rif_can ;appel de routine
...
rif_can ;début routine (B contient e(n))
move B,X:-(R0) ;e(n)->X:en (mémorisation de e(n), écrase le plus ancien e(n-i))
move X:(R0)+,X0 ;
move X:(R1)+,Y0 ;
mac X0,Y0,B ;B=e(n)-b*e(n-1)=w(n)
move B,X:-(R2) ;w(n)->X:wn (mémorisation de w(n), écrase le plus ancien w(n-i))
clr B
do #2,finmac ;boucle sur les multiplications-accumulations de la 2e équation
move X:(R2)+,X0 ;w(n-i)->X0
move X:(R1)+,Y0 ;a(i)->Y0
mac X0,Y0,B ;B=B+X0*Y0 <-> s(n)=s(n)+a(i)*w(n-i)
finmac
rts ;fin routine
Exercice 5 : TFR (Transformée de Fourier Rapide) en assembleur DSP56303 (6 points)
1) Ecrire un programme en assembleur DSP56303, permettant de copier les valeurs d’un tableau
de 16 éléments, placé en mémoire X à l’adresse $20, dans un autre tableau qui sera placé en
mémoire Y à l’adresse $30. On suppose que les adresses des éléments du tableau de départ ont
subi un renversement binaire ; elles doivent donc être remises dans l’ordre naturel. (2 points)
2) On dispose d’un programme réalisant une TFR et le renversement binaire des adresses des
points de sortie. Si on l’applique à un tableau de 64 points comportant 3 périodes d’un signal
sinusoïdal, quel doit être le résultat ? Justifier la réponse. (1 point)
3) Même question si le renversement binaire des adresses n’est pas réalisé. (1 point)
4) Ecrire un programme calculant le module des points de sortie de la TFR, dont on suppose que
la partie réelle se trouve dans un tableau en mémoire X, la partie imaginaire en mémoire Y. Le
résultat sera placé dans un autre tableau en mémoire Y. (2 points)
1) C’est ce que fait le programme "bit_rev.asm" disponible sur le site [Link]. Il suffit de
donner la routine de copie ici :
copie
move #data1,r2 ; r2 pointe sur la zone 'data1'
move #data2,r3 ; r3 pointe sur la zone 'data2'
move #-1,m2 ; programmation de l'adressage linéaire pour m2
move #0,m3 ; programmation de l'adressage 'bit reverse' pour m3
move #points/2,n2 ; nombre d'adresses qu'il faut inverser -> n2
; (= la moitié du tableau seulement)
do #points,fin_cop ; boucle de copie sur 'points' itérations
move x:(r2)+n2,x0 ; lecture de la valeur dans la mémoire source
move x0,x:(r3)+ ; écriture de la valeur dans la mémoire destination
; (avec adressage en 'bit reverse')
4
fin_cop rts
2) En théorie :
TF
j
s(t) = sin(2πft) S(f) = [δ(f + f0) − δ(f − f0) ]
2
Le résultat est imaginaire pur donc le tableau des parties réelles aura des éléments tous nuls.
Théoriquement, sans le renversement binaire apporté par la TFR, le premier Dirac sera en 4e
position car il y a 3 périodes de signal dans le tableau, d’amplitude -0,5. Le 2e sera la duplication du
Dirac situé dans les fréquences négatives ; il sera en N-3+1=64-2=62e position.
3) Si le renversement binaire des adresses n’est pas réalisé, il faut calculer les adresses de ces 2
Diracs. Celle du 1er est 2, soit 000010 sur 6 bits (car il faut 6 bits pour coder les adresses des 64
points) renversement binaire
2=000010 010000=16
Celle du 2e est 62 :
62=111110 011111=31
donc les 2 Diracs seront respectivement en 16e et en 32e position.
4) Sous forme de routine :
module move #data,R3 ; R3 pointe en début de tableau des sorties de la FFT (parties réelles)
move R3,R4 ; R4 idem pour les parties imaginaires
move #0,M3 ; R3 en adressage binaire inversé (résultats dans l'ordre naturel)
move M3,M4 ; idem pour R4
move #points/2,N3 ; adressage binaire inversé sur 'points/2' points
move N3,N4 ; idem pour R4
move #result,R2 ; R2 pointe sur tableau résultat (en adressage linéaire par défaut)
debmod do #points,finmod ; boucle de 'points' itérations
move X:(R3)+N3,X0
move Y:(R4)+N4,Y0
mpy X0,X0,A
macr Y0,Y0,A
move A,X:(R2)+
finmod
rts