Uebung 8: DSP-Realisierung FIR

Transcription

Uebung 8: DSP-Realisierung FIR
ZHAW, DSV1, 2009/01, Rumc, Hhrt, Dqtm
1
Uebung 8: DSP-Realisierung FIR-Filter
Teil 1: Bandpass
Matlab-Entwurf
a) Entwerfen Sie mit Hilfe der Fenster-Methode (Hamming-Fenster) ein FIR-Bandpass-Filter der
Ordnung N = 126 (127 Filterkoeffizienten), das einen Durchlassbereich von fDBu = 400 Hz bis
fDBo = 3400 Hz aufweist (-6 dB Eckfrequenzen).
Plotten Sie die Impulsantwort und den Amplitudengang [dB] des BP-Filters.
Speichern Sie die FIR-Filterkoeffizienten im h-File bp.h, mit dem Sie dann den entsprechenden Koeffizientenvektor im C-File initialisieren können.
Beachten Sie, dass Sie bei einem Fixed-Point-DSP die Koeffizienten im Q15-Format
abspeichern müssen (= mit 2^15 multiplizieren und Nachkommastellen abschneiden).
Hinweis: Sie können die Vorlage dsv1ueb8.m verwenden
DSP-Realisierung
Vorbereiten:
1. Die Vorlage für alle sample-basierten DSP-Labors finden Sie im Web unter
https://home.zhaw.ch/~rumc/dsv1/uebungen/DSK5510_vorlage.zip
Kopieren und dekomprimieren Sie dieses Archiv in ein lokales Verzeichnis und
entfernen Sie allenfalls den Schreibschutz.
2. Starten Sie die Entwicklungsumgebung Code Composer Studio und öffnen Sie
das Projekt mit Project -> Open... -> tone.pjt
Klicken Sie auf das + links von tone.pjt, unter Source finden Sie die Quelldatei
tone.c. Öffnen Sie diese durch Doppelklick.
3. Eine kurze Anleitung für die Arbeit mit der Entwicklungs-Umgebung finden Sie am
Ende der Datei tone.c
Hier wird auch beschrieben, wie Sie zum Debuggen Variablen verfolgen und
ändern können.
4. Die while-Schleife in der Vorlage liest den linken und den rechten Kanal ein,
kopiert diese beiden Samples um und gibt sie aus. Damit lässt sich testen, ob die
Entwicklungsumgebung und das Evaluationboard laufen, bevor mit dem
Programmieren begonnen wird.
b) Compilieren, laden und starten Sie das Programm. Das Signal am Eingang wird zum Ausgang
durchgeschlauft. Bevor Sie weitermachen testen Sie das mit CD-Player und Kopfhörer oder mit
Funktionsgenerator und Oszilloskop.
c) Messen Sie die Zeitverzögerung zwischen Eingangs- und Ausgangssignal. Sie stammt alleine
vom Codec.
Wieviele Abtastperioden Ts verzögert dieser Codec das Signal bei der AD-DA-Wandlung
insgesamt? Hinweis: Für welche Eingangsfrequenz ist die Zeitverschiebung 1 Periode?
2
ZHAW, DSV1, 2009/01, Rumc, Hhrt, Dqtm
d) Verwenden Sie die C-Funktion fir aus der DSPLIB (die mit dem DSP mitgeliefert wird).
Hier ist ein Ausschnitt aus dem Manual (Manual SPRU422i unter DSV1 Webpage, FIR Befehl
S.4-46):
ushort oflag = fir (DATA *x, DATA *h, DATA *r, DATA *dbuffer, ushort nx, ushort nh)
dbuffer[nh+2]
x
x[j+126]
x[j+125] x[j+124]
…
x[j+2]
x[j+1]
x[j]
…
b2
b1
b0
x[j-1]
h[nh]
b126
b125
b124
r
x[nx]
h[nh]
Pointer to input vector of nx real elements.
Pointer to coefficient vector of size nh in normal order. For example, if nh=6, then
h[nh] = {h0, h1, h2, h3, h4, h5} where h0 resides at the lowest memory address in
the array.·This array must be located in internal memory since it is accessed by the
C55x coefficient bus.
r[nx]
Pointer to output vector of nx real elements. In-place computation (r = x) is allowed.
dbuffer[nh+2]
Pointer to delay buffer of length nh = nh + 2·
In the case of multiplebuffering schemes, this array should be initialized to 0 for the first filter block only.
Between consecutive blocks, the delay buffer preserves the previous r output
elements needed.The first element in this array is special in that it contains the
array index-1 of the oldest input entry in the delay buffer. This is needed for
multiple-buffering schemes, and should be initialized to 0 (like all the other array
entries) for the first block only.
nx
Number of input samples
nh
The number of coefficients of the filter. For example, if the filter coefficients are
{h0, h1, h2, h3, h4, h5}, then nh = 6. Must be a minimum value of 3. For smaller
filters, zero pad the coefficients to meet the minimum value.
oflag
Overflow error flag (returned value)· If oflag = 1, a 32-bit data overflow occurred in
an intermediate or final result. If oflag = 0, a 32-bit overflow has not occurred.
Um zu testen, ob man eine Funktion richtig aufruft, verwendet man oft Trivialfilter, deren
Verhalten einfach und bekannt ist. Bei einem FIR-Filter ist das z.B. b0 = 1, b1 = 0, b2 = 0. Was
muss dieses Filter ausgeben?
Deklarieren und initialisieren Sie alle benötigten Variablen.
Packen Sie die Filter so in eine if-Verzweigung, dass die Filter nur bei gedrücktem DIPSchalter aktiv sind und das Signal sonst zum Ausgang durchgeschlauft wird. Das erleichtert
das Testen.
Erscheint das erwartete Signal am Ausgang
Hinweise:
• DATA ist das Q15-Format für den Fixed-Point-DSP
Werte-Bereich -1 .. +0.99997 entspricht -32768 .. +32767
In diesem Bereich müssen alle Zahlen vorliegen, sonst gibt es einen Overflow.
Die Signale x vom ADC und r zum DAC sind bereits im Q15-Format.
dbuffer ist der interne Verzögerungspuffer (beim Programmstart auf 0 init.).
h sind die Filter-Koeffizienten: aus b = {1, 0, 0} wird h = {32767, 0, 0}
3
ZHAW, DSV1, 2009/01, Rumc, Hhrt, Dqtm
•
•
•
Die Funktion fir arbeitet grundsätzlich mit Arrays (= Vektoren). Für Arrays werden in C beim
Funktionsaufruf standardmässig nur die Speicheradressen übergeben (per reference). Die
* bezeichnen also eine Adresse (= Pointer). Einfache Variablen hingegen werden auf den
Stack kopiert (per value).
Wenn wir Sample um Sample abarbeiten, sind die Samples in einfachen Variabeln
gespeichert. Die Adresse der Variabeln bekommt man durch voranstellen eines & vor den
Variablennamen.
Jedes Filter (je für den linken und für den rechten Kanal) benötigt einen eigenen
Verzögerungspuffer.
Die Funktionsaufrufe sehen dann so aus:
oflag_l = fir(&sample_in_l, h, &sample_out_l, dbuffer_l, 1, 3);
oflag_r = fir(&sample_in_r, h, &sample_out_r, dbuffer_r, 1, 3);
e) Implementieren Sie nun das FIR-BP-Filter, indem Sie den Koeffizientenvektor mit Hilfe des hFiles bp.h initialisieren.
Messen Sie den Amplitudengang mit dem Funkionsgenerator und dem KO aus.
Bei welchen Frequenzen ist die Amplitude um -6 dB bzw. -20 dB abgefallen?
Hinweis: Sie können das Filter auch mit dem NF-Spektrumanalysator (NWA) ausmessen.
Tracking out
(sweep output)
HP3580A
Spek.Analyzer
f)
DSP-C55x
Zünden Sie eine LED unmittelbar vor dem fir-Befehl an und unmittelbar nach dem firBefehl wieder aus.
Messen Sie die Rechenzeit in Sekunden und in DSP-Zyklen für der FIR-Routine (127 MACBefehle1) mit dem Oszilloskop (siehe unten wie). Vergleichen Sie diese Rechenzeit mit der ADDA Abtastperiode. Wie stark ist der DSP mit dieser FIR-Berechnung ausgelastet? Der DSP
arbeitet mit 200 MHz.
Verbinden Sie den DSP-Board-Ausgang mit Kanal 2 des Osziloskops (um den Signal-Ground
herzustellen). Messen Sie die Spannung mit der Messspitze am Kanal 1 direkt am LEDAnschluss am Rand des Boardes. Die LED brennt, wenn die Spannung = 0 ist.
g) Hören Sie sich die Filterwirkung mit einem Audio-Signal an.
1
Number of cycles for FIR command (preliminary benchmark from Programmers Reference ): (25+nx*(2+nh)) Zyklen
4
ZHAW, DSV1, 2009/01, Rumc, Hhrt, Dqtm
Teil 2: Tiefpass- und Komplementärfilter = Frequenzweiche
Matlab-Entwurf: Tiefpassfilter, Einfluss eines Koeffizienten betrachten
a) Entwerfen Sie mit Hilfe der Fenster-Methode (Hamming-Fenster) ein FIR-TP-Filter der
Ordnung N=126 (127 Filterkoeffizienten) mit einem Durchlassbereich bis fDB = 1000 Hz
(-6 dB Eckfrequenz).
b) Ändern Sie den 62ten Koeffizienten um 1% und kontrollieren Sie den Einfluss auf H(f).
Wiederholen Sie diese Analyse für eine Änderung von 5%.
c) Subtrahieren Sie ‚1’ von dem 63ten Koeffizient und kontrollieren Sie den Einfluss auf H(f). Wie
können Sie diese Änderung erklären?
DSP-Realisierung: Tiefpass- und Komplementärfilter
d) Realisieren Sie das Tiefpass Filter und das komplementäre Hochpass-Filter (aus Punkt (c))
und geben Sie die entsprechenden Ausgänge auf den linken und rechten Kanal aus. Messen
Sie die Filter aus und hören Sie sich die Filterwirkung an. Aufpassen „-1“ in Q15 bedeutet –
(2^15).
Hinweise:
Das DSP-Programm kann aus Aufgabe 1 übernommen werden. Der Koeffizientenvektor muss
allerdings mit den TP-Filterkoeffizienten (tp.h) initialisiert werden.
sample_in_r = sample_in_l; damit gleiches Eingangssignal für beide Filter.
DSP-Realisierung: Tiefpass- und Komplementärfilter, Rechenaufwand ~ halbiert
e) Nehmen Sie das Tiefpass Filter von Aufgabe d) und realisieren Sie das komplementäre
Hochpass-Filter HHP(z) = z-N/2 - HTP(z) wie in der folgenden Abbildung dargestellt:
yTP[n] zum linken Kanal ausgeben
HTP(z)
x[n]
z
-N/2
+
yHP[n] zum rechten Kanal ausgeben
Das Hochpass-Filter HHP(z) = z-N/2 - HTP(z) muss nicht mit einem Filter realisiert werden.
Es kann durch Verzögerung des Eingangssignals x[n] (Ringbuffer) und Subtraktion von yTP[n]
realisiert werden. Man spart so 127 MAC-Operationen!
Die Verzögerung z-N/2 entspricht der Verzögerung des Tiefpass-Filters. Beide Signale müssen
gleich lange verzögert werden, bevor sie subtrahiert werden können.
Realisieren Sie die Verzögerung z-N/2 mit einem Ringbuffer der Länge N/2. Geben Sie die
beiden Ausgangssignale yTP[n] und yHP[n] gleichzeitig über den linken und den rechten Kanal
aus. Messen Sie die Filter aus und hören Sie sich die Filterwirkung an.
Hinweise: Sie benötigen als Variablen nur einen DATA-Array für den Ringbuffer und eine
Integervariable für den Pointer.
Der neueste Wert wird an die Stelle im Ringbuffer-Array geschrieben, die durch den Pointer
indiziert wird. Der Pointer wird anschliessend inkrementiert. Wenn der Pointer an der
Arraygrenze angelangt ist, wird er auf 0 zurückgesetzt.
sample_in_r = sample_in_l; damit gleiches Eingangssignal für beide Filter.