Dsvdoc
Upcoming SlideShare
Loading in...5
×

Like this? Share it with your network

Share
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
920
On Slideshare
920
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
5
Comments
0
Likes
0

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Praktikum Digitale Signalverarbeitung Institut für Nachrichtengeräte und Datenverarbeitung Prof. Dr.-Ing. Peter Vary
  • 2. Inhaltsverzeichnis 1 Der Signalprozessor Analog Devices ADSP-21369 7 1.1 Grundlagen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 1.1.1 Einleitung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 1.1.2 Grundstruktur der Signalprozessor-Architektur . . . . . . . . . . . 7 1.2 Signalprozessor Analog Devices ADSP-21369 . . . . . . . . . . . . . . . . 12 1.2.1 Architektur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 1.2.2 Datenformate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 1.2.3 Recheneinheiten und Datenregister . . . . . . . . . . . . . . . . . 15 1.2.4 Das Programm-Steuerwerk . . . . . . . . . . . . . . . . . . . . . . 18 1.2.5 Datenadressierung . . . . . . . . . . . . . . . . . . . . . . . . . . 24 1.2.6 Speicher . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 1.3 Entwicklungsumgebung: Visual DSP++ . . . . . . . . . . . . . . . . . . . 28 1.3.1 Einführung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 1.3.2 Implementierung des Source-Codes . . . . . . . . . . . . . . . . . 29 1.4 Versuchsdurchführung . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 1.4.1 Einführung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 1.4.2 Programm 1: Interruptgesteuerte Ein-/Ausgabe . . . . . . . . . . . 35 1.4.3 Programm 2: Parallele Verarbeitung von Befehlen . . . . . . . . . . 45 1.4.4 Programm 3: Benutzung des Rahmenprogramms . . . . . . . . . . 49 2 Grundlagen MATLAB und SIMULINK 53 2.1 Einleitung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 2.2 Grundlagen der digitalen Signalverarbeitung . . . . . . . . . . . . . . . . . 54 2.2.1 Abtastung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 2.2.2 Quantisierung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 2.3 Einführung in MATLAB . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 2.3.1 Starten von MATLAB . . . . . . . . . . . . . . . . . . . . . . . . 56 3
  • 3. 2.3.2 Benutzung von Hilfe-Funktionen .................. 58 2.3.3 Verwendung von Variablen . . . . . . . . . . . . . . . . . . . . . . 60 2.3.4 Operationen mit Vektoren und Matrizen . . . . . . . . . . . . . . . 62 2.3.5 Elementare Funktionen . . . . . . . . . . . . . . . . . . . . . . . . 64 2.3.6 Grafische Darstellungsmöglichkeiten . . . . . . . . . . . . . . . . 65 2.3.7 Audiowiedergabe . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 2.3.8 Verwalten von Daten und Dateien . . . . . . . . . . . . . . . . . . 65 2.3.9 Erstellen von Skripten und Funktionen . . . . . . . . . . . . . . . . 66 2.4 Einführung in SIMULINK . . . . . . . . . . . . . . . . . . . . . . . . . . 67 2.4.1 Starten von SIMULINK . . . . . . . . . . . . . . . . . . . . . . . 68 2.4.2 Die Quellen eines SIMULINK-Modells . . . . . . . . . . . . . . . 70 2.4.3 Die Senken eines SIMULINK-Modells . . . . . . . . . . . . . . . 71 2.4.4 Starten einer Simulation mit Angabe von Simulationsparametern . . 71 2.5 DSP-Debugging mit MATLAB . . . . . . . . . . . . . . . . . . . . . . . . 72 2.6 Vorbereitende Aufgaben . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 2.6.1 Aufgabe I . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 2.6.2 Aufgabe II . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 2.6.3 Aufgabe III . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 2.6.4 Aufgabe IV . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 2.7 Versuchsdurchführung . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77 2.7.1 Versuch A: Grundlegende MATLAB-Operationen . . . . . . . . . 77 2.7.2 Versuch B: MATLAB-Funktionen . . . . . . . . . . . . . . . . . . 78 2.7.3 Versuch C: DSP-Debugging mit MATLAB . . . . . . . . . . . . . 79 2.7.4 Versuch D: Echo-Effekt mit dem DSP / Zyklischer Speicher . . . . 79 2.7.5 (*) Versuch E: Rückfaltungen . . . . . . . . . . . . . . . . . . . . 80 2.7.6 (*)Versuch F: Grobquantisierung . . . . . . . . . . . . . . . . . . . 81 2.7.7 (*)Versuch G: Amplitudenmodulation mit Hüllkurvenempfang . . . 82 Literaturverzeichnis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84 3 Diskrete Fourier-Transformation (DFT) 85 3.1 Einleitung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85 3.2 Theoretische Grundlagen . . . . . . . . . . . . . . . . . . . . . . . . . . . 85 3.2.1 Definition und Eigenschaften der DFT . . . . . . . . . . . . . . . . 85 3.2.2 Fensterfunktionen .......................... 87 3.2.3 Schnelle Fourier-Transformation (FFT) . . . . . . . . . . . . . . . 93 3.2.4 Schnelle Faltung . . . . . . . . . . . . . . . . . . . . . . . . . . . 93 4
  • 4. 3.3 Vorbereitende Aufgaben . . . . . . . . . . . . . . . . . . . . . . . . . . . 97 3.3.1 Aufgabe I . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97 3.3.2 Aufgabe II . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98 3.3.3 Aufgabe III . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98 3.4 Versuchsdurchführung . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101 3.4.1 Versuch A: DFT spezieller Signale . . . . . . . . . . . . . . . . . . 101 3.4.2 Versuch B: Zero-Padding . . . . . . . . . . . . . . . . . . . . . . . 102 3.4.3 Versuch C: Fensterung und Leckeffekt . . . . . . . . . . . . . . . . 102 3.4.4 Versuch D: Schnelle Faltung mittels overlap add Verfahren . . . . . 103 3.4.5 Versuch E: FFT auf dem DSP . . . . . . . . . . . . . . . . . . . . 106 3.4.6 (*)Versuch F: Gemeinsame Transformation zweier reeller Signale . 106 3.4.7 (*)Versuch G: Analyse von Signalen mit diskr. spektr. Komponenten 107 Literaturverzeichnis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108 4 Digitale FIR- und IIR-Filter 109 4.1 Einleitung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109 4.2 Beschreibung linearer zeitdiskreter Systeme . . . . . . . . . . . . . . . . . 109 4.3 FIR-Filter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111 4.3.1 FIR-Filter mit linearer Phase . . . . . . . . . . . . . . . . . . . . . 111 4.3.2 FIR-Filterentwurf . . . . . . . . . . . . . . . . . . . . . . . . . . . 115 4.4 IIR-Filter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119 4.4.1 Stabilität . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119 4.4.2 Filterstrukturen . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119 4.4.3 IIR-Filterentwurf . . . . . . . . . . . . . . . . . . . . . . . . . . . 123 4.5 Spezielle Filter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125 4.5.1 Differentiation . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125 4.5.2 Integration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126 4.5.3 Hilbert-Transformation . . . . . . . . . . . . . . . . . . . . . . . . 126 4.5.4 Interpolation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127 4.6 Eigenschaften realer Filter . . . . . . . . . . . . . . . . . . . . . . . . . . 128 4.6.1 FIR-Filter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128 4.6.2 IIR-Filter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130 4.7 Vorbereitende Aufgaben . . . . . . . . . . . . . . . . . . . . . . . . . . . 134 4.7.1 Aufgabe 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134 4.7.2 Aufgabe 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134 4.7.3 Aufgabe 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134 5
  • 5. 4.7.4 Aufgabe 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135 4.7.5 Aufgabe 5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135 4.7.6 Aufgabe 6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136 4.8 Versuchsdurchführung . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137 4.8.1 FIR-Versuch A: Rechteck-, Hamming- und Blackman-Fenster . . . 137 4.8.2 FIR-Versuch B: Kaiser-Fenster . . . . . . . . . . . . . . . . . . . . 137 4.8.3 FIR-Versuch D: Differentiation . . . . . . . . . . . . . . . . . . . . 138 4.8.4 FIR-Versuch E: FIR-Filter auf dem DSP . . . . . . . . . . . . . . . 138 4.8.5 (*)FIR-Versuch F: Koeffizienten-Quantisierung . . . . . . . . . . . 139 4.8.6 (*) FIR-Versuch G: Tschebyscheff-Approximation . . . . . . . . . 139 4.8.7 IIR-Versuch A: Rekursive Differenzengleichung . . . . . . . . . . 139 4.8.8 IIR-Versuch B: Spezielle rekursive Filter . . . . . . . . . . . . . . 140 4.8.9 IIR-Versuch C: Sprungantwort und Einschwingzeit . . . . . . . . . 142 4.8.10 (*)IIR-Versuch D: Vergleich verschiedener Approximationsverfahren 142 Literaturverzeichnis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144 6
  • 6. Kapitel 1 Der Signalprozessor Analog Devices ADSP-21369 1.1 Grundlagen 1.1.1 Einleitung Im ersten Versuch wird der Aufbau und die Programmierung des Prozessors ADSP-21369 von Analog Devices erklärt. Um einen leichten Einstieg in die Projektphase im Anschluss zu ermöglichen, wurde am IND eine Software erstellt. Die Prinzipien dieser Software sind im zusätzlichen Dokument „Rapid Prototyping on Embedded targets: RTProcDSP“ erläu- tert. Durch die Software-Vorgabe wird es den Studenten ermöglicht, den Prototypen eines neuartigen Algorithmus zu erstellen, ohne allzuviel mit den Programmierungsdetails des Echtzeit- Betriebssystems in Kontakt zu kommen. Zur Programmierung der Hardware bietet Analog Devices eine Entwicklungsumgebung an, die sich Visual DSP++ nennt. Diese wird schließlich kurz vorgestellt. Mit ihrer Hilfe wer- den im Anschluss die Übungsbeispiele simuliert bzw. emuliert. 1.1.2 Grundstruktur der Signalprozessor-Architektur In den letzten Jahren war bei Bauteilen in Hardware-Komponenten neuer Produkte eine Spezialisierung auf den Anwendungsfall zu beobachten. Es macht keinen Sinn, für Algo- rithmen zur reinen Signalverarbeitung die Kosten eines General-Purpose Prozessors (z.B. Intel Pentium Prozessor) bezahlen zu müssen, wenn dieselben Algorithmen von einem Pro- zessor ausgeführt werden können, der auf diese Art von Anwendungen spezialisiert ist. Gleichzeitig erscheint es auch in vielen Bereichen sinnvoll, Algorithmen nicht in „Silicon“, also Hardware, sondern in Software zu realisieren. Dadurch kann auf sich ändernde Sys- temanforderungen bei existierenden Produkten schnell und umfassend reagiert werden, in- dem zum Beispiel Software-Updates durchgeführt werden. DSPs sind für Echtzeitanwendungen, z. B. im Bereich der Audio- und Videoverarbeitung, entwickelt worden und verfügen über für ihren Einsatz angepasste Befehlssätze und Archi- tekturen. Sie haben einen niedrigen Leistungsverbrauch und sind durch ihre Spezialisierung in der Anschaffung sehr günstig. Ein Programmierer kann im Bereich der Signalverarbeitungs- 7
  • 7. Algorithmen sehr kompakten Code erzeugen, was zu einer Minimierung des Speicherbe- darfs in einem Produkt führt. Die ersten Signalprozessoren waren modular aus Bit-Slice-Elementen aufgebaut. Der damit verbundene hohe Aufwand beschränkte den Einsatz der digitalen Signalverarbeitung auf spezielle Gebiete. Erst die Entwicklung monolithisch integrierter Signalprozessoren An- fang der achtziger Jahre ermöglichte den Einsatz der DSV in vielen kommerziellen Berei- chen. Mittlerweile existiert ein breites Angebot digitaler Signalprozessoren verschiedener Hersteller. Trotz ihrer unterschiedlichen und komplexen Architekturen enthalten die heutigen Signal- prozessoren gemeinsame Grundstrukturen. Diese Grundstrukturen ergeben sich aus den An- forderungen der DSV-Algorithmen. Die für die DSV exemplarischen Algorithmen wie z. B. die Fourier-Transformation, die Korrelation und die digitale Filterung enthalten in ihrem Kern vektorielle Skalarprodukte. Um diese Skalarprodukte schnell berechnen zu können, sind Signalprozessoren mit einem Hardware-Multiplizierer ausgestattet. Diesem ist ein Addierer/Akkumulator nachgeschal- tet. Abbildung 1.1 zeigt den prinzipiellen Aufbau der Recheneinheit (Daten-ALU (Arithmetic Logical Unit)) am Beispiel eines 16 Bit Festkomma Signalprozessors. Die zu verarbeiten- den Daten werden in Eingangsregistern zwischengespeichert und dem Multiplizierer zu- geführt. Damit keine Genauigkeitsverluste auftreten, wird das Ergebnis der Multiplikation zunächst mit einer Wortbreite von 31 bzw. 32 Bit dargestellt und zum Inhalt des Ausgangs- registers addiert. Die mit insgesamt 40 Bit um 8 Bit größeren Wortbreiten von Addierer und Ausgangsregister ermöglichen die überlauffreie Addition von bis zu 28 = 256 Produkten. Abbildung 1.1: Daten-ALU eines 16-Bit Signalprozessors Erst wenn das Ergebnis feststeht, also alle Multiplikationen und Additionen durchgeführt wurden, verringert ein sogenannter Barrelshifter die Ergebniswortbreite auf das ursprüng- liche 16 Bit Format. Dabei kann eine mathematische Rundungsoperation und eine betrags- mäßige Begrenzung eingeschlossen sein. Multiplizierer und Addierer arbeiten gleichzeitig. Das bedeutet, dass in einem Maschinen- 8
  • 8. zyklus die Werte aus den Eingangsregistern multipliziert werden können und das Ergebnis des Multiplizierers im Addierer verarbeitet werden kann. Damit werden zwei Rechenope- rationen pro Zyklus ausgeführt. Das vektorielle Skalarprodukt y der Dimension N kann im Prinzip in N Prozessorzyklen berechnet werden: N−1 y = x · bT = bi · xi (1.1) i=0 mit x = {x0 , x1 , . . . , xN−1 } (1.2) und b = {b0 , b1 , . . . , bN−1 }. (1.3) Das hier beschriebene gleichzeitige Addieren und Multiplizieren ist eines der wichtigsten Merkmale eines Signalprozessors und wird durch spezielle multiply/accumulate-Befehle unterstützt. Bei einigen Signalprozessoren werden die Multiplikation und die Addition in zwei aufeinander folgenden Zyklen, d.h. im „Pipeline“ - Betrieb durchgeführt. Im Akku- mulator wird dabei jeweils das Produktergebnis aus dem vorhergehenden Befehlszyklus auf das Ausgangsregister aufaddiert. Da der Multiplizierer und der Akkumulator gleichzei- tig arbeiten, dauert die Berechnung des Skalarproduktes der Dimension N insgesamt N + 1 Takte. Selbstverständlich bietet ein DSP auch die Möglichkeit, nur zu addieren oder nur zu multi- plizieren. Weiterhin gehören Bit-Manipulationsbefehle und logische Operationen zum Be- fehlsrepertoire eines Signalprozessors. Im vorgestellten Beispiel müssen nach jedem Maschinenzyklus zwei neue Eingangsdaten bereitstehen, wenn die Daten-ALU ausgelastet werden soll. Zusätzlich muss in jedem Pro- grammschritt ein Befehlswort gelesen werden. Das bedeutet drei Datenübertragungen pro Zyklus. Diese hohe Übertragungrate wird durch eine sogenannte „Harvard-Architektur“ er- möglicht. Diese Architektur verfügt im Gegensatz zur „von Neumann-Struktur“ über se- parate Programm- und Datenspeicher sowie über separate Daten- und Adressbusse. Da- durch sind Schreib- und Leseoperationen im Datenspeicher möglich, während gleichzeitig Instruktionen aus dem Programmspeicher gelesen werden. Eine Super-Harvard-Architektur bietet zusätzlich die Möglichkeit, Instruktionen in einem Cache zwischenzuspeichern. Der betrachtete Prozessor ADSP-21369 entspricht in seinem Aufbau einer Super-Harvard Architektur. Abbildung 1.2 zeigt das Prinzipschaltbild eines derartigen Signalprozessors mit erweiterter Harvard-Architektur. Neben der Daten-ALU, dem Programm- und dem Datenspeicher sind zwei weitere Kom- ponenten zu erkennen: die Programm-Ablaufsteuerung und die Adress-ALU. Die Adress-ALU berechnet bei dieser Architektur pro Maschinenzyklus die beiden Spei- cheradressen der Daten für die nächste Operation der Daten-ALU. Erst dadurch wird si- chergestellt, dass in jedem Befehlszyklus neue Daten zu den Eingangsregistern übertragen werden können. Der Befehlssatz der Adress-ALU ist auf die Belange der DSV abgestimmt. Hervorzuheben ist z. B. die in der Regel verfügbare Modulo-Adressarithmetik. Bei dieser Adressierungsart 9
  • 9. Abbildung 1.2: Prinzipielle Architektur eines digitalen Signalprozessors (DSP) erzeugt die Adress-ALU aufeinanderfolgende Adressen innerhalb eines bestimmten Berei- ches. Ist das Bereichsende erreicht, so wird mit dem Bereichsanfang fortgefahren, ohne dass dazu zusätzliche Programmschritte notwendig sind. Diese Eigenschaft lässt sich z. B. vorteilhaft in Programmen nutzen, in denen Daten blockweise verarbeitet werden (Modulo- Adressierung, vgl. Abschnitt 1.2.5). Die Leistungsmerkmale der heute verfügbaren Prozessoren unterscheiden sich bezüglich • Arithmetik • Speicherkapazität • Geschwindigkeit • Architektur und Befehlssatz. Für eine kleine, repräsentative Auswahl aus dem derzeitigen Angebot wurden in Tabelle 1.1 einige Angaben zum Entwicklungsstand integrierter Signalprozessoren zusammengestellt. 10
  • 10. Firma Typ Jahr Zyklus/Frequenz Wortbreite Arithmetik Daten-RAM Infineon Carmel 10xx 4 ns/250 MHz 16 bit Festkomma (← Core) Carmel 20xx (Core) a 32k b Tricore 97-99 6 ns/167 MHz 16/32 Gleitkomma (MCU-DSP) Texas TMS320C25 1987 80 ns/12,5 MHz 16 Festkomma 4k x 16 Instruments TMS 320C40 33 ns/30 MHz 32 Gleitkomma 2k x 16 TMS 320C50 25 ns/40 MHz 16 Festkomma 10k x 16 TMS 320C62 1997 5 ns/200 MHz 16 Festkomma 2 x 512k TMS 320C67 1997 6 ns/167 MHz 32 Gleitkomma 2 x 512k TMS 320C64 2000 0,9 ns/1100 MHz (← Core) (Core) Motorola 56001 1987 100 ns/10 MHz 24 Festkomma 2 x 512k x 24 56301 12,5 ns/80 MHz 24 Festkomma 2 x 2k x 24 56800E 2000 5 ns/200 MHz 8-32 Festkomma (← Core) (MCU-DSP) 56853 2001 8,3 ns/120 MHz 32k Analog ADSP-21060 1995 25 ns/40 MHz 32 Gleitkomma 2 x 2M Devices ADSP-21065L 1995 16 ns/60 MHz 32 Gleit/Fest 1M 2192 (Dual) 2000 6,25 ns/160 MHz 16 Festkomma (← Core) 21116 ($5) 2000 10 ns/100 MHz 32 Gleitkomma ADSP-21369 2005 2,5 ns/400 MHz 32 Gleit/Fest 16M a CLIW and power plugs support b Caches-support Tabelle 1.1: Auswahl von aktuellen und alten DSPs 11
  • 11. 1.2 Signalprozessor Analog Devices ADSP-21369 1.2.1 Architektur Zunächst soll ein Überblick über die Prozessorarchitektur und seine für den Versuch re- levanten Komponenten vorgestellt werden. Abschnitt 1.2 ist als eine kurze Einführung zu verstehen. Für weitere Informationen wird auf die „ADSP-2136x SHARC Programming Reference“ verwiesen, die im Folgenden kurz „Handbuch“ genannt wird. Der in Versuch 4 und der anschließenden Projektphase eingesetzte Signalprozessor ADSP- 21369 ist ein 32 Bit Gleitkommaprozessor, der bei einer Taktfrequenz von 333 MHz arbeitet und 8 MB on-chip-Speicher hat (2 MB SRAM und 6 MB ROM). Er hat darüberhinaus einen Cache-Speicher, der 32 Befehle halten kann, und eine große Anzahl von Registern (spezielle Speicherstellen, die z. B. Operanden und Ergebnisse enthalten). Dank paralleler Ausführung großer Teile der ALU werden SIMD-Befehle (Single Instruction Multiple Data) unterstützt, so dass der Prozessor bei voller Auslastung 2 GFLOPS (Giga Floating Point Operations per Second) verrichten kann. Multi-Prozessor-Einsatz wird durch Link Ports unterstützt. Mit dem DMA (Direct Memory Access) Controller lassen sich große Datenblöcke ein- und ausgeben, ohne dass die Rechenkapazität des Prozessors reduziert wird. Auf der Versuchshardware ist ein solcher Prozessor vorhanden. Desweiteren befindet sich auf derselben Platine ein externer Speicher (SDRAM), der Platz für 4 Mega-Wort Daten beinhaltet (32-Bit Worte) sowie ein 1 MB großer nichtflüchtiger Speicher (Flash-EEPROM). Zur Peripherie gehören außerdem ein AD/DA-Wandler (AD1835A), über den die Audioein- und ausgabe abläuft, sowie eine UART-Schnittstelle (ADM3202 RS-232), die der Laufzeit- Komunikation mit dem PC dient. Die Audiodaten werden mit einer Abtastfrequenz von bis zu 96 KHz, in der Regel aber 48 KHz eingelesen (bei einem DAC sogar bis zu 192Hz) und mit 16, 20 oder 24 Bit quantisiert. Die UART-Schnittstelle hat eine Datenübertragungsrate von 9600 bis 115200 Baud und dient der Übergabe von Variablen vom PC an den DSP und andersherum. Die einzelnen Prozessor-Kennzahlen sind in Tabelle 1.2 zusammengefasst. Prozessortyp ADSP-21369 Datentyp Gleitkomma (32 oder 40 Bit) Festkomma (16 oder 32 Bit) Speicher 2 MB SRAM + 6 MB ROM + 512 kBit SRAM + 4 Mx32 SDRAM + 8 MBit parallel flash + 2 Mbit SPI flash Taktfrequenz 333 MHz Analoge Ausgänge 4 Stück, Stereo Analoge Eingänge 1 Stück, Stereo Abtastraten bis zu 96 kHz 16, 20 oder 24 Bit Analoge Verstärkung Vor- und Nachverstärkung Schnittstelle UART, 16550, 115200 Baud Tabelle 1.2: Prozessor-System-Merkmale Abbildung 1.3 zeigt das vereinfachte Blockschaltbild des ADSP-21369. Es handelt sich um 12
  • 12. eine „Super Harvard-Architektur“ (daher SHARC) mit SIMD-Funktionalität. Abbildung 1.3: Vereinfachtes Blockschaltbild des ADSP-21369 Der Prozessorkern (core processor) des ADSP-21369 besteht aus zwei Verarbeitungseinhei- ten (PEX und PEY), von denen jede aus drei Recheneinheiten (ALU, Multiplizierer, Shif- ter) besteht sowie einem Programm-Steuerwerk, zwei Daten-Adressrechnern (DAG1 und DAG2) mit jeweils acht Registern für indirekte Adressierung, zwei Timern, dem Befehls- Cache und aus 16 Data-Registern im Data Register File. Darüber hinaus existieren meh- rere Modus- und Statusregister, die die Funktion des Prozessors steuern (z. B. die Register MODE1 und MODE2) und Aussage über Rechenergebnisse geben (z. B. das ASTAT Register). Diese Register sind nicht in Abbildung 1.3 eingezeichnet. Weiterhin sind in obiger Abbildung die DMA-Controller, acht full-duplex-fähige seriel- le Schnittstellen, eine digitale Audioschnittstelle, die vier Präzisionstaktgeber (PCG), ei- ne Eingabeschnittstelle (IDP), ein S/PDIF-Empfänger/-Sender, acht Kanäle mit jeweils ei- nem asynchronen Abtastratenkonverter, acht serielle Schnittstellen, eine 16-bit Parallelein- gabeschnittstelle (PDAP) und eine flexible Signal-Routing-Einheit (DAI SRU) enthält so- wie ein Digital-Peripheral-Interface dargestellt, das drei Taktgeber, eine I2C-Schnittstelle, zwei UARTs, zwei serielle periphere Schnittstellen (SPI) und eine flexible Signal-Routing- Einheit (DPI SRU) enthält. Wie oben schon erwähnt, verfügt der ADSP-21369 über SIMD-Funktionalität. Generell wird die Verarbeitungseinheit PEX benutzt. Eine gleichzeitige Verwendung der Einheit PEY kann durch Setzen des PEYEN-Mode-Bits im MODE1-Register aktiviert werden. Ist dies der Fall, so werden die selben Instruktionen in beiden Verarbeitungseinheiten ausgeführt, operieren allerdings auf verschiedenen Daten. Diese Architektur ist besonders bei rechen- intensiven Algorithmen effizient. Das Einschalten des SIMD-Modus’ hat auch eine Auswirkung auf die Art und Weise, wie Daten zwischen Speicher und den beiden Verarbeitungseinheiten übertragen wird. Ist dieser Modus aktiviert, so wird eine doppelte Datenbandbreite gebraucht, um den Rechenfluss in beiden Einheiten aufrecht zu erhalten, so dass im SIMD-Modus mit jedem Zugriff auf 13
  • 13. den Speicher oder die Register also zwei Datenwerte transferiert werden. Dementsprechend müssen die Daten auch im Speicher auf korrekte Weise abgelegt werden müssen. Bevor nun die Einheiten des Prozessors näher betrachtet werden, sollen erst die zur Verfü- gung stehenden Datenformate erwähnt werden: 1.2.2 Datenformate Der ADSP-21369 bietet sowohl Fest- als auch Gleitkomma-Formate an. Mit der Festkomma- darstellung wird eine Zahl durch 32 Bits repräsentiert. In einem Register im Data Register File belegen sie die obersten 32 der 40 Bits. Man unterscheidet zwischen den Darstellungen signed und unsigned bzw. integer und fractional. Beim signed-Format ist das ers- te Bit das Vorzeichenbit. Negative Zahlen werden durch das Zweierkomplement dargestellt. Der Wert des LSBs ist für signed integer gleich 1 bzw. für signed fractional 2−31 . So ergeben sich die Zahlenbereiche − 231 ≤ x ≤ 231 − 1 (signed integer, SI) (1.4) −31 −1 ≤ x ≤ 1 − 2 (signed fractional, SF). (1.5) Mit dem unsigned-Format können nur positive Zahlen dargestellt werden. Es gelten die Zahlenbereiche 0 ≤ x ≤ 232 − 1 (unsigned integer, UI) bzw. 0 ≤ x ≤ 1 − 2−32 (unsigned fractional, UF). Die Gewichte der einzelnen Bits sind in Abbildung 1.4 verdeutlicht. Abbildung 1.4: Die Gewichte einzelner Bits verschiedener Festkommafor- mate bei Speicherung in einem 40-Bit Register Zusätzlich zu der Festkommadarstellung bietet der ADSP-21369 ein Gleitkomma-Format mit entweder 32 Bits oder 40 Bits an. Es besteht aus einem Vorzeichenbit s, 8 Bits für den Exponenten e und 23 bzw. 31 Bits für den Bruchteil f der Basis, der durch 1. f dargestellt wird. 1. f ist dabei eine Zahl zwischen 1 und 2 − 2−23 bzw. 1 und 2 − 2−31 . Der Wert einer Zahl x ergibt sich dann aus dem Zusammenhang x = (−1)s · (1. f ) · 2e−127 (1.6) Abbildung 1.5 zeigt die Bitbelegung im Speicher. Durch die Gleitkommadarstellung lassen sich Quantisierung und Übersteuerungsprobleme weitgehend vermeiden. Sie bietet sich deswegen bei der Entwicklung neuer Algorithmen und Prototypen an. 14
  • 14. Abbildung 1.5: Gleitkomma-Formate für 32 bzw. 40 Bits 1.2.3 Recheneinheiten und Datenregister Der Prozessorkern enthält wie in Abbildung 1.6 veranschaulicht drei unabhängige Rechen- einheiten: eine ALU, einen Multiplizierer und einen Shifter. Abbildung 1.6: Aufbau der Core Unit Alle drei Datenformate können verarbeitet werden: 32 Bit Festkomma, 32 Bit Gleitkomma bzw. 40 Bit Gleitkomma. Zwischen den Recheneinheiten und den Datenbussen befinden sich die Datenregister (register file). Sie bestehen aus 16 Registern der Breite 40 Bit, in de- nen Rechenoperanden und Ergebnisse gespeichert werden. Da alle Rechenoperationen nur einen Prozessorzyklus benötigen, können die Ergebnisse eines Zyklus’ im darauffolgenden Zyklus beliebig weiterverwendet werden. Ein Register wird mit „F“ und einer Nummer 0-15 angesprochen, wenn es für Gleitkomma- operationen verwendet wird, und mit „R“ und einer Nummer für Festkommaoperationen. Das MR Register dient zur Speicherung eines Fixed-Point-Multiplikations Ergebnisses. 15
  • 15. Um einen schnellen Kontextwechsel zu ermöglichen, stehen alle Register in zweifacher Ausführung zur Verfügung. Die Modifikation eines entsprechenden Statusbits verursacht, dass alle Prozessoroperationen auf diesen „Schatten“-Registern ausgeführt werden. ALU Die ALU verfügt über eine Vielzahl arithmetischer und logischer Operationen für sowohl Festkomma- als auch Gleitkommadarstellungen. Für eine umfassende Liste dieser Opera- tionen sei auf das Handbuch verwiesen. Hier ein kleines Beispiel: Beispiel: 1. Addiere den Inhalt des Registers F0 zu dem des Registers F1 und spei- chere das Ergebnis in F0 F0 = F0 + F1; 2. Nimm den Betrag von F0 und speichere das Ergebnis in F1 F1 = ABS F0; 3. Nimm den maximalen Wert von R1 und R2 und speichere das Ergebnis in R0 R0 = MAX (R1, R2); Alle Befehle sowie „F“ und „R“ können entweder groß oder klein geschrieben werden, da der Assembler Groß- und Kleinschreibung nicht unterscheidet. In dem Statusregister ASTAT befinden sich Flaggen, die nach dem Beenden einer ALU-Operation gesetzt wer- den. Z. B. wird die Flagge AZ (Bit 0) gesetzt, wenn das Ergebnis der Operation Null ist. Abbildung 1.7 zeigt die Bedeutung der einzelnen Bitstellen des Statusregisters ASTAT. Abbildung 1.7: Aufbau des ASTAT-Registers Die ALU wird auch für bitbezogene Operationen wie logische AND, OR, NOR und NOT verwendet. Beispielsweise können mit AND einzelne Bits herausmaskiert und mit OR ein- 16
  • 16. zelne Bits gesetzt werden. Außerdem kann mit XOR kontrolliert werden, in welchen Posi- tionen sich zwei Register unterscheiden. Die logischen Operationen sind nur für Festkom- maoperanden definiert und haben nur einen Einfluss auf die oberen 32 Bits eines Registers. Die letzten 8 Bits werden zu Null gesetzt. Abbildung 1.8: Beispiel für ALU-Operationen Im Register MODE1 befinden sich drei Flaggen, mit denen u.a. entschieden wird, ob das Ergebnis einer Festkommaoperation ggf. gesättigt werden soll und wie Gleitkommaresultate gerundet werden sollen, siehe Handbuch, Abschnitt 2.5.2. Eine vollständige Beschreibung des MODE1-Registers befindet sich im Handbuch auf den Seiten E-14 und E-15. Multiplizierer Mit dem Multiplizierer können Festkomma- oder Gleitkommamultiplikationen durchge- führt werden. Das Resultat einer Festkommamultiplikation kann in einem der beiden Mul- tiplikatorregister (MRF oder MRB) oder in einem Datenregister R0 - R15 gespeichert wer- den. Bei Nutzung der Multiplikatorregister kann im selben Zyklus eine Addition zu oder Subtraktion von dem letzten Inhalt des Registers vorgenommen werden. Beispiel: 1. Multipliziere den Inhalt des Registers R0 mit dem von R1. Das Ergebnis wird zum Inhalt von MRF addiert. MRF = MRF + R0 · R1; Auf diese Art und Weise kann sehr einfach eine multiply/accumulate-Operation implemen- tiert werden. Das Standardformat für Festkommamultiplikationen ist signed fractional. Wenn eine andere Darstellung erwünscht ist, muss diese explizit angegeben werden. Dies erfolgt, in- dem nach dem Befehl in Klammern die Buchstaben S oder U bzw. I oder F angefügt werden, siehe Abschnitt 2.6.6 des Handbuches. Hierbei bezeichnen: • S signed • U unsigned • I integer 17
  • 17. • F fractional Beide Operanden müssen entweder vom Typ integer oder fractional sein. Signed und unsi- gned sind mischbar. Beispiel: 1. Die Zahlen in R1 und R2 sind beide vom Format signed fractional R0 = R1 · R2; oder R0 = R1 · R2 (SSF); 2. Die Zahlen in R1 und R2 sind beide vom Format unsigned integer R0 = R1 · R2 (UUI); 3. Die Zahl in R1 ist unsigned fractional und die in R2 signed fractional. Das Ergebnis soll abgerundet werden R0 = MRF - R1 · R2(USFR); Eine Gleitkomma multiply/accumulate-Operation wird durch parallele Nutzung der ALU und des Multiplizierers durchgeführt. Dabei ist jedoch zu beachten, dass für die Addition in dem Beispiel der Wert in F8 zur Berechnung gewählt wird, der einen Takt zuvor bestimmt wurde. Weiterhin sind die zu verwendenden Register einer Begrenzung unterworfen (siehe hierzu auch Handbuch S. B-95). Beispiel: 1. Berechne C := A · B + C Die Werte von A, B und C liegen in F1, F2 bzw. F12. F8 = F1 · F2, F12 = F8 + F12; Genau wie die ALU hat auch der Multiplizierer eine Wirkung auf das Statusregister. Bei- spielsweise kann mit dem MN-Bit im ASTAT-Register kontrolliert werden, ob das Ergebnis einer Multiplikation negativ ist. Shifter Der Shifter stellt die dritte Recheneinheit dar. Mit dem Shifter kann z. B. der Inhalt eines Re- gisters verschoben werden. Der Shifter arbeitet grundsätzlich nur in Festkommaarithmetik, d.h. nur mit den oberen 32 Bits eines Registers. Die letzten 8 der 40 Bits im Resultatre- gister werden immer zu Null gesetzt. Der Shifter hat auch eine Wirkung auf das ASTAT Register. Zusätzlich zu den normalen Shift-Funktionen bietet der Shifter die Möglichkeit zur Manipulation und zum Test einzelner Bits. Der Befehl zur Verschiebung des Inhaltes eines Registers heißt LSHIFT (Logic shift). Die Wirkung wird durch das folgende Beispiel illustriert. 1.2.4 Das Programm-Steuerwerk Das Programm-Steuerwerk (Program Sequencer), siehe Abbildung 1.3, steuert den Ablauf des Programms. Dieser ist meistens linear (sequentiell). Abweichungen von diesem linearen Fluss werden durch die fünf Programmstrukturen loop, jump, subroutine, interrupt und idle ermöglicht. Diese Strukturen sind in Abbildung 1.10 dargestellt. 18
  • 18. Abbildung 1.9: Beispiel für Funktionalität des Shifters Der Kern des Programmsteuerwerks besteht aus dem Programmzähler (Program Counter, PC). Dieser enthält am Anfang eines Zyklus’ die Adresse des durchzuführenden Befehls und wird während des Zyklus’ hochgezählt. Ein Sprung im Programm geschieht, indem dem PC eine neue Adresse gegeben wird. Alle oben erwähnten Programmstrukturen beste- hen auf die ein oder andere Weise aus Programmsprüngen. Ein Sprung erfolgt im allgemei- nen zu einem in Assembler deklarierten „label“ (Sprungmarke). Die Sprungmarke besteht aus einer willkürlichen, nicht reservierten Zeichenfolge gefolgt von einem Doppelpunkt, z. B. „counter:“ oder „loop1:“. Bei Schleifen gibt die Sprungmarke den letzten Befehl der Schleife an. Kommentare können im Assemblerprogramm wie in C-Programmen zwischen „/*“ und „*/“ eingebettet werden. Sie helfen später sowohl dem Programmierer als auch anderen, die mit dem Quellencode zu tun haben, das Programm zu verstehen. Die Programmstrukturen werden im folgenden kurz erklärt: Loop Eine Schleife (loop) lässt sich sehr bequem durch den loop counter (LCNTR) implementieren. In LCNTR wird dabei zuerst die Zahl der Wiederholungen angegeben. Mit dem Befehl DO < label > UNTIL LCE (loop counter expired) wird die Schleife ausgeführt. Das notwendige Label < label > bezeichnet den letzten Befehl des zu iterierenden Loops. Beispiel: Zähle R0 von 0 bis 100 R0 = 0; LCNTR = 100, DO counter UNTIL LCE; counter: R0 = R0 + 1; /* this is the last instruction of the loop */ Jump Durch einen Sprung (jump) lässt sich eine Programmverzweigung implementieren. Der Sprung kann entweder unbedingt oder bedingt sein. Bei einem bedingten Sprung wird zu- 19
  • 19. Abbildung 1.10: Verschiedene Programmstrukturen erst eine Flagge in einem Register, das u. a. vom ASTAT-Register abhängig ist, kontrolliert. Wenn diese Flagge eins ist, erfolgt der Programmsprung, im anderen Fall nicht. Unter anderem gibt es die Flaggen EQ Result equal to zero NE Result not equal to zero LT Result less than zero LE Result less than or equal to zero AV Addition overflow MV Multiplier overflow Beispiel: Wenn R0 − R1 ≤ 0, springe nach negative R2 = R0 -R1; IF LE JUMP negative; positive: ... negative: ... Mit dem JUMP-Befehl kann auch eine Schleife implementiert werden. 20
  • 20. Beispiel: R0 = 0; R1 = 100; increase: R0 = R0 + 1; COMP (R0,R1); IF NE JUMP increase; ... Subroutine Eine Subroutine kann mit einem Unterprogramm verglichen werden, zu dem jederzeit ge- sprungen werden kann und von dem automatisch an die richtige Stelle im Hauptprogramm wieder zurückgesprungen wird, wenn das Unterprogramm zu Ende ist. Mit dem Befehl CALL wird der Sprung initiert und mit RTS (Return From Subroutine) wird die Subroutine beendet. Vor dem Sprung wird die aktuelle Programmadresse auf den Stack gelegt. Durch RTS wird sie wieder dem Programmzähler zurückgegeben. Ein CALL kann genau wie JUMP sowohl unbedingt als auch bedingt sein. Beispiel: IF MV CALL overflow; ... overflow: /* multiplier overflow*/ ... /* do something! */ RTS; Man beachte den Unterschied zwischen JUMP und CALL. Bei JUMP handelt es sich um einen einfachen Sprung zu einer anderen Stelle im Programm, wo das Programm weiter läuft. Mit CALL soll nur gesprungen werden, wenn durch RTS auch ein Sprung zurück gemacht wird. Es ist wichtig, dass alle Paare CALL-RTS zusammenpassen. Wird ein Sprung durch RTS ver- langt, ohne dass zu der Subroutine mit CALL gesprungen wurde, folgt ein Programmfehler, weil auf dem Stack die falsche (oder gar keine) Retour-Adresse vorhanden war. Interrupts Interrupts stellen eine sehr flexible und effiziente Lösung für das Handhaben von Ereignis- sen dar und müssen von jedem Assembler-Programmierer beherrscht werden. Ein Interrupt ist ein Ereignis, das einen Sprung zu einer vordefinierten Adresse auslöst. Das Ereignis kann entweder intern im Prozessor auftreten (z. B. ein ALU-Overflow) oder extern (z. B. wenn ein neuer Abtastwert vorliegt). Der ADSP-21369 hat vier externe Hardware-Interrupts, inklusi- ve eines speziellen Reset-Interrupts, und eine Vielzahl interner Interrupts, siehe Abbildung 1.11. Für die Programmsteuerung bei Interrupts gibt es die Interruptvektortabelle, vergleiche den beispielhaften Programmablauf in Abbildung 1.12. Beim Auslösen eines Interrupts wird zu der dem Interrupttyp entsprechenden Adresse ge- sprungen (Schritt 1). Im allgemeinen enthält diese Adresse den Befehl JUMP, so dass das 21
  • 21. Interrupt Vector Table ADSP-21369 Emulator (read-only, HIGH PRIORITY 0x90000 + 0x00 0 EMUI non-maskable) Reset (read-only RSTI 0x04 1 non-maskable) Illegal input condition 2 IICDI 0x08 detected Status loop or mode 0x0C 3 stack overflow; or PC SOVFI stack full Timer=0 (high 0x10 4 TMZHI priority option) SPERRI 0x14 SP error interrupt 5 Hardware breakpoint BKPI 0x18 6 interrupt 0x1C 7 Reserved 0x20 8 IRQ2I IRQ2I asserted 0x24 9 IRQ1I IRQ1I asserted 0x28 10 IRQ0I IRQ0I asserted ... ... ... ... User Software 0x98 28 SFT0I Interrupt 0 User Software 0x9C 29 SFT1I Interrupt 1 User Software 0xA0 30 SFT2I Interrupt 2 User Software 0xA4 31 SFT3I LOW PRIORITY Interrupt 3 Abbildung 1.11: Inhalt der Interrupt-Vector-Tabelle Programm mit einer Interrupt-Subroutine fortfahren kann (Schritt 2). Am Ende der Interrupt- Subroutine wird mit RTI (Return From Interrupt) zu der Adresse im Programm zurückge- sprungen, die der Programmzähler enthielt, als der Interrupt ausgelöst wurde (Schritt 3). Bei einem externen Interrupt wird zuerst der Inhalt des ASTAT-Registers und des MODE1- Registers sowie die Adresse des Programmzählers (PC) vor dem Sprung auf den Stack ge- legt. Durch RTI werden diese Registerwerte vom Stack zurückgenommen. Für externe Inter- rupts und für den Timer-Interrupt ist eine Verschachtelungstiefe (nesting) von vier möglich. Folgendes Beispiel erläutert die Verwendung von Timer-Interrupts: Beispiel: 1. Es soll ein Timer-Interrupt jede 1ms ausgelöst werden. 1ms entspricht 6000010 = EA6016 Zyklen bei 60 MHz, vergleiche Abschnitt 11 des Handbuches (zu beachten: Der Prozessor verfügt über zwei völlig gleichwertige Timer-Sektionen 0 und 1) /* timer interrupt address (high Prio timer IRQ)*/ .SEGMENT/PM pm_tmzhi; JUMP timer_interrupt; .ENDSEG; ... 22
  • 22. Abbildung 1.12: Programmablauf beim Auslösen des Interrupts IRQ1 /* global interrupt disable*/ BIT CLR MODE1 IRPTEN; /* Timer disable and setup first*/ BIT CLR MODE2 TIMEN0; /* stop timer */ BIT SET MODE2 PWMOUT0; /* set PWMOUT modus */ TPERIOD0 = 0xEA5F; /* 60000 - 1 */ /* timer interrupt enable*/ BIT SET IMASK TMZHI; /* start timer (set counter to 0)*/ BIT SET MODE2 TIMEN0; /* global interrupt enable*/ BIT SET MODE1 IRPTEN; ... timer_interrupt: ... /* Process timer-interrupt service*/ RTI; Beim Start oder Reset eines Programms startet der Prozessor immer bei der Adresse des Reset-Interrupts. Diese ist für den ADSP-21369 gleich 0x90005. Dementsprechend muss an dieser Speicherstelle ein Sprung zum Programmanfang vorhanden sein. Dies kann durch den folgenden Programmcode erreicht werden. 23
  • 23. Beispiel: /* reset interrupt address */ .SEGMENT/PM pm_rti; JUMP prog_start; .ENDSEG; ... /* the program begins here */ prog_start: ... Idle Mit dem Befehl IDLE wird der Prozessor angehalten bis ein externer Interrupt oder ein Timer-Interrupt auftritt. Im Gegensatz zu einer endlosen Warteschleife, die mit dem Be- fehl JUMP implementiert werden kann, wird mit IDLE der Prozessor in einen „low-power“- Zustand versetzt. Nach dem Rücksprung aus der Interrupt-Subroutine wird die Programma- barbeitung mit dem Befehl fortgesetzt, der IDLE folgt. 1.2.5 Datenadressierung Für die Berechnung von Adressen im Programm- und Datenspeicher stehen zwei Daten- adressrechner (data address generators, DAG) zur Verfügung. Mit diesen wird eine indirekte Adressierung ermöglicht, d.h. anstatt die tatsächliche Speicherstelle im Programm anzuge- ben, wird sie durch den DAG berechnet. In jedem der zwei DAG gibt es acht Adressregister, die I-Register oder Index-Register ge- nannt werden. Der DAG1, der Adressen für den Datenspeicher (DM) (siehe Abschnitt 4.2.6) berechnet, enthält die Register I0 bis I7, während der DAG2, der Adressen für den Pro- grammspeicher (PM) berechnet, über die Register I8 bis I15 verfügt. Die Zuordnung der Adressierungs-Register zu Programm-/Datenspeicher ist durch die Tat- sache bedingt, dass der Programm-Speicher Adressbus nur 24 Bit breit ist. Somit sind auch alle Register der zweiten Adressierungslogik nur 24 Bit breit. Mit den zugehörigen Modify-Registern (M0-M7 für DAG1 bzw. M8-M15 für DAG2) kann eine Adresse vor oder nach dem Speicherzugriff hoch- oder runtergezählt (inkrementiert bzw. dekrementiert) werden. Hierdurch wird u.a. eine laufende Abspeicherung oder ein laufen- des Auslesen von Daten ermöglicht, ohne dass dem Index-Register manuell ein neuer Wert gegeben werden muss. Die Adressrechner werden mit den Befehlen DM bzw. PM angespro- chen. Diese Befehle haben zwei Argumente: ein I-Register bzw. ein M-Register oder einen konstanten Modify-Wert. Bei post-modify Adressierung erfolgt erst der Speicherzugriff und dann die Berechnung des neuen Inhalts vom I-Register. Die Syntax lautet dann DM (Ia, Mb) oder PM (Ic, Md), wobei a und b Zahlen zwischen 0 und 7 und c bzw. d Zahlen zwi- schen 8 und 15 sind. Bei pre-modify wird die neue Adresse berechnet bevor der Zugriff erfolgt. Hierfür wird die Syntax DM(Ma, Ib) oder PM(Mc, Id) verwendet. 24
  • 24. Beispiel: 1. Lade in R6 den Inhalt der Speicherstelle 0x0000C000 des Datenspei- chers. R6 = DM(0x0000C000); oder I0 = 0x0000C000; R6 = DM (I0, 0); 2. Lade in R6 den Inhalt der DM-Speicherstelle, die in I5 vorgegeben ist, und zähle danach die Adresse in I5 um 2 hoch R6 = DM (I5, 2); 3. Addiere die Adresse in I8 mit dem Wert in M10, und speichere danach den Inhalt von R0 an der neu berechneten PM-Adresse (M10 kann negativ sein) PM (M10, I8) = R0; Beispiel: 1. Berechne die Summe N der Elemente in den Speicherstellen DM(I0) bis DM(I0+N-1), für N=10. #define N 10 /* number of elements */ F0=DM (I0,1); F1=DM(I0,1); LCNTR = N-1, DO endloop UNTIL LCE; /* result in F0 */ endloop: F0 = F0 +F1, F1 = DM (I0, 1); Ablauf der Schleife: in DM(I0) bis DM(I0+N-1) sind die Zahlen a0 ... aN−1 vorhanden. Iteration LCNTR F0 F1 Initialisierung N-1 a0 a1 i=1 N-2 a0 +a1 a2 ... N−2 i = N-2 1 m=0 ak aN−1 N−1 i = N-1 0 m=0 ak undefiniert Zyklische Daten-Puffer Zyklische Daten-Puffer werden für effiziente Implementierungen von Filtern, Verzögerungs- gliedern und anderen, in der digitalen Signalverarbeitung häufig vorkommenden Struktu- ren eingesetzt. Die Implementierung zyklischer Daten-Puffer, sog. Ringspeicher (circular buffer), wird durch Modulo-Adressierung erheblich erleichtert. Hierfür werden die base- Register (B) und die length-Register (L) verwendet. Ein B-Register enthält dabei die Basi- sadresse eines Ringspeichers und L die Anzahl der Elemente (die Länge). Das Register L0 und das Register M0 gehören immer zusammen, usw.. 25
  • 25. Abbildung 1.13: Beispiel eines zyklischen Puffers Nach Initialisierung der B und L-Register wird zuerst die Basisadresse dem entsprechenden I-Register automatisch übergeben. Bei einer post-modify Modifizierung des I-Registers (ei- ne pre-modify Modifizierung ist bei zyklischen Puffern nicht erlaubt) wird kontrolliert, ob die neue Adresse innerhalb des Bereichs zwischen B und B+L-1 liegt. Wenn dies der Fall ist, wird die neue Adresse behalten. Wenn sie zu groß ist, wird die Länge L subtrahiert, und dementsprechend wird L addiert, wenn sie kleiner als B ist. Dadurch ergibt sich immer die neue Adresse durch den Zusammenhang Ia := Ba + (Ia + Mb − Ba) mod La (1.7) a und b können verschiedene Zahlen aus den Bereichen 0-7 oder 8-15 sein (DM bzw PM). Es ist notwendig, dass |Mb| < La. Wie die Register der ALU stehen auch die Register der Adressierungslogik doppelt zur Verfügung, um einen schnellen Kontext Wechsel zu ermöglichen. Beispiel: 1. Es soll ein Verzögerungsglied implementiert werden. Die Verzögerung beträgt 20 Abtastwerte. Der Eingangswert ist beim Aufruf der Subrou- tine delay_20 (wird mit call aufgerufen) in DM(I6) vorhanden und der (verzögerte) Ausgangswert soll in DM(I7) geschrieben werden. /* base address*/ B0 = 0x0C200; /* length 2010 = 1416 */ L0 = 0x14; ... /* read oldest data from buffer */ delay_20: F0 = DM(I0,0): 26
  • 26. /* write output data */ DM(I7, 0) = F0; /* read input data */ F0 = DM (I6, 0); /* put data in circular buffer, * address is increased by one*/ DM(I0, 1) = F0; RTS; 1.2.6 Speicher Der Programm- und Datenspeicher Der im Praktikum eingesetzte Prozessor ADSP-21369 hat 2 MB on-chip und 4 Mega Wort externen Speicher, der grob in zwei Kategorien aufgeteilt wird: der Programmspeicher (PM - Program Memory) und der Datenspeicher (DM - Data Memory). Die Wortbreite 32 Bit wird für Fest- und Gleitkommadaten verwendet. Es können auch 48-Bit Wörter definiert werden, die entweder Befehle oder 40-Bit Gleitkommadaten enthalten. Schließlich steht auch ein 16-Bit Format für Festkommadaten zur Verfügung. Die Aufteilung des gesamten Speichers in Segmente kann weiterhin für jede Anwendung spezifisch bestimmt werden. Hierfür wird ein sogenanntes Link-Description-File (LDF) angegeben, in dem Symbolen (Namen) physikalische Adressen zugeordnet werden. • Im Adressraum sind die internen Speicherbereiche in Blöcke aufgeteilt, weiterhin gibt es jeweils einen Normal-Word- und einen Short-Word-Bereich. Die vorgegebe- nen Adress-Grenzen müssen dementsprechend auch im Link-Description-File einge- halten werden, für eine genaue Zuordnung der Blöcke zu den Adressen sei auf das Handbuch verwiesen. • Der externe Speicher ist ebenfalls im Adressraum des ADSP 21369 vorgesehen, der schliesslich verwendete Adressbereich ist schaltungstechnisch bedingt von Adresse 0x00200000 bis 0x08FF0000 anzusprechen, näheres hierzu kann der Beschreibung der EZKIT-Hardware entnommen werden. Auf dieselbe Art und Weise sind auch die Steuerungs- und Datenregister der anderen Peripherien (z. B. UART ADM3202) Teil des Adressraums (siehe wiederum Manual zu EZKIT). Im PM können sowohl Programmbefehle als auch Daten gespeichert werden. Im Datenspei- cher (DM) können ausschließlich Daten gespeichert werden. In sowohl PM als auch DM kön- nen auch Wörter anderer Breiten verwendet werden. In diesem Fall ändert sich die Adres- sierung, siehe auch hierzu Kapitel „External Memory Interface“ im Handbuch. Instruktionen müssen über den 32 Bit breiten Programmspeicher Adressbus angefordert werden, weshalb diese sich nur in den entsprechenden Teilen des Speichers befinden kön- nen. Die PM/DM-Datenbusse Über die PM und DM Datenbusse (PMD bzw. DMD ) werden die Befehle und Daten zwischen dem Speicher und den verschiedenen Einheiten des Prozessors verschoben. Wie im PM so- 27
  • 27. wohl Befehle als auch Daten gespeichert werden können, so kann der PM Datenbus Befehle zum Programmrechenwerk oder auch Daten zu z. B. den Registern transportieren, jedoch nicht gleichzeitig. Der parallele Datenbus ermöglicht zwei gleichzeitige Speicherzugriffe. So kann im selben Zyklus sowohl ein neuer Befehl vom PM als auch ein Wert vom DM gelesen werden. Hierbei wird die Adresse im PM vom Programmsteuerwerk über den PM Adressbus (PMA) und die Adresse im DM über den DM Adressbus (DMA) vermittelt. Alternativ können, wenn der auszuführende Befehl schon im Cache-Speicher vorhanden ist, beide Datenbusse für den Transport von Daten verwendet werden. Vom PM und DM kann dann jeweils ein Wert einem Register übergeben werden - alles innerhalb eines Zyklus’. Dieses Verfahren wird dual data access genannt. Um dieses zu ermöglichen, empfiehlt es sich immer, die zu verarbeitenden Daten zu trennen (z. B. Filterkoeffizienten im Programm- speicher und Abtastwerte im Datenspeicher). Weiter muss der Befehl in der Form compute, DM read or write, PM read or write; sein, zum Beispiel R0=R0+R1, DM(I1, M1)=R0, R1=PM(I8, M8); Wenn der Befehl nicht im Cache-Speicher liegt, werden zusätzliche Zyklen benötigt. 1.3 Entwicklungsumgebung: Visual DSP++ 1.3.1 Einführung Im Laufe der letzten Jahre wurde die Hardware im Bereich Prozessoren immer weiter ent- wickelt. Die heutigen Architekturen sind im allgemeinen sehr leistungsstark, und die Wahl eines DSPs für einen Algorithmus wird somit auch von Faktoren jenseits der Performance mitbestimmt. Zu diesen anderen Faktoren zählt insbesondere die zur Verfügung stehende Software. Die „Time to market“, also der Zeitrahmen, dessen es bedarf, ein Produkt auf den Markt zu bringen, kann durch guten Software-Support drastisch verkürzt werden. C- Compiler gehören hierbei zum Standard. Analog Devices liefert zu den Sharc-DSPs die Software Visual DSP++. In Anlehnung an die Entwicklungsumgebung Visual Studio unter Windows können Algorithmen hiermit schneller implementiert werden. Im Folgenden soll eine kurze Einführung in die Umgebung Visual DSP++ gegeben werden: Das Software-Entwicklungspaket von Analog Devices ist eine IDE (Integrated Develop- ment Environment). Dazu gehören Tools zur Erstellung der Software (z. B. Editor) sowie welche zur Verifikation des erstellten Software (z. B. Debugger). Da die Release von Visual DSP++, die im Praktikum verwendet wird, regelmässig auf den neusten Stand gebracht wird, können sich zu den im folgenden präsentierten Bildern unter Umständen leichte Abweichungen ergeben. 28
  • 28. Abbildung 1.14: Aufruf der Entwicklungsumgebung Visual DSP++ 1.3.2 Implementierung des Source-Codes Für die Entwicklung eines Algorithmus’ unter Visual DSP++ sowie unter allen Visual- Umgebungen ist der Begriff Projekt von großer Bedeutung: Ein Projekt umfasst die Gesamtheit aller zu der Implementation einer Anwendung gehö- rigen Module. Ein Modul kann zum Beispiel eine Text-Datei sein, in der Code in einer Programmiersprache gespeichert ist, oder eine vorkompilierte Bibliothek, auf deren Metho- den zugegriffen wird. Die Module eines Projektes werden gegebenenfalls kompiliert und gelinkt. Sie bilden somit die Basis für einen ausführbaren Algorithmus. Im einfachsten Fall besteht ein Projekt aus einer Datei, die den gesamten Source-Code enthält. Starten der Entwicklungsumgebung Die Entwicklungsumgebung Visual DSP++ wird wie unter Windows üblich aus dem Start- Menü gestartet (siehe Abbildung 1.14). Die Bedienung gestaltet sich wie in den meisten Fällen sehr intuitiv. Sollte in einer vorher- gehenden Sitzung ein Projekt bearbeitet worden sein, so erscheint dieses Projekt direkt zu Beginn. Es können Unterfenster für das Projekt selbst (A), aber auch für Quellcode (B) bzw. Prozessor-Zustände (z. B. Disassembly(C)) angezeigt werden (siehe Abbildung 1.15). Im Projekt-Fenster wird angezeigt, welche Dateien alle Teil des Projekts sind. Sollte hier noch kein Projekt angezeigt werden, so muss erst eins angelegt werden bzw. ein vorhande- nes eingeladen werden. 29
  • 29. A C B Abbildung 1.15: Fenster nach Programmstart Menüpunkte In Abbildung 1.15 ist zu erkennen, welche Menüpunkte es bei Visual DSP++ gibt. Die wichtigen Unterpunkte werden im folgenden kurz aufgelistet: • Menüpunkt File: In diesem Menüpunkt können Dateien geladen oder gespeichert werden. Dabei wer- den Projekte und Textdateien im gleichen Dialog ausgewählt. Desweiteren kann auf den DSP ein ganzes Programm bzw. in den Debugger die Symboltabelle eines Pro- gramms geladen werden (Unterpunkte Load ...). Für einen beschleunigten Zugriff stehen Links zu kürzlich geöffneten Projekten usw. bereit (Unterpunkte Recent ...). • Menüpunkt Edit: In diesem Menüpunkt kann Text editiert werden. Dabei stehen die üblichen Opera- tionen wie Copy/Paste zur Verfügung. • Menüpunkt Session: In diesem Menüpunkt kann die aktuelle Session gewählt werden. Im Falle des Prak- tikums dient dies insbesondere der Wahl zwischen der Emulation mithilfe des JTAG- Interfaces (V3+Projektphase) und der Simulation (V1+V2). Andere Sessions werden im Rahmen dieses Praktikums nicht verwendet. • Menüpunkt View: In diesem Menüpunkt können Fenster angezeigt bzw. nicht angezeigt werden. Ins- besondere kann wie in Abbildung 1.19 angedeutet (Plot) auch ein Speicherbereich grafisch ausgegeben werden. 30
  • 30. Abbildung 1.16: File-Dialog • Menüpunkt Projekt: In diesem Menüpunkt können Projekt spezifische Operationen vorgenommen wer- den. Abbildung 1.20 veranschaulicht die Möglichkeiten, die wichtigsten Funktionen im einzelnen: – Add to Project: Hiermit können einem Projekt Module hinzugefügt werden. – Build File: Hiermit können einzelne Module kompiliert werden. – Build Project: Hiermit werden alle Module eines Projekts kompiliert (sofern notwendig) und zusammengelinkt. – Rebuild all: Hiermit werden sämtliche Projekte wie unter Menüpunkt Build Project bearbei- tet, die momentan geöffnet sind. – Project Options: Compile- und Link-Options können hier spezifiziert werden. • Menüpunkt Register: Dieser Menüpunkt dient dem Debuggen eines gerade auf dem DSP ablaufenden Pro- gramms. Es können hier Register des DSPs zur Anzeige ausgewählt werden. Für eine Benutzung im Rahmen des Praktikums ist insbesondere die Anzeige der inaktiven Register wichtig (Inactive Registers). • Menüpunkt Memory: In diesem Menüpunkt können Speicherbereiche angezeigt werden. Die Daten an den 31
  • 31. Abbildung 1.17: Edit-Dialog entsprechenden Speicherstellen können in verschiedenem Format dargestellt werden. In den meisten Fällen ist eine Darstellung im Format Two Column sinnvoll. Mit dem Befehl Dump können ganze Speicherbereiche auch direkt in einer Datei gespeichert werden. Dies ist nützlich, um Rechenergebnisse zum Beispiel mit Matlab zu verifi- zieren. • Menüpunkt Debug: Im Menüpunkt Debug kann der Debugger gestartet und kontrolliert werden. • Menüpunkt Settings: In diesem Menüpunkt können Einstellungen vorgenommen werden. Insbesondere können hier Breakpoints aufgelistet und Interrupts simuliert werden (siehe V1). Vorgehensweise bei der Erzeugung von Objekt-Codes (DSP Executable) Im Laufe der Versuche dieses Praktikums und in der anschließenden Projektphase soll das Rahmenprogramm erweitert und auf die Applikation angepasst werden. Hierzu sollen dem Projekt Module hinzugefügt werden. Nachdem dies geschehen ist, werden alle Module er- neut zusammengelinkt. Dabei werden eventuell aufgetretene Fehler im Ausgabefenster an- gezeigt. Sofern die Anwendung komplett erzeugt wurde, wird das auszuführende Programm direkt in den Programmspeicher des DSP geladen. Der Prozessor hält direkt an und erwartet weitere Instruktionen. Ausführen des Programms Zur weiteren Ausführung des geladenen Sourcecodes wird F5 gedrückt. Alle Anzeige- Fenster werden zu diesem Zeitpunkt deaktiviert. Sofern ein zuvor eingestellter Breakpoint 32
  • 32. Abbildung 1.18: Session-Dialog erreicht wird, hält die Ausfühung an, und alle Ausgabefenster werden aktualisiert. Mit SHIFT-F5 kann der Prozessor auch zu jedem anderen Zeitpunkt angehalten werden. Setzen von Breakpoints Mit F9 kann an der Stelle der aktuellen Eingabeposition ein Breakpoint gesetzt werden. Dies ist jedoch nur möglich, wenn der Prozessor gerade nicht im laufenden Zustand ist. Ausführung Instruktion für Instruktion Wenn der Prozessor angehalten wurde, sei es aufgrund von Breakpoints oder manuell, kann mit F11 der Programmcode Schritt für Schritt abgearbeitet werden (sog. durchsteppen). Zu bedenken ist jedoch, dass auch im angehaltenen Modus Interrupts ausgelöst werden können. Aus diesem Grunde springt der Prozessor zumeist beim Durchgehen Instruktion für Instruktion in die nächste Interrupt Service Routine höherer Ordnung. Vorgehen beim Debuggen Ein DSP-Object-Code wird wie beschrieben eingeladen. Daraufhin kann der Code gedebug- ged werden. Zumeist wird nur ein Teilaspekt untersucht, der in einer Unterfunktion imple- mentiert wurde. Um den zugehörigen Source-Code anzuzeigen, muss der Program-Counter (PC) auf einer Stelle stehen, die zu der zu untersuchenden Funktion gehört. Nach Programmstart muss hierfür der Disassembly-Output nach einem Symbol in der Funk- tion ( z. B. Funktionsname ) durchsucht werden. Dies geschieht durch Betätigung der rech- ten Maustaste sowie Aufruf der Goto-Funktionalität. Die Aktivierung von Browse führt zu 33
  • 33. Abbildung 1.19: View-Dialog einer Auflistung aller existierenden Symbole. Nach Auffinden des Symbols wird ein Break- point gesetzt. Nun wird der Programmcode bis zum Breakpoint ausgeführt (Run, F5). 1.4 Versuchsdurchführung 1.4.1 Einführung Die nun folgenden Programmbeispiele sollen schrittweise in die Programmierung des ADSP- 21369 einführen. Beachten Sie bitte, dass die ersten zwei Programme im Simulator-Modus ausgeführt werden und erst das dritte Beispiel auf dem DSP emuliert wird. Ziel der hier durchgeführten ersten beiden Versuche ist das Erlernen und Verstehen von Prinzipien Hard- ware-naher Programmierung and der Funktionsweise des DSPs auf Assembler-Programm- Ebene. Der dritte Versuch dient der Einarbeitung in die vorgegebene Software RTProcDSP. Da dieses Programm in C/C++ programmiert wurde, geschieht von diesem Zeitpunkt an auch die Programmierung der Algorithmen in C/C++. Es sei jedoch darauf verwiesen, das es im Verlauf des Projekts notwendig sein kann, Fragmente der Programme in Assembler zu realisieren, um die Ausführungsgeschwindigkeit des DSPs zu erhöhen. Für die Spezifi- kation der Schnittstelle zwischen C/C++ und Assembler sei auf die Anleitung in der DSP Literatur „C/C++ Compiler and Library Manual for Sharc Processors“ verwiesen. • Im Programm 1 werden Daten interruptgesteuert ein- und ausgelesen. Die von ei- ner Datei in einen Ringspeicher eingelesenen Werte können in einer Interruptroutine modifiziert werden und anschließend in einen Speicherbereich ausgegeben werden. Hierbei behandeln wir auch den Aufbau von Ringspeichern mit Hilfe der Modulo- Adressierung. 34
  • 34. Abbildung 1.20: Project-Dialog • Das Programm 2 zeigt die Anwendung von Befehlen für die parallele Verarbeitung von Multiplikations- und Additionsbefehlen anhand eines Tiefpass-Filters. • Zum Schluss wird das Programm RTProcDSP vorgestellt. Da es im folgenden die Grundlage zur Umsetzung der Projekte bildet, werden alle funktionalen Merkmale an kleinen Übungsbeispielen verdeutlicht. 1.4.2 Programm 1: Interruptgesteuerte Ein-/Ausgabe Der Sinn dieses Programms besteht darin, einen schnellen Einstieg in die Assemblerpro- grammierung zu geben, insbesondere sollen zyklische Datenspeicher und die Programm- steuerung durch Interrupts dargestellt werden. Unter einem Interrupt (engl. für Unterbrechung) versteht man eine von dem Prozessor ge- steuerte Unterbrechung des sequentiellen Programmablaufs. Stellen wir uns den sequenti- ellen Programmablauf so vor, dass ein Ablaufzeiger (oder auch Program Counter) nachein- ander die Speicherstellen anzeigt, die das Programm abarbeiten soll, dann ist ein Interrupt eine Unterbrechung, in der der Zeiger auf eine vorher vereinbarte Speicherstelle „umge- bogen“ wird. An dieser Stelle kann dann auch ein Verweis auf ein Unterprogramm stehen oder direkt ein kurzes Unterprogramm vorhanden sein, das bearbeitet wird. Nach dem Ende dieses Unterprogrammes wird der Programmcode wieder an alter Stelle aufgenommen und weiter sequentiell bearbeitet. Starten Sie das VisualDSP++ Environment und wählen Sie zunächst eine Session zur Pro- zessor-Simulation aus (sollte so eine Session auf Ihrem Rechner noch nicht vorhanden sein, kontaktieren Sie den Betreuer). Laden Sie anschliessend das Projekt V1. Um das Programm auf dem DSP auszuführen, müssen Sie zunächst alle Dateien kompilieren und linken (Pro- 35
  • 35. Abbildung 1.21: Register-Dialog ject → Build Project oder F7) und dann die Programmausführung beginnen (Debug → Run oder F5). Die Ausführung des Programms bleibt nun zu Beginn der _main-Routine an ei- nem Breakpoint stehen. Von hier aus können alle Schritte des Programms durch F11 einzeln ausgeführt werden. Programmcode von Projekt 1 Das vorliegende Programmbeispiel V1.asm aus dem Projekt V1 liest interruptgesteuert einen Wert aus dem mit input angegebenen Speicherbereich in ein Register. Anschliessend wird dieser Wert an den mit output bezeichneten Speicherplatz weitergegeben. Es ist als ein Pro- grammierbeispiel anzusehen und soll später gemäß der Aufgabenstellung modifiziert wer- den. Es ist sinnvoll, den Programmcode parallel zu dieser Beschreibung zu lesen. Der physikalische Speicherplatz wird durch ein sogenanntes Link-Description-File (LDF) in logische Segmente aufgeteilt. Durch den Linker werden die Symbole (z. B. Namen von Variablen) im Programmcode mit den physikalischen Speicheradressen verbunden, wobei das LDF dafür die Regeln spezifiziert (in „Linker & Utilities Manual for ADSP-21xxx Family DSPs“ wird dieser Vorgang illustriert). Den verschiedenen Segmenten werden wei- terhin unterschiedliche Bedeutungen als Program- oder Datamemory zugewiesen. Zur Ver- anschaulichung hier nun der Auszug aus dem verwendeten Link-Description-File V1.ldf: 36
  • 36. Abbildung 1.22: Debug-Dialog ARCHITECTURE(ADSP-21369) MEMORY { seg_rth { TYPE(PM RAM) START(0x00090000) END(0x000900ff) WIDTH(48) } seg_pmco { TYPE(PM RAM) START(0x000902D0) END(0x000903FF) WIDTH(48) } seg_pm64 { TYPE(PM RAM) START(0x0004c6c0) END(0x0004dfff) WIDTH(64) } seg_dm64 { TYPE(DM RAM) START(0x0005d800) END(0x0005d81f) WIDTH(64) } seg_pm40 { TYPE(PM RAM) START(0x00090400) END(0x000904ff) WIDTH(48) } seg_dm40 { TYPE(DM RAM) START(0x000b0000) END(0x000b01ff) WIDTH(48) } seg_pm32 { TYPE(PM RAM) START(0x00098c00) END(0x00098cff) WIDTH(32)} seg_dm32 { TYPE(DM RAM) START(0x000b8400) END(0x000bafff) WIDTH(32) } } Das LDF wird bearbeitet, indem mit der rechten Maustaste auf die Datei geklickt wird, um dort dann die Option Open with Source Window zu wählen. Die symbolischen Namen der Segmente im LDF, zum Beispiel seg_dm32, werden im Quellcode von V1.asm wiederver- wendet, um dort Variablen einem bestimmten Speicherbereich zuzuordnen. Eine besondere Rolle spielt das Segment seg_rth, in dem der Programmcode des Interrupt- Vector-Tables abgelegt wird. Zugehörig findet man das Assembler-Programm in der Datei 21369_IVT.asm. Im folgenden soll nicht weiter auf das Link-Description-File eingegangen werden, da dieses in der Regel unverändert übernommen werden kann. Die beiden Assembler Programmcode-Dateien 21369_IVT.asm und V1.asm werden nun einzeln erläutert. In der Datei 21369_IVT.asm werden die Instruktionen im Interrupt-Vector- Table spezifiziert. Der Programmcode ist eine Eins-zu-Eins-Abbildung der Tabelle in Ab- bildung 1.11. Insbesondere wird hier das auszuführende Programm angesprungen, sobald ein Reset-Interrupt ausgelöst wurde (Zeile 15). Um eine Interrupt gesteuerte Eingabe zu ermöglichen, ist weiterhin eine jump-Instruktion an der Position von IRQ0, Zeile 69, einge- 37
  • 37. Abbildung 1.23: Settings-Dialog fügt. Diese dient dem Aufruf der Funktion _convolution bei jedem Eintritt der Interrupt- Ereignisses. In der Datei V1.asm wird der tatsächliche Programmcode der _main- Funktion sowie der Interrupt-Service-Routine _convolution aufgelistet. Bei Programmausführung dient die _main-Funktion der Initialisierung. In dieser Funktion werden die Adress-Generatoren so eingestellt, dass anschliessend die Einlese-Operation erfolgreich verläuft. Am Ende der _main-Routine versetzt sich der Prozessor in den idle-Modus, um Energy zu sparen (Zeile 53). Aufgaben • Öffnen Sie die Datei V1.ldf im Source Window. Lokalisieren Sie die Speicher- Segmente und identifizieren sie die verwendeten Segmente in den beiden Programm- codedateien. An welcher Adresse liegt die Variable output? • Starten Sie die Programmausführung. Diese hält am ersten Breakpoint sofort wieder an. Das Programm und alle Variablen wurden zu diesem Zeitpunkt bereits in den Speicher geladen. Öffnen Sie die folgenden Fenster zur Betrachtung – des Disassembly-Outputs und des zugehörigen Programmcodes. – des relevanten Adress-Generators (DAG). – des Datenspeichers – der Interrupt-Register. Plotten Sie das Signal, das im Speicher zur Variable input gespeichert ist. Wählen Sie dafür die Option View → Debug Windows → Plot → New. Wählen sie den dar- zustellenden Speicherbereich mithilfe der Browse-Funktionalität aus. Beachten Sie, 38
  • 38. dass sie das Zahlenformat (Float) und die Länge richtig einstellen. Verfizieren Sie die Richtigkeit der Darstellung anhand der Zahlenwerte, die sie durch Darstellung des Speichers (Memory → Two Column) ablesen können. • Führen Sie das Programm nun Schritt für Schritt bis zum Erreichen der IDLE-Instruktion aus (durchsteppen), indem Sie die Taste F11 bedienen. Beobachten Sie die Initia- lisierung der Interruptregister und der für die Verwaltung des zirkulären Speichers notwendigen Register. Was bedeuten die Kürzel A,D,P,F und der gelbe Pfeil? • Nach der Initialisierung kann das Programm mit F5 (Run) ausgeführt werden. Da wir uns im Simulations-Modus befinden kann ein auftretender externer Interrupt nur si- muliert werden. Dies geschieht durch Auswahl von Settings → Interrupts . Wählen Sie den Interrupt IRQ0 und eine sinnvolle Eistellung für die Interrupt-Periode, sowie die verbleibenden Einstellmöglichkeiten. Was bedeuten die einzelnen Parameter? Be- achten Sie, dass die Aktivierung des Interrupts durch Hinzufügen (ADD) geschieht. • Bevor Sie nun die Ausführung mit F5 weiterlaufen lassen, muss ein Breakpoint an der ensprechende Stelle im Interrupt Vector Table eingefügt werden. Überlegen Sie, an welcher Stelle dieses sinnvoll ist • Verändern Sie das Programm in der Interruptroutine, indem Sie den Befehl R0 = ABS R0; benutzen, um den Betrag des Eingangssignals am Ausgang zu erhalten. Erklären Sie das (unerwartete) Ergebnis. • Für die Experten: In der Vorgabe ist ein Speicher-Zugriffsfehler. Können Sie diesen identifizeren und wenn ja, wie ist er zu beheben? Programmcode 21369_IVT.asm // 21369 Interrupt Vector Table // .extern _main; .extern _convolution; .section/pm seg_rth; __EMUI: // 0x00: Emulator interrupt (highest priority, read-only, non-maskable) nop; nop; nop; nop; __RSTI: // 0x04: Reset (read-only, non-maskable) nop; // <-- (this line is not executed) jump _main; nop; nop; __IICDI: // 0x08: Illegal Input Condition Detected jump (pc,0); jump (pc,0); jump (pc,0); jump (pc,0); __SOVFI: // 0x0C: Status loop or mode stack overflow or PC stack full jump (pc,0); jump (pc,0); jump (pc,0); 39
  • 39. jump (pc,0); __TMZHI: // 0x10: Core timer interrupt (higher priority option) jump (pc,0); jump (pc,0); jump (pc,0); jump (pc,0); __SPERRI: // 0x14: jump (pc,0); jump (pc,0); jump (pc,0); jump (pc,0); __BKPI: // 0x18: Hardware breakpoint interrupt jump (pc,0); jump (pc,0); jump (pc,0); jump (pc,0); __res1I: // 0x1C: (reserved) jump (pc,0); jump (pc,0); jump (pc,0); jump (pc,0); __IRQ2I: // 0x20: IRQ2 is asserted jump (pc,0); jump (pc,0); jump (pc,0); jump (pc,0); __IRQ1I: // 0x24: IRQ1 is asserted jump (pc,0); jump (pc,0); jump (pc,0); jump (pc,0); __IRQ0I: // 0x28: IRQ0 is asserted nop; jump _convolution; rti; rti; __DAIHI: // 0x2C: DAI interrupt (higher priority option) __P0I : jump (pc,0); jump (pc,0); jump (pc,0); jump (pc,0); __SPIHI: __P1I : // 0x30: SPI transmit or receive (higher priority option) __SPII : jump (pc,0); jump (pc,0); jump (pc,0); jump (pc,0); __GPTMR0I: // 0x34: General Purpose timer 0 interrupt __P2I : 40
  • 40. jump (pc,0); jump (pc,0); jump (pc,0); jump (pc,0); __SP1I: // 0x38: SPORT 1 interrupt __P3I : jump (pc,0); jump (pc,0); jump (pc,0); jump (pc,0); __SP3I: // 0x3C: SPORT 3 interrupt __P4I : jump (pc,0); jump (pc,0); jump (pc,0); jump (pc,0); __SP5I: // 0x40: SPORT 5 interrupt __P5I : jump (pc,0); jump (pc,0); jump (pc,0); jump (pc,0); __SP0I: // 0x44: SPORT 0 interrupt __P6I : jump (pc,0); jump (pc,0); jump (pc,0); jump (pc,0); __SP2I: // 0x48: SPORT 2 interrupt __P7I : jump (pc,0); jump (pc,0); jump (pc,0); jump (pc,0); __SP4I: // 0x4C: SPORT 4 interrupt __P8I : jump (pc,0); jump (pc,0); jump (pc,0); jump (pc,0); __EP0I: // 0x50: External port0 interrupt. Thats the only label we’re using here __P9I : jump (pc,0); jump (pc,0); jump (pc,0); jump (pc,0); __GPTMR1I: // 0x54: General Purpose timer 1 interrupt __P10I : jump (pc,0); jump (pc,0); jump (pc,0); jump (pc,0); __SP7I: // 0x58: serial port 7 interrupt 41
  • 41. __P11I : jump (pc,0); jump (pc,0); jump (pc,0); jump (pc,0); __DAILI: // 0x5C: DAI interrupt (lower priority option) __P12I : jump (pc,0); jump (pc,0); jump (pc,0); jump (pc,0); __EP1I: // 0x60: External port1 interrupt __P13I : jump (pc,0); jump (pc,0); jump (pc,0); jump (pc,0); __DPII: // 0x64: DPI interrupt __P14I : jump (pc,0); jump (pc,0); jump (pc,0); jump (pc,0); __MTMI: // 0x68: Memory to Memory interface interrupt __P15I : jump (pc,0); jump (pc,0); jump (pc,0); jump (pc,0); __SP6I: // 0x6C: serial port 6 interrupt __P16I : jump (pc,0); jump (pc,0); jump (pc,0); jump (pc,0); __GPTMR2I: // 0x70: General Purpose timer 2 interrupt __P17I : jump (pc,0); jump (pc,0); jump (pc,0); jump (pc,0); __SPILI: // 0x74: SPI transmit or receive (lower priority option) __P18I : __SPIBI: jump (pc,0); jump (pc,0); jump (pc,0); jump (pc,0); __CB7I: // 0x78: Circular buffer 7 overflow exception jump (pc,0); jump (pc,0); jump (pc,0); jump (pc,0); 42
  • 42. __CB15I: // 0x7C: Circular buffer 15 overflow exception jump (pc,0); jump (pc,0); jump (pc,0); jump (pc,0); __TMZLI: // 0x80: Core timer interrupt (lower priority option) jump (pc,0); jump (pc,0); jump (pc,0); jump (pc,0); __FIXI: // 0x84: Fixed-point overflow exception jump (pc,0); jump (pc,0); jump (pc,0); jump (pc,0); __FLTOI: // 0x88: Floating-point overflow exception jump (pc,0); jump (pc,0); jump (pc,0); jump (pc,0); __FLTUI: // 0x8C: Floating-point underflow exception jump (pc,0); jump (pc,0); jump (pc,0); jump (pc,0); __FLTII: // 0x90: Floating-point invalid exception jump (pc,0); jump (pc,0); jump (pc,0); jump (pc,0); __EMULI: // 0x94: Emulator low priority interrupt jump (pc,0); jump (pc,0); jump (pc,0); jump (pc,0); __SFT0I: // 0x98: User software interrupt 0 jump (pc,0); jump (pc,0); jump (pc,0); jump (pc,0); __SFT1I: // 0x9C: User software interrupt 1 jump (pc,0); jump (pc,0); jump (pc,0); jump (pc,0); __SFT2I: // 0xA0: User software interrupt 2 jump (pc,0); jump (pc,0); jump (pc,0); jump (pc,0); __SFT3I: // 0xA4: User software interrupt 3 (lowest priority) 43
  • 43. jump (pc,0); jump (pc,0); jump (pc,0); jump (pc,0); Programmcode V1.asm /***************************************************************************** * V1.asm *****************************************************************************/ #include <def21369.h> .SECTION/PM seg_dm32; #define SAMPLES 9 /* Input */ .VAR input[SAMPLES]= -4.,-3.,-2.,-1. ,0., 1.,2.,3.,4.; /* Output */ .VAR output[SAMPLES]= 0.,0.,0.,0.,0.,0.,0.,0.,0.; .ENDSEG; .SECTION/PM seg_pmco; /* Set the scope of the ’_main’ symbol to global. This makes the symbol available for reference in object files that are linked to the current one. Use ’.EXTERN’ to refer to a global symbol from another file.*/ .GLOBAL _main; /* Declare the ’_main’ symbol. */ _main: /* Set bit called IRPTEN to enable interrupts */ BIT SET MODE1 IRPTEN; /* Set irq0i interrupt bit */ BIT SET IMASK IRQ0I; /* set value for modify-register M0 */ M0=1; /* set length of ringbuffer B0 */ L0=@input; /* name buffer B0, I0 is set at the same time */ B0=input; /* set length of ringbuffer B1 */ L1=@output; /* name buffer B1, set I1 */ B1=output; /* Switch to low power mode and expect interrupt */ end: 44
  • 44. idle; JUMP end; /* Delimit the ’_main’ symbol so the linker knows which code is associated with the symbol. */ ._main.END: .GLOBAL _convolution; _convolution: /* put the current value of buffer addressed by I0 to register F0 and increase buffer with M0 */ R0=DM(I0,M0); /* Here the modification for the input value can be placed: Calculate the absolute value (ASM insn abs) */ /* put value from register F0 to buffer B1 and increase with M0 */ DM(I1,M0)=R0; _convolution.END: RTI; .ENDSEG; 1.4.3 Programm 2: Parallele Verarbeitung von Befehlen In diesem Programm sollen die besonderen Vorzüge des DSP für eine schnelle Verarbeitung von Signalen anhand eines Tiefpass-FIR-Filters dargestellt werden. Das Programm realisiert eine Faltung: m−1 y(n) = a(k)x(n − k), (1.8) k=0 wobei a(k) die Filterkoeffizienten, x(n-k) die um k verzögerten Eingangswerte und y(n) die berechneten Ausgangswerte sind. Das FIR-Filter benutzt vordefinierte Eingangswerte, die in einem Puffer eingeladen sind, und Koeffizienten, die in einer Datei abgelegt sind. Zeitlich zurückliegende Eingangswerte werden in einem zyklischen Speicher als sogenannte States berücksichtigt. Das Programm stellt ein Filter der Länge 23 dar, das auf 200 vordefinierte Werte angewendet wird. Es wird durch einen Interrupt wiederholt aufgerufen. Das zugehörige Projekt V2 ist im Verzeichnis V2 abgelegt. Zusätzlich zu den Quellcode- Dateien werden Variablenfelder in Dateien angegeben: • Eine Datei mit Filterkoeffizienten fircoefs.dat • Eine Datei mit dem Eingabesignal rect.dat Die Filterkoeffizienten werden bei Versuchstermin 4 (s. Kap. 4.8.4) wiederverwendet. Ziel dieses Versuches ist, die Funktion des Programmes durch Debuggen zu verstehen. Da der Algorithmus (vom prinzip her) bekannt ist, soll zunächst eine Referenzimplementierung in Matlab erstellt werden, die das Verständnis des DSP Codes erleichtern soll. 45
  • 45. Aufgaben • Vorarbeit: Laden Sie die Datenfelder in den Dateien fircoefs.dat und rect.dat als FIR Filterkoeffizienten and Eingangswerte respektive in Matlab ein. Zum Einladen dient der load-Befehl. Realisieren Sie das FIR Filter als Matlab Funktion und verifizieren Sie Ihre Version mit der filter Funktion. Realisieren Sie Ihre Funktion in der Form, dass die Filterzustände als Parameter mit übergeben und wieder zurückgegeben wer- den (analog zur filter-Funktion und der DSP Version). • Öffnen Sie nun das Projekt V2. Verwenden Sie den Interrupt IRQ0 wie bei der ers- ten Aufgabe und setzen Sie einen Breakpoint an der Stelle, von wo aus jeweils die _filter-Routine angesprungen wird. • Vollziehen Sie die Ausführung des Programms nach. Versuchen Sie, die Verarbei- tung von Hand (auf Papier) auszuführen. Was bedeutet der Zusatz (dB) in Zeile 99? Welche Variable im DSP Code entsprechen den Größen h(k), x(k) und x(k − N)? Was genau passiert während der Interrupt-Service-Routine? Wozu dient die XOR- Verknüpfung in Zeile 146? Was passiert, wenn statt der Register R8, R12 und R4 andere Register verwendet werden? Plotten Sie inbuf und outbuf, wenn die Verar- beitung aller Eingangssamples beendet ist. Plotten Sie auch die Koeffizienten im Feld coefs. • Wie könnte man die FIR-Routine verkürzen, wenn eine Rechengenauigkeit von 32 bit integer ausreicht? Programmcode V2 /******************************************************** * * V2.ASM FIR filterprogram for ADSP21369 * Filename: V22.asm * * Description: * * The program shows how to effectivly perform a convolution * with the multiple instructions feature of the ADSP-21369 * * Registers affected: * * F0 F8 I0 I1 * F4 F12 I8 I2 * * Used parameters: * F0 = input sample x(n) * R1 = number of taps in the filter minus 1 * B0 = address of the delay line buffer * M0 = modify value for the delay line buffer * L0 = length of the delay line buffer * B8 = address of the coefficent buffer * M8 = modify value of the coefficent buffer * L8 = length of the coefficent buffer * ********************************************************/ #define SAMPLE 200 /*number of input samples to be filtered*/ #define TAPS 23 /*length of filter*/ 46
  • 46. #include <def21369.h> .SECTION/PM seg_pm32; /*FIR coefficients stored in file */ .VAR coefs[TAPS]=quot;fircoefs.datquot;; .ENDSEG; .SEGMENT/DM seg_dm32; /*buffer that holds the delay line*/ .VAR dline[TAPS]; /*input samples stored in file */ .VAR inbuf[SAMPLE] = quot;rect.datquot;; /*buffer that contains output coefficients*/ .VAR outbuf[SAMPLE]; .ENDSEG; .SECTION/PM seg_pmco; /* Set the scope of the ’_main’ symbol to global. This makes the symbol available for reference in object files that are linked to the current one. Use ’.EXTERN’ to refer to a global symbol from another file.*/ .GLOBAL _main; /* Declare the ’_main’ symbol. */ _main: /*enable interrupts*/ BIT SET MODE1 IRPTEN; /* enable circular buffering */ BIT SET MODE1 CBUFEN; L0=TAPS; /*delay line buffer pointer initialisation*/ B0=dline; /*set modify-register M0=1*/ M0=1; /*set modify-register M1=1*/ M1=1; L1=@inbuf; /*input buffer pointer initialisation*/ B1=inbuf; L2=@outbuf; /*output buffer pointer initialisation*/ B2=outbuf; L8=TAPS; 47
  • 47. /*coefficient buffer pointer initialisation*/ B8=coefs; /*set modify-register M8=1*/ M8=1; /*initialize delay line buffer to zero*/ CALL fir_init (DB); /* Set coefficient to second filter coeff */ MODIFY(I8,M8); R0=TAPS; /*enable interrupt IRQ0I*/ BIT SET IMASK IRQ0I; done: /*wait for interrupt */ JUMP done; fir_init: LCNTR=R0, DO zero1 UNTIL LCE; zero1: /*initialize the delay line to 0*/ DM(I0,M0)=0; R0=SAMPLE; LCNTR=R0, DO zero2 UNTIL LCE; zero2: /*initialize the output buffer to 0*/ DM(I2,M1)=0; RTS; /* Delimit the ’_main’ symbol so the linker knows which code is associated with the symbol. */ ._main.END: .GLOBAL _filter; _filter: /* Filter one input sample. */ CALL fir(DB); /* At first setup the loop counter for circular buffer */ R1=TAPS-3; /* Read in h(1) (the second filter coefficient) and x(k-1) */ R8=R8 XOR R8, F0=DM(I0,M0), F4=PM(I8,M8); /* ======> Call fir subroutine */ /*result is stored in outbuf */ DM(I2,M1)=F0; RTI; 48
  • 48. fir: /* Calculate x(k-1)*h(1) and load next values, x(k-2) and h(2) */ F12 = F0*F4, F0=DM(I0,M0), F4=PM(I8,M8); /*set loop to iterate taps-3 times*/ LCNTR=R1, DO macs UNTIL LCE; macs: /* In loop: Calculate next product and add (MAC operation) */ F12=F0*F4, F8=F8+F12, F0=DM(I0,M0), F4=PM(I8,M8); /* Loop is over, read in the input sample and the filter coefficient h(0) */ F12=F0*F4, F8=F8+F12, F0=DM(I1,M1), F4=PM(I8,M8); /* Trigger termination of function but with two instructions to follow */ RTS(DB); /* Write the input into the delay line and calculate final product */ F12=F0*F4, F8=F8+F12, DM(I0,0) = F0; ._filter.END: /* perform last add and store result in F0*/ F0=F8+F12; .ENDSEG; 1.4.4 Programm 3: Benutzung des Rahmenprogramms Im letzten Teil dieser Übung sollen Sie das Rahmenprogramm kennenlernen. Ziel der folgenden Aufgaben ist es, alle Möglichkeiten von RTProcDSP zu demonstrieren, die eine möglichst effiziente Umsetzung der Algorithmen auf den DSP ermöglichen und auch ausgeschöpft werden sollten. Desweiteren soll der Umgang mit der Programmierspra- che C/C++ für Echtzeit-Programmierung erlernt werden. Das Dokument „Rapid Prototy- ping on Embedded targets: RTProcDSP“ sollte während der Bearbeitung der folgenden Aufgaben zur Hand und vorbereitend gelesen worden sein. Zunächst werden die Einstellmöglichkeiten von RTProcDSP demonstriert. Im darauf fol- genden Teil sollen die Möglichkeiten der Kommunikation des DSPs mit dem über RS- 232 angeschlossenen PC aufgezeigt werden. Dies umfasst zu Anfang die Laufzeitkontrolle von Programmparametern und anschliessend die Matlab basierten Debug Möglichkeiten. Schliesslich geht es um die Verwendung der DSP Runtime-Library-Funktionen. Beachten Sie bitte, dass die Vorgabe zu Versuch 3 gleichzeitig auch als Template für die folgende Projektphase dient. Benutzung des DSP-Betriebssystem-Kerns: Audiowiedergabe Wechseln Sie zunächst die Session für den Emulationsmodus. Die zu wählende Session ist ADSP-21369 via HPUSB-ICE (Sollte diese Session bei Ihnen nicht vorhanden sein, kontaktieren Sie den Betreuer). Öffnen Sie nun das Projekt rtProcDSP im Unterverzeichnis V3/rtProcDSP. Kompilieren Sie das Projekt wie in den beiden Versuchen zuvor. 49
  • 49. Stellen Sie sicher, dass die Hardware korrekt verkabelt ist. Als Eingangssignal wird der Kopfhörer des MD-Players mit den Stereo Eingangsbuchsen des DSP-Boards verbunden. Geben Sie zunächst die Ausgangskanäle Channelset 1 (siehe Dokument zu RTProcDSP) aus. Aufgaben • Starten Sie das Programm mit F5. Das Eingangssignal sollte nun hörbar sein. Zu- nächst wird der Debugger verwendet, um die Funktionsweise zu demonstrieren. • Stoppen Sie die Ausführung des Programms durch Shift-F5. Entgegen der Erwartung ist weiterhin etwas zu hören. Können Sie dieses Verhalten erklären (Die Antwort finden Sie in der Dokumentation zu RTProcDSP)? • Spielen Sie mit den Audio-Einstellungen ein wenig herum. Probieren Sie verschiede- ne Abtastraten (8000, 16000, 32000 Hz) und Buffergrößen (16, 1024, 2048 Samples). Editieren Sie hierfür die Datei userDef.h. Aktivieren Sie wahlweise 2,4 oder 6 Aus- gangskanäle. • Wechseln Sie in der Ansicht zu der Datei algorithmStart.c. Diese entspricht der Ver- kapselung des Algorithmus in RTProcDSP und wird in Zukunft Ihr „Entwicklungsho- rizont“ sein. Suchen Sie die Member-Funktion, in der die Audiosamples verarbeitet werden. Wie heisst diese? Setzen Sie in dieser Funktion einen Breakpoint. Beachten Sie, dass zum Setzen eines Breakpoints das Programm angehalten werden muss. Las- sen Sie die Programmausführung weiterlaufen (F5). Die Ausführung läuft bis zu dem gesetzten Breakpoint und hält wiederum an. Versuchen Sie mit F10 zu debuggen. Was stellen Sie fest? Können Sie das beobachtete Verhalten erklären? Wieso verwenden wir jetzt F10 und vorher F11 zum Verfolgen der Programmausführung? Laustärkeregelung über die Kommunikationsschnittstelle Es soll im folgenden die Funktionalität eines Host-Programms auf dem PC mit der DSP- Software kombiniert werden. Das Host-Programm dspGui2.exe befindet sich im execute- Verzeichnis und kann durch Doppelklick aufgerufen werden. Starten Sie die Ausführung des DSP-Programms im VisualDSP Environment und wech- seln Sie zum Host-Programm. Eine Aufnahme des Kontroll-Fensters ist in Abbildung 1.24 dargestellt. Zur Verbindung muss zunächst eine COM-Schnittstelle ausgewählt werden. In dem Beispiel entspricht die physikalische RS-232-Verbindung dem Port COM6. Nach Auswahl dieses Ports erkennt man die erfolgreiche Verbindung an der Ausgabe im Kontrollfenster. Diese ist in Abbildung 1.25 dargestellt. Die Anwendung hat einen Slider, der durch die runde Markierung in Abbildung 1.25 hervor- gehoben wird. Dieser Slider kann zur Lautstärkesteuerung bewegt und schliesslich wieder losgelassen werden. In dem Moment des Loslassens wird vom PC eine generische Nach- richt an den DSP geschickt, die den aktuell eingestellten Lautstärkewert beinhaltet. Der zu- gehörige Opcode ist 1. Der einzige übertragene Parameter ist die Laustärke als Float Wert zwischen 0.0 und 1.0. 50
  • 50. Abbildung 1.24: Anwendung zur Lautstärkesteuerung Abbildung 1.25: Ausgabe nach Herstellung der Verbindungg 51
  • 51. Aufgaben • Die Member-Funktion algorithmStart::process soll so verändert werden, dass das Ausgabesignal der eingestellten Lautstärke entsprechend leiser oder lauter wird. Hierzu soll zunächst eine neue Variable level eingeführt werden, mit der jedes Au- diosample multipliziert wird. Beachten Sie, dass die neue Variable auf den Wert 1.0 vorinitialisiert wird (zum Beispiel im Konstruktor der Klasse). Konfigurieren Sie die Audioverarbeitung so, dass nur channelset 1 verwendet wird (siehe Doku zu RTProcDSP), bei einer Abtastrate von 48 kHz und einer Puffergröße von 512 Samp- les. • Realisieren Sie die Lautstärkesteuerung. Hinweis: Eine Variable, die als float-Type in einem integer-Feld vorliegt, kann mit dem Befehl varF = *((float*)&varI); umgewandelt werden, mit int varI; float varF; 52
  • 52. Kapitel 2 Grundlagen MATLAB und SIMULINK 2.1 Einleitung Ziel dieses Versuchs ist es, den grundlegenden Umgang mit der Signalverarbeitungssoftwa- re MATLAB und deren Erweiterung SIMULINK zu erlernen. MATLAB hat sich im Bereich der Signalverarbeitung als eins der populärsten Werkzeuge durchgesetzt. Der Name MATLAB kommt von MATrix-LABoratory und verweist auf die zwei Überlegungen, die bei der Entwicklung verfolgt wurden. Grundelemente in MATLAB stellen Matrizen dar, welche in verschiedenster Weise manipuliert werden können. Damit ist MATLAB zur Bearbeitung von Signalen und zur Ausführung numerischer Verfahren hervor- ragend geeignet. Der Namensteil LABoratory deutet darauf hin, dass das Haupteinsatzgebiet in der technischen und wissenschaftlichen Forschung und im rapid prototyping liegt. MATLAB beinhaltet einen gewissen Grundstock an Befehlen und Funktionen, welcher durch sogenannte Toolboxes bzw. selbst programmierte Funktionen beliebig erweitert werden kann. Diese Toolboxes werden z. B. an Universitäten entwickelt und werden teils kommerzi- ell, teils unentgeltlich zur Verfügung gestellt. Eigene Funktionen lassen sich in sogenannten M-Files in Form einer Aneinanderreihung vorhandener Funktionen und Befehle oder auch in C oder FORTRAN in Form von MEX-Files erstellen. MATLAB selbst ist dabei nicht als klassische Mathematiksoftware zu bezeichnen, da es mit dem Grundmodul nicht möglich ist, algebraische Probleme zu lösen. Diese Funktionalität wird jedoch durch die Symbolic Math Toolbox ermöglicht. SIMULINK ist eine Erweiterung von MATLAB, die speziell die Simulation eines Systems mit Hilfe einer blockdiagrammorientierten, grafischen Darstellung ermöglicht. Mit ihr las- sen sich komplexe Systeme anhand von Blockschaltbildern in einfacher Weise implemen- tieren. SIMULINK beinhaltet dazu viele verschiedene Blöcke wie z. B. Quellen, Senken, lineare, nichtlineare, zeitkontinuierliche und zeitdiskrete Funktionen. Die in SIMULINK vorhandenen Standardblöcke lassen sich sowohl durch Toolboxes als auch durch sogenann- te Blocksets erweitern, in denen spezielle Blöcke und Funktionen für bestimmte Aufgaben- gebiete enthalten sind. Für diese Toolboxes und Blocksets gilt gleiches wie bei MATLAB. Ferner lassen sich auch für SIMULINK eigene Funktionen und Blöcke erstellen. 53
  • 53. 2.2 Grundlagen der digitalen Signalverarbeitung In den beiden folgenden Abschnitten werden kurz die grundsätzlichen Aspekte der Digitali- sierung, d. h. der Abtastung und Quantisierung, erläutert. Für weiterführende Informationen sei z. B. auf [5, 3, 1] und [6] verwiesen. 2.2.1 Abtastung Um ein analoges Signal mit einem digitalen Rechner- bzw. Prozessorsystem zu verarbeiten, muss dieses Signal zunächst in geeigneter Weise digitalisiert, d. h. abgetastet und quantisiert werden. Die Abtastung liefert eine zeitdiskrete, aber wertkontinuierliche Folge. Die idea- 1 le Abtastung mit der Abtastfrequenz fa = T kann durch die Multiplikation des analogen Signals x0 (t) mit der Dirac-Impulsfolge ∞ p(t) = δ(t − kT ) (2.1) k=−∞ wie folgt beschrieben werden: ∞ 1 n x1 (t) = x0 (t) · p(t) X1 ( f ) = X0 ( f ) ∗ δ( f − ). (2.2) T |T | n=−∞ Das zeitdiskrete Signal besitzt ein periodisches Spektrum mit der Periodenlänge fa . Nach dem Abtasttheorem gilt, dass ein Signal x0 (t), dessen Spektrum für f ≥ fg verschwindet, aus den Abtastwerten exakt rekonstruiert werden kann, wenn das Abtastintervall zu T ≤ 1/(2 fg ) bzw. die Abtastfrequenz zu fa ≥ 2 fg gewählt wird. Ist diese Bedingung nicht erfüllt, so treten spektrale Rückfaltungen (englisch: aliasing) auf, die u. U. zu starken Signalverzerrungen führen. Durch Vorfilterung mit einem analogen Tief- pass, dessen Grenzfrequenz fc ≤ fg ist, kann dieser Effekt vermieden werden. x0(t) C x2(t) Abbildung 2.1: Prinzip des Abtasthalteglieds x1(t) h 0(t) x0(t) x2(t) p(t) Abbildung 2.2: Äquivalente idealisierte Beschreibung des Abtasthalteglieds 54
  • 54. Reale Abtastsysteme arbeiten, wie in Abbildung 2.1 dargestellt, mit einem Abtasthalteglied. Die Wirkungsweise lässt sich durch ideale Abtastung mit nachfolgender Filterung bzw. Fal- tung mit der Impulsantwort   1 für 0 ≤ t ≤ T  h0 (t) =  (2.3)    0 sonst beschreiben (siehe Bild 2.2). Der Frequenzgang dieses Filters besitzt die Form T sin(ωT/2) − jωT/2 e− jωt dt = T = T · si(ωT/2)e− jωT/2 . H0 ( jω) = e (2.4) ωT/2 0 1 0.8 0.6 |H0 | T 0.4 0.2 0 0 0.2 0.4 0.6 0.8 1 f / fa Abbildung 2.3: Frequenzganggewichtung eines Abtasthaltegliedes im inter- essierenden Bereich 0 ≤ f ≤ fa Daraus resultiert bei der Digital-Analog-Umsetzung die in Bild 2.3 skizzierte Frequenz- ganggewichtung, die durch eine entsprechende gegenläufige digitale oder analoge Filterung kompensiert werden kann. 2.2.2 Quantisierung Da die digitale Verarbeitung notwendigerweise mit einer begrenzten Wortbreite von w Bi- närstellen erfolgt, muss nach der Abtastung quantisiert werden. Hierbei wird ein wertekon- tinuierlicher Abtastwert (im Folgenden vereinfachend mit x(k) bezeichnet) durch eine von 2w möglichen Stufen dargestellt. Für ein Signal mit dem Amplitudenbereich −xmax ≤ x(k) ≤ +xmax (2.5) 55
  • 55. ergibt sich bei einer gleichmäßigen Quantisierung eine Stufenhöhe von xmax ∆x = (2.6) . 2w−1 Zur Beurteilung des resultierenden Quantisierungsfehlers e(k) = x(k) − x(k) ˆ (2.7) werden dessen Leistung N = E{e2 } sowie der Signal-Rausch-Abstand berechnet (siehe [7], Kap. 9.2). Die verschiedenen Formen der gleichmäßigen Quantisierung mit Betragsabschneiden und Runden lassen sich, wie in Bild 2.4 gezeigt, durch Quantisierungskennlinien beschreiben. Bei den Kennlinien a) und b) erfolgt die Quantisierung durch eine Rundungsoperation, wäh- rend die Kennlinie c) das Abschneiden (Abrunden) der Betragswerte beschreibt. Mit der bezüglich der Endpunkte unsymmetrischen Kennlinie a) kann der Wert x = 0 exakt ˆ ∆x dargestellt werden, während für die in beiden Achsenrichtungen um 2 verschobene Kenn- linie b) der betragsmäßig kleinste Wert durch min| x|= ∆x ˆ2 0 repräsentiert wird. Bei den beiden Kennlinien a) und b) ist der Quantisierungsfehler auf ∆x (2.8) |e| ≤ 2 begrenzt. Demgegenüber liegt bei der Kennlinie c) (Betragsabschneiden) der maximale Quantisierungsfehler beim doppelten Wert, d. h. bei max |e| = ∆x. 2.3 Einführung in MATLAB In diesem und dem folgenden Abschnitt werden Ihnen zunächst jeweils die wichtigsten Funktionen für den Umgang mit MATLAB bzw. SIMULINK vermittelt. Anschließend wer- den die zur Lösung der vorbereitenden Aufgaben benötigten Funktionen und Vorgehens- weisen erläutert. Mit den so erlernten Grundlagen sollten Sie schließlich in der Lage sein, selbständig Probleme mit Hilfe von MATLAB und SIMULINK zu lösen. Dies soll dazu die- nen, in der späteren Projektphase Systeme und Funktionen vor der Implementierung auf dem DSP testen zu können. Ferner werden Ihnen diese Grundlagen auch von Nutzen sein, wenn Sie sich im Verlauf des Studiums bzw. im späteren Beruf mit Problemen der digitalen Signalverarbeitung beschäftigen, da MATLAB in vielen wissenschaftlichen Einrichtungen und Firmen eingesetzt wird. 2.3.1 Starten von MATLAB Die aktuelle Version von MATLAB ist eine integrierte Entwicklungsumgebung (IDE: Inte- grated Development Environment). Dies beinhaltet einen Editor, einen Kommandozeilen- Interpreter und andere nützliche Hilfsmittel wie zum Beispiel einen Debugger. Die gesamte 56
  • 56. ˆ +xmax ˆ x xmax = 2w ⋅ ∆x - ∆x ˆ ˆ xi+1 ∆x 2 ˆi x x ∈ {±i ⋅ ∆x} ˆ x i = 0, 1, 2, … xmax = (2w-1) ∆x ∆x xmin xmax 2 xmin = -(2w+1) ∆x 2 E{e2} = ∆x 2 12 -(xmax + ∆x) ˆ a) ˆ +xmax ˆ x xmax = (2w-1) ⋅ ∆x ˆ ˆ xi+1 ∆x 2 xi ˆ x ∈ {±(2i-1) ⋅ ∆x } ˆ 2 xmax = 2w ⋅ ∆x x 2 xmin = -xmax ∆x xmin xmax E{e2} = ∆x 2 12 b) ˆ –xmax ˆ ˆ +xmax x xmax = (2w-2) ⋅ ∆x ˆ ˆ xi+1 ˆ ∆x 2 xi x ∈ {±i ⋅ ∆x} ˆ xmax = 2w ⋅ ∆x x 2 xmin xmax xmin = -xmax ∆x E{e2} = ∆x 2 3 ˆ -xmax c) Abbildung 2.4: Kennlinien für gleichmäßige Quantisierung mit w = 4 a) Rundungskennlinie vom Typ midtread b) Rundungskennlinie vom Typ midrise c) Betragsabschneiden 57
  • 57. Abbildung 2.5: Aufruf zum Start der MATLAB-IDE Umgebung kann unter Windows durch Auswahl unter START ⇒ PROGRAMME ⇒ MAT- LAB 6.5 gestartet werden (siehe Bild 2.5). Es erscheinen sogleich die Fenster mit den Bezeichnungen Workspace, Command History und Command Window. Im Workspace werden alle angelegten Variablen angezeigt, in der Command History werden alle zuvor aufgerufenen Kommandos ausgegeben und im Com- mand Window schließlich werden alle Kommandos dem Interpreter angegeben. Es können nun beliebige Ausdrücke angegeben werden. Diese Ausdrücke werden nach Drücken der Return-Taste sofort ausgeführt. Das Ergebnis wird in der Variable ans abgelegt und auto- matisch ausgegeben. Diese Art der Anwendung nennt sich interaktiver Modus. Ein Beispiel hierfür ist in Bild 2.6 gezeigt. Die automatische Ausgabe kann unterdrückt werden, indem am Ende der Eingabe das Semikolon-Zeichen (’;’) eingegeben wird. Dies sollten Sie sich beim Umgang mit Vektoren und Matrizen zur Gewohnheit machen, um unübersichtliche Ausgaben zu vermeiden. Mit Hilfe der Tastenkombination Ctrl-C kann eine Berechnung oder eine Ausgabe jederzeit beendet werden. Der Inhalt des MATLAB-Fensters kann mit Hilfe des Befehls clc gelöscht werden. 2.3.2 Benutzung von Hilfe-Funktionen Bevor in den folgenden Abschnitten einige der elementaren Variablenstrukturen, Operatio- nen, Funktionen und grafischen Darstellungsmöglichkeiten näher erläutert werden, werden im Folgenden die sehr nützlichen von MATLAB bereibestellten Hilfe-Funktionen vorge- stellt. Diese liefern in der Regel schnell eine Problemlösung, wenn beispielsweise nach speziellen Befehlen, deren Syntax oder deren Optionen gesucht wird. Die umfassendste Hilfestellung bietet das Help Desk, welches mit dem Befehl helpdesk bzw. über den entsprechenden Eintrag im Menü Help aufgerufen wird. Zu allen helpdesk MATLAB Operatoren und Funktionen werden ausführliche Beschreibungen und Beispie- le bereitgestellt. Nach bestimmten Ausdrücken kann in verschiedenen Suchmodi gesucht werden, so zum Beispiel über einen Index oder in einer Suche nach Schlüsselwörtern. Neben dieser ausführlichen Hilfefunktion bieten die Kommandos help <befehlsname> help 58
  • 58. Abbildung 2.6: Beispiel für die Eingabe eines mathematischen Ausdrucks im interaktiven Modus des MATLAB-Interpreters Abbildung 2.7: Helpdesk von Matlab 59
  • 59. und helpwin <befehlsname> Hilfestellungen mit reduziertem Umfang. Beide Komman- helpwin dos helfen auf einfache Weise, sowohl die Syntax als auch die Funktionalität eines Befehls herauszufinden. Hierbei wird beim Aufruf von help <befehlsname> die Hilfeinformation direkt im MATLAB-Kommandofenster dargestellt, während bei helpwin <befehlsname> ein zweites Fenster für die Hilfeinformation geöffnet wird. Beide Kommandos setzen jedoch voraus, dass der Befehlsname bekannt ist. Im Gegensatz hierzu kann mit lookfor <suchbegriff> nach Befehlsnamen gesucht werden. Hierzu lookfor wird die erste Zeile aller help-Beschreibungen nach Übereinstimmungen mit dem Suchbe- griff überprüft und gegebenenfalls ausgegeben. 2.3.3 Verwendung von Variablen Bei Benutzung von MATLAB wird in den meisten Fällen mit Variablen gearbeitet, denen man Ergebnisse bzw. Zahlenwerte zuweist. Dies geschieht automatisch, indem die Variable benannt wird. Ein Beispiel hierfür ist in Bild 2.8 dargestellt. Auch hier wird die automa- tische Ausgabe mit Hilfe des Semikolon-Zeichens unterdrückt. Der Name einer Variablen muss mit einem alphabetischen Zeichen beginnen; Groß- und Kleinschreibung wird be- rücksichtigt. Aus diesem Grund sind die MATLAB-Schlüsselworte, wie z. B. Namen von Funktionen usw. klein zu schreiben. Abbildung 2.8: Beispiel für die automatische Zuweisung einer Variablen mit und ohne Unterdrückung der Ausgabe Eine Übersicht aller im Workspace aktuell verwendeten Variablen mit Größe, Speicherbele- gung und Variablenart kann im Workspace-Fenster eingesehen werden, desweiteren liefert der Befehl whos (siehe Bild 2.9) dieselbe Information. whos Variablen können mit dem Befehl clear <variablenname> gelöscht werden; clear oh- clear ne Angabe eines Namens löscht alle vorhandenen Variablen. Hat man eine vordefinierte Variable wie z. B. pi umdefiniert, so hat eine solche Variable nach einem Aufruf von clear wieder seine ursprüngliche Bedeutung. Im Allgemeinen sollte man jedoch sehr vorsichtig mit der Verwendung von vordefinierten Namen als Variablen- oder Funktionsnamen sein, da dies zu unerwarteten Ergebnissen führen kann. Bevor man also einen Bezeichner ver- wendet, bei dem man sich nicht ganz sicher ist, ob eine eingebaute Variable oder Funktion bereits so heißt, sollte man help <name> aufrufen. Falls dieser Befehl meldet, dass es kei- 60
  • 60. Abbildung 2.9: Beispiel für eine Ausgabe des Befehls whos ne zugehörige .m Datei gefunden hat, ist dieser Name zumindest durch keine Funktion oder Variable von Matlab vordefiniert. Variablenstrukturen In MATLAB werden fast alle Daten in Form von Feldern (array) dargestellt. Skalare Größen werden als Feld der Dimension 1 × 1 dargestellt. Einfache Vektoren der Länge n können entweder als Zeilen- (1 × n) oder als Spaltenvektor (n × 1) abgelegt sein. Felder können aber auch Matrizen beliebiger Dimension n aufnehmen (dim1 × dim2 × . . . × dimn ). Die einzelnen Elemente der Felder können nun nicht nur Zahlen (reell und komplex) sondern auch ein- zelne Zeichen aufnehmen. Eine Zeichenkette der Länge n wird dabei als Zeilenvektor der Länge n (1 × n) mit dem speizellen Typ char array dargestellt. Im Allgemeinen wird eine Variable durch Zuweisen eines Wertes erzeugt. Dabei ist es nicht Variablen zuweisen nötig zuvor einen Typ festzulegen. Diesen erkennt MATLAB automatisch. Will man z. B. eine skalare Variable x anlegen, die den Wert 12.5 enthalten soll, so erreicht man dies durch x=12.5. Auf gleiche Weise kann der Inhalt einer Variablen einer anderen zugewiesen werden (z. B. x=y). Ein Feld wird durch Verwenden eckiger Klammern gebildet. Dabei werden die Zeilenele- Felder erzeugen mente durch Leerzeichen oder Kommata, die Spaltenelemente durch Semikolons getrennt. Ein zweidimensionales Feld der Größe 3×3, welches zeilenweise die Zahlen 1 bis 9 enthält, kann folglich mit [1 2 3; 4, 5, 6; 7 8 9] erzeugt werden. Auf einzelne Elemente bzw. Bereiche von Elementen einer Variablen kann man in der Form <variablenname>(m,n) zugreifen, wobei m die Zeilenangabe und n die Spaltenangabe ist. Anstelle der Konstanten m und n können auch Variablen und beliebige mathematische Ausdrücke verwendet werden. Dabei ist jedoch auf die richtige Größe der Variablen zu achten. In Bild 2.10 ist die Bildung eines Zeilen- bzw. Spaltenvektors und einer 3×4 Matrix gezeigt. Zur Erstellung eines Zeichenfeldes müssen die Zeichen zwischen Hochkommata (’Text’) gesetzt werden. Ansonsten gelten die gleichen Konventionen wie für numerische Felder. Es stehen zwei Funktionen zur Verfügung, um Auskunft über die Dimension einer Variablen 61
  • 61. Abbildung 2.10: Beispiel für die Erstellung eines Vektors bzw. einer Matrix zu erhalten: gibt Auskunft über die Länge der Variablen x (auf einen length(x) Vektor angewendet wird die Länge ausgegeben; auf ein Feld angewendet wird das Maximum von (m,n) ausgege- ben.) gibt Auskunft über die Dimension der Variablen x (die Aus- size(x) gabe liefert ans = m n) 2.3.4 Operationen mit Vektoren und Matrizen MATLAB stellt eine große Anzahl von Befehlen und Funktionen zur Erstellung und Manipu- lationen von Feldern zur Verfügung. In den folgenden Abschnitten werden die wichtigsten Funktionen vorgestellt. Eine Beschreibung weiterer Funktionen ist z. B. in [2] oder [4] bzw. in der umfangreichen Hilfe von MATLAB zu finden (siehe Abschnitt 2.3.2). Generierung von Feldern Um Vektoren zu erzeugen, deren Werte konstanten Abstand haben (z. B. [1 2 3 4 5]), bietet MATLAB mit dem Colon-Operator (’:’) eine sehr elegante Möglichkeit. Man braucht Colon nur Startwert, Schrittweite und Endwert in der Form start:step:end anzugeben und MATLAB erzeugt daraus den entsprechenden Zeilenvektor. Wird die Schrittweite ausgelas- sen, nimmt sie ihren Standardwert von 1 an. Abbildung 2.11 zeigt die Funktionsweise des Colon-Operators. Die auf diese Weise erzeugten Vektoren lassen sich überall dort einsetzen, wo auch sonst Vektoren verwendet werden können. Zum einen kann der erzeugte Vektor natürlich wie in Abbildung 2.11 gezeigt einer Variablen zugewiesen werden. Eine weitere viel genutzte Einsatzmöglichkeit ist, dieses Konstrukt zu nutzen, um auf einfache Weise ganze Element- Bereiche auswählen 62
  • 62. Abbildung 2.11: Beispiel für die Generation von Vektoren mit Hilfe des Co- lon-Zeichens bereiche aus Vektoren zu extrahieren. So lassen sich z. B. durch Eingabe von x1=x(5:10) 6 Elemente aus dem Vektor x in x1 ablegen. Ferner kann damit auf Teilmatrizen zugegriffen werden. Die Eingabe von m1=m(5:10,6:9) würde z. B. aus den Zeilen 5 bis 10 und den Spalten 6 bis 9 der Matrix m die Matrix m1 bilden. Der komplette Bereich einer Dimension kann dabei durch Auslassen von Start- und Endwert erfolgen (also z. B. m1=m(:,6:9)). Weitere hilfreiche Funktionen zur Generierung elementarer Felder (Beispiele hierzu sind in Bild 2.12 gezeigt) werden in der folgenden Auflistung kurz vorgestellt. Die Anzahl der Argumente der angegebenen Funktionen kann unter Umständen variieren. Durch optionale Argumente kann die Funktionsweise in der Regel genauer spezifiziert oder spezielle Optio- nen gesetzt werden. Ausführliche Beschreibungen sind über die in Abschnitt 2.3.2 zusam- mengefassten Hilfe-Funktionen zu finden. Feld der Dimension m × n mit Nullwerten zeros(m,n) Feld der Dimension m × n mit Einserwerten ones(m,n) Identitätsmatrix der Dimension m × n eye(m,n) Feld der Dimension m × n mit gleichmäßig- bzw. rand(m,n), randn(m,n) normalverteilt zufälligen Werten Vektor der Länge N mit linearem bzw. logarithmi- linspace(m,n,N), schem Abstand der Werte (Start: n, Ende: m) logspace(m,n,N) Manipulation von Feldern Zur Manipulation von Feldern stehen unter MATLAB eine Vielzahl von Funktionen zur Verfügung, von denen hier nur die grundlegenden beschrieben werden; x und y seien im folgenden Felder entsprechender Größe: 63
  • 63. Abbildung 2.12: Beispielausgaben der in MATLAB zur Verfügung stehen- den Funktionen zur Generation von Feldern Bildung des Skalar- bzw. Matrixprodukts x*y Elementweise Addition x+y Elementweise Subtraktion x-y Elementweise Multiplikation x .* y Transponieren x’ Bildung der Inversen einer Matrix inv(x) 2.3.5 Elementare Funktionen In diesem Abschnitt werden einige spezielle Funktionen vorgestellt, die zur Signalanalyse hilfreich sind. Da MATLAB eine sehr große Anzahl an Funktionen zur Verfügung stellt, kann hier nur auf einige eingegangen werden (siehe Abschnitt 2.3.2 für ergänzende Informatio- nen). x sei im folgenden ein Feld entsprechender Größe, n sei ein beliebiger Zahlenwert: liefert einen Zeilenvektor mit den Höchstwerten (Minimalwerten) max(x), min(x) der einzelnen Spalten. Wenn x ein Zeilenvektor ist, wird der größ- te (kleinste) Wert dieses Vektors ausgegeben. berechnet die absoluten Werte der Elemente des Vektors x. Wenn abs(x) x komplexe Elemente enthält, wird der Betrag ausgegeben. 64
  • 64. liefert ein Feld mit Einsen und Nullen, so dass die Einsen das x<n Erfüllen (true) und die Nullen das nicht Erfüllen (false) der Ver- gleichsoperation darstellen. (Weiter Vergleichsoperationen sind > größer, == gleich, <= kleiner oder gleich, >= größer oder gleich, ∼= nicht gleich) liefert die Indizes der Elemente des Feldes, für welche die Bedin- find(x < n) gung der Vergleichsoperation erfüllt ist. wendet die schnelle (inverse) diskrete Fourier-Transformation fft(x), ifft(x) (DFT/IDFT) auf den Vektor x an wendet die Sinus-/Cosinus-Funktion auf die Elemente des Vek- sin(x), cos(x) tors x an 2.3.6 Grafische Darstellungsmöglichkeiten Zur grafischen Darstellung von Feldern stehen unter MATLAB eine Vielzahl von Funktionen zur Verfügung, von denen hier nur die grundlegenden genannt werden. lineare x-y Darstellung des Vektors x plot(x) logarithmische x-y Darstellung des Vektors x loglog(x) wie plot(x) aber x-Achse logarithmisch semilogx(x) wie plot(x) aber y-Achse logarithmisch semilogy(x) 3-D-Darstellung (Gitter) der Matrix x mesh(x) 3-D-Darstellung (Gitter mit Farbflächen) der Matrix x surf(x) Darstellung des Leistungsdichtespektrums des Vektors x spectrum(x) Spektrogramm für Sprachsignale (Leistungsdichtespektrum über specgram(x) der Zeit) des Vektors x 2.3.7 Audiowiedergabe Mit dem Befehl sound(x, f) kann ein Signal-Vektor x bei einer Abtastfrequenz von f abgespielt werden. 2.3.8 Verwalten von Daten und Dateien Die mit MATLAB erzeugten Daten lassen sich auf unterschiedliche Weise abspeichern. Der Befehl save <dateiname> speichert alle zur Zeit vorhandenen Variablen in der Datei save dateiname.mat ab. Dies ist sinnvoll, um die MATLAB-Sitzung zu einem späteren Zeit- punkt fortzusetzen. Mit Hilfe des Befehls load <dateiname> werden diese Variablen wie- load der in die Arbeitumgebung geladen. Beide Befehle können auch in der Form save <dateiname> <variable1> <variable2> <...> bzw. load <dateiname> <variable1> <variable2> <...> verwendet werden. Dabei werden nur die angegebenen Variablen gespeichert bzw. gela- 65
  • 65. den. Bei Verwendung dieser Befehle bleibt die Zuweisung der Variablennamen zu den Zahlenwerten fest. Es besteht auch die Möglichkeit, Variablen im ASCII-Format abzu- speichern, indem der Befehl save mit dem Parameter -ascii verwendet wird (z. B. save <dateiname> <variable1> <...> -ascii). Bei einer in diesem Format erstellten Da- tei werden die gespeicherten Daten einer Variablen zugewiesen, die identisch mit dem Da- teinamen ist. In den folgenden Versuchen werden zum Speichern bzw. Laden der benötigten Daten die Befehle savedbl und loaddbl verwendet, mit denen einzelne Variablen im Format double savedbl loaddbl verwaltet werden. Im Unterschied zu save und load besteht hier keine Bindung zwischen Zahlenwerten und Variablennamen. Mit der Befehlszeile savedbl(variablenname, ’dateiname.dbl’) wird eine Variable gespeichert; durch Eingabe von variablenname = loaddbl(’dateiname.dbl’) wird der Datensatz in die entsprechende Variable geladen. Verwalten von Dateien Unter MATLAB stehen folgende Befehle zum Verwalten von Dateien zur Verfügung: Anzeigen des aktuellen Arbeitsverzeichnisses pwd Auflisten des Verzeichnisinhalts ls Auflisten des Verzeichnisinhalts dir In der Verzeichnisstruktur in die nächst höhere Ebene wechseln cd .. Wechseln in ein Unterverzeichnis mit Angabe des Namens cd verzeichnisname Bei Verwendung der Befehle pwd, dir und ls wird die Ausgabe in der Variablen ans gespeichert. Dies kann zum automatischen Verarbeiten von Dateien sehr hilfreich sein. 2.3.9 Erstellen von Skripten und Funktionen MATLAB ermöglicht das Implementieren eigener Skripte und Funktionen. Hierfür werden ausführbare Kommandos hintereinander in ein sogenanntes M-File geschrieben. Danach können das Skript bzw. die Funktion aus dem Interpreter-Fenster heraus aufgerufen und die Befehle ausgeführt werden. Das M-File trägt dabei den Namen des Skriptes bzw. der Funktion. Um ein Skript oder eine Funktion zu editieren, muss zunächst der integrierte Editor aufgerufen werden. Dies geschieht durch Verwendung des Befehls edit. In einem neuen Fenster kann jetzt eine Datei eingegeben und schließlich abgespeichert werden. Skripte Skripte sind einfache Abfolgen von Kommandos wie sie auch im Interpreter-Fenster ein- gegeben werden. Die Operationen arbeiten auf Daten, die im Workspace bereits vorhanden sind, Parameterübergaben sind nicht möglich. Ein Skript kann neue Variablen erzeugen, die ins Workspace geschrieben werden. Skripte sind insbesondere dann nützlich, wenn Befehlsabfolgen häufig wiederkehren. Beispiel: Das Skript stat soll den Mittelwert und die Standardabweichung eines Vektors berechnen. 66
  • 66. Das zugehörige “M-File” “stat.m” kann dann folgendermaßen ausehen: n = length(x); mean = sum(x) / n; stdev = sqrt(sum((x - mean).^2)/n); Dabei muss x bereits im Workspace vorhanden sein. Der Aufruf des Skriptes aus dem Interpreter-Fenster geschieht hier durch das Kommando stat. Nach Beendigung des Skrip- tes befinden sich die Variablen n, mean und stdev neu im Workspace. Funktionen Funktionen zeichnen sich durch klar definierte Schnittstellen zum Workspace oder zu ande- ren Funktionen aus. Durch einen Header werden Ein- und Ausgabevariablen definiert. Jede Funktion bekommt von MATLAB einen eigenen Namensbereich zugewiesen. Dadurch sind funktionsinterne Variablen nur innerhalb der Funktion sichtbar. Außerdem können im Ge- gensatz zum Skript Variablen aus dem Workspace nicht in der Funktion verändert werden, auch dann nicht, wenn diese als Übergabeparameter der Funktion zur Verfügung gestellt wurden. Man spricht von “call-by-value”. Beispiel: Eine Funktion, die Mittelwert und Standardabweichung eines Übergabevektors berechnet und zurückgibt, kann folgendermaßen aussehen: function [mean, stdev] = stat(x) n = length(x); mean = sum(x) / n; stdev = sqrt(sum((x - mean).^2)/n); Aus dem Interpreter-Fenster heraus lässt sich die Funktion dann z. B. mittels [mx stdx] = stat(x) aufrufen, wobei der Übergabevektor x sich im Workspace befindet und mx bzw. stdx nach Beendigung der Funktion ins Workspace geschrieben werden. 2.4 Einführung in SIMULINK In diesem Abschnitt werden die zum Umgang mit SIMULINK benötigten Grundlagen ver- mittelt. Der Umgang mit SIMULINK gestaltet sich sehr intuitiv. Da in diesem Versuch hauptsächlich das DSP-Blockset verwendet wird, welches die meisten zur digitalen Signal- verarbeitung benötigten Funktionen beinhaltet, werden alle Beispiele anhand dieses Block- sets kurz erläutert. Der Umgang mit allen anderen Blöcken gestaltet sich in gleicher Weise und ist schnell selbständig zu erlernen. Auch hier sei auf Abschnitt 2.3.2 und insbesondere auf die helpdesk Funktion verwiesen. SIMULINK ist eine Software zum Aufbau von Simulationsmodellen, die auf einer grafi- schen Benutzeroberfläche in Form von Fenstern basiert. Die Modelle werden durch einzel- ne Blöcke, die untereinander verbunden werden, zusammengesetzt. In SIMULINK gibt es grundsätzlich zwei verschiedene Arten von Fenstern: Modellfenster und Bibliotheksfenster. Modellfenster sind zum Erstellen von Modellen gedacht, das heißt, sie sind editierbar, wäh- rend Bibliotheksfenster nur zum Bereitstellen von Blöcken für das Modell gedacht sind. 67
  • 67. Bibliotheksfenster können auch weitere Bibliotheken enthalten. Im Allgemeinen wird ein Modell durch das Hinüberziehen von Blöcken mit der Maus aus Bibliotheksfenstern in das Modellfenster erzeugt. Dort können die Blöcke mit der Maus miteinander verbunden wer- den, so dass ein Datenaustausch zwischen ihnen stattfinden kann. Ein SIMULINK-Modell besteht aus drei Typen von Elementen: einer oder mehreren Quel- len, dem Modell des zu simulierenden Systems und einer oder mehreren Senken. Die Quel- len (sources) sind die Eingabewerte für das simulierte System. Sie beinhalten zum Bei- spiel Sinuswellen, Stoßfunktionen oder Variablen aus dem MATLAB-Workspace. Die Sen- ken (sinks) empfangen die Ausgabewerte des Systems. Beispiele für Senken sind Graphen, Oszilloskope, Dateien oder wiederum Variablen im MATLAB-Workspace. Modelle können über beliebige Zeitabschnitte simuliert werden, wobei Ergebnisse in be- liebigen Zeitabständen ausgegeben werden können. Auf diese Weise kann der Ablauf einer Simulation genau beobachtet werden. 2.4.1 Starten von SIMULINK Die Simulationsumgebung SIMULINK wird vom MATLAB-Prompt durch die Eingabe von simulink simulink gestartet. Abbildung 2.13: Startbildschirm von SIMULINK Daraufhin öffnet sich ein editierbares Modell- und ein Bibliotheksfenster. Letzteres enthält die einzelnen SIMULINK-Bibliotheken sowie einen Verweis auf die Blocksets und Toolbo- xes. Durch Doppelklick auf ein Bibliothekssymbol wird die dazugehörige Bibliothek auf der rechten Seite geöffnet, wobei die einzelnen Funktionsblöcke dieser Bibliothek darge- stellt sind. Diese Funktionsblöcke lassen sich mit der Maus in das Modellfenster herüber- ziehen. Die Bibliotheksfenster selbst lassen sich jedoch nicht verändern. Im Rahmen dieses Praktikums soll im Wesentlichen mit dem DSP-Blockset gearbeitet wer- den (siehe Abb. 2.14), das sich unter dem Symbol Blocksets & Toolboxes verbirgt. Die Parameter der verwendeten Funktionsblöcke lassen sich nach dem Kopieren in das Modellfenster gewöhnlich durch Doppelklick auf den entsprechenden Block aufrufen und editieren. Die Parameter variieren von Block zu Block, wichtig ist es aber in jedem Fall, 68
  • 68. Abbildung 2.14: Die DSP-Blockset Toolbox 69
  • 69. auf die richtigen Abtastintervalle für zeitdiskrete Blöcke zu achten. Obwohl grundsätzlich eine beliebige Zeitskalierung verwendet werden kann, ist es sinnvoll, die Abtastintervalle in Sekunden anzugeben, da man sonst leicht den Überblick verliert. Es ist möglich, in die Eingabefelder auch mathematische Ausdrücke einzugeben, so dass man zum Beispiel für eine Abtastrate von 8000 Hz als Abtastzeit 1/8000 eintragen kann. 2.4.2 Die Quellen eines SIMULINK-Modells Die häufig benötigten Quellen sind sowohl in der DSP-Toolbox unter DSP Sources als auch bei den SIMULINK-Sources zu finden (siehe Abb. 2.15). Dort befinden sich zum Beispiel Konstanten, deren Wert im Einstellungsfenster editiert werden kann, die Sprungfunktion oder die Sinusfunktion, bei der sich Amplitude, Phase und Frequenz einstellen lässt. Der Signal Generator-Block lässt sich zwischen verschiedenen Funktionen umschalten, so dass nicht jedesmal ein neuer Block in das Modell eingefügt werden muss. Besonders wichtig ist der Signal From Workspace-Block, mit dessen Hilfe es möglich ist, beliebige Eingangssignale aus dem MATLAB-Workspace zu verwenden. Auf diese Weise können unter MATLAB beliebige Signale erzeugt oder aus Dateien geladen werden, die danach mit einem SIMULINK-Modell bearbeitet werden können. Abbildung 2.15: Die Quellblöcke von SIMULINK 70
  • 70. 2.4.3 Die Senken eines SIMULINK-Modells Häufig wird man zur Analyse des Ausgabesignals eine grafische Ausgabe wählen. Hier gibt es in der DSP-Toolbox unter DSP Sinks Ausgabeblöcke sowohl für den Zeitbereich als auch für den Frequenzbereich. Für Ausgaben im Zeitbereich gibt es das Vector Scope, das eine fest definierbare Anzahl von Werten darstellt oder unter den SIMULINK-Sinks das Scope, dessen Zeitskalierung sich automatisch an die Simulationsdauer anpassen kann. Der Scope-Block bietet außerdem die Möglichkeit, einen beliebigen Bereich der grafischen Dar- stellung zu vergrößern, in dem man den Zoom-Button, der mit einer Lupe gekennzeichnet ist, im Ausgabefenster betätigt und dann den gewünschten Bereich mit der Maus selektiert. Für die Ausgabe im Frequenzbereich gibt es Blöcke, die die FFT ihres Eingangssignals darstellen. Der Vector Scope-Block kann auch ein Signal im Frequenzbereich darstellen. Desweiteren bietet der Spectrum Scope-Block die Möglichkeit, die FFT eines gepufferten oder ungepufferten Signals darzustellen, Abbildung 2.16: Die Senken von Simulink Mit dem To Workspace-Block lassen sich Ergebniswerte in den MATLAB-Workspace trans- ferieren, wobei der Name der Variablen, in die die Werte geschrieben werden sollen, im Einstellungsfenster des Blocks eingegeben werden kann. 2.4.4 Starten einer Simulation mit Angabe von Simulationsparametern Die Kontrolle über den Ablauf der Simulation befindet sich im Modellfenster unter dem Menüpunkt Simulation. Dort lassen sich die Simulationsparameter wie Startzeit, Stoppzeit und Lösungsverfahren einstellen. Da im Verlauf dieses Praktikums nur zeitdiskrete Model- le erstellt werden (wie sie auf einem digitalen Signalprozessor auch nur zu verwirklichen sind), sollte unter Solver options immer discrete (no continuous states) eingestellt werden. Eine falsche Wahl der Start- und Stoppzeit ist ein häufiger Fehler bei der Simulation eines Modells. Sie sollten bei der Wahl der Stoppzeit z. B. darauf achten, dass zu diesem Zeitpunkt 71
  • 71. auch wirklich alle Puffer gefüllt sind, da sie vorher keinen Vektor ausgeben. Unter dem Menüpunkt Simulation lässt sich die Simulation durch Auswahl des Unterpunkts Start starten, durch den Unterpunkt Stop beenden und durch die Unterpunkte Pause bzw. Continue anhalten und fortsetzen. Während die Simulation läuft, ist es in gewissen Grenzen immer noch möglich, das Modell zu verändern, wie zum Beispiel Oszilloskope an andere Stellen anzuschließen, um die Verarbeitung des Signals im Modell nachzuvollziehen. Ein Beispiel für ein Simulink-Modell inklusive Ausgabe-Senken zeigt Abbildung 2.17. Abbildung 2.17: Beispiel für ein SIMULINK-Modell 2.5 DSP-Debugging mit MATLAB Zum Testen und Verifizieren von Algorithmen, die mit Visual DSP++ auf dem DSP imple- mentiert wurden, wird der MATLAB-Debugger verwendet. Dazu wird der Algorithmus von MATLAB aus als remote function call ausgeführt. Lesen zunächst das Handbuch RTProcDSP – Rapid Prototyping on Embedded Targets, in dem das Debugging von Algorithmen auf dem DSP mit Hilfe von MATLAB ausführlich beschrieben wird (s. Kap. 3.5.5). Zusätzlich zu den dort beschriebenen Funktionen stehen Ihnen unter MATLAB auch folgende vereinfachte Funktionen zur Verfügung: [remoteFunctions] = rtProcDSP_enableDebugging(idComPort) Kapselt die zur Initialisierung des Debuggings nötigen Funktionen. Öffnet den COM-Port mit der ID idComPort (überlicherweise 0) und stellt eine Verbindung zum DSP her. In der 72
  • 72. Variable remoteFunctions sind die Namen der zum Debugging registrierten Funktionen abgespeichert. [success error outBuffer] = rtProcDSP_executeRemoteFunctionsDSP(fid, bufSize, inBuffer) Diese Funktion wurde bereits im Handbuch RTProcDSP – Rapid Prototyping on Embedded Targets detailliert beschrieben. Mit Hilfe von rtProcDSP_executeRemoteFunctionsDSP werden eine beliebige Anzahl an Eingabevariablen inBuffer an den DSP übergeben. Die Funktion wird auf dem DSP ausgeführt, anschließend wird das Ergebnis über die Variablen outBuffer zurückgegeben. Mit der Eingabevariable fid wird eine ID zur Identifizierung der auszuführenden Funktion übergeben, mit bufSize wird die Größe der Ausgabevaria- blen festgelegt. Zusätzlicher Rückgabewert ist die Bool’sche Variable success, die angibt, ob die Operation erfolgreich ausgeführt worden ist. Sollte dies nicht der Fall sein, wird eine Fehler-Nachricht über die zweite Ausgabevariable error zurückgegeben. rtProcDSP_disableDebugging() Kapselt alle zur Beendigung des Debuggings nötigen Funktionen. Beendet die Verbindung zum DSP und schließt die geöffneten COM-Ports. Die Verwendung der obigen Funktionen soll im Folgenden anhand eines einfachen Beispiels demonstriert werden. Die Funktion testFunction, die bereits im Handbuch RTProcDSP – Rapid Prototyping on Embedded Targets beschrieben wurde, wird hier untersucht, indem ein Zufallsvektor übergeben wird. >> rF = rtProcDSP_enableDebugging(0) Com port was successfully opened, now trying to activate port. Device detected at specified com port. Right DSP device detected, connection established successfully. Device successfully switched into debug mode. rtProcDSP: Debugging has been successfully enabled! data = description: ’DSP DEBUG control for RTPROC DSP’ systemState: 4 timeoutMsec: 8000 comPorts: {’COM1’ ’COM2’ ’COM3’ ’COM4’} connectComPortID: 0 tokenDSP: ’IND,ADSP21369,RTPROC_DSP’ debugFunctions: {[1x1 struct] [1x1 struct]} rF = [1x1 struct] [1x1 struct] >> rF{1} ans = functionName: ’testFunction’ numberArgsIn: 1 numberArgsOut: 1 >> [success error out] = rtProcDSP_executeRemoteFunctionDSP(0,[5],rand(1,5)) Remote Function Call terminated succesfully. success = 1 error = ’’ out = 0.0975 0.2785 0.5469 0.9575 0.9649 73
  • 73. >> rtProcDSP_disableDebugging() Device successfully switched into regular mode. Safely disconnected device from PC.rtProcDSP: Debugging has been disabled! 74
  • 74. 2.6 Vorbereitende Aufgaben Die vorbereitenden Aufgaben sind zu Hause vollständig zu lösen. 2.6.1 Aufgabe I Überlegen Sie sich, wie man in MATLAB ein Cosinus-Signal erzeugt, das aus n = 8000 Werten besteht und bei einer gegebenen Abtastfrequenz fa = 8000 Hz die Frequenz f = 2000 Hz besitzt. Verwenden Sie hierzu das Colon-Zeichen zur Generierung des Eingangsvektors, einfache Operationen zur Manipulation von Feldern sowie die cos-Funktion. Lösung: 2.6.2 Aufgabe II Wie kann man in MATLAB mit einfachen Vektoroperationen die Energie eines Signals be- stimmen? Lösung: 75
  • 75. 2.6.3 Aufgabe III ∆x2 Leiten Sie die Rauschleistung E{e2 } = eines gleichmäßigen Quantisierers her. 12 Lösung: 2.6.4 Aufgabe IV Der Hilbert-Transformator ist ein System, das häufig im Zusammenhang mit der Quadratur- modulation, der Einseitenbandmodulation und der Bestimmung der Einhüllenden (analyti- sches Signal) eingesetzt wird. Er bewirkt eine Phasenverschiebung um ∆ϕ(Ω) = 90 Grad. Der ideale zeitdiskrete (nichtkausale) Hilbert-Transformator wird beschrieben durch HH0 (e jΩ ) = − j · sgn(Ω) −π≤Ω≤π (2.9) π 1 − j · sgn(Ω)e jΩk dΩ hH0 (k) = (2.10) 2π −π 1 = (1 − cos(πk)) (2.11) πk   0 ; k = 0, ±2, ±4, . . .  = (2.12)  2 ; k ungerade  πk Wie kann die Hüllkurve eines amplitudenmodulierten Signals mit Hilfe eines Hilbert-Transformators gewonnen werden? Geben Sie die Blockschaltbilder eines Hüllkurvenempfängers sowie des dazugehörigen Senders an, indem Sie die Quadraturkomponenten mittels Hilbert-Transformator bilden. Berücksichtigen Sie die durch den Transformator verursachte Zeitverzögerung! 76
  • 76. Lösung: 2.7 Versuchsdurchführung Die mit (*) gekennzeichneten Versuche sind nur zur Vertiefung des Stoffs gedacht und kön- nen weggelassen werden, falls die zur Verfügung stehende Zeit nicht ausreicht. 2.7.1 Versuch A: Grundlegende MATLAB-Operationen Im folgenden werden Sie mit den wichtigsten Funktionen von MATLAB und SIMULINK kurz vertraut gemacht. Erzeugen Sie in MATLAB ein Cosinus-förmiges Signal der Länge N = 512, das bei einer Abtastfrequenz fa = 8000 Hz die Frequenz f = 1000 Hz besitzt. Nennen Sie dieses Signal signal1. Speichern Sie das Signal mit der MATLAB-Funktion savedbl unter dem Namen signal1.dbl ab. 77
  • 77. Lassen Sie sich signal1 und dessen Betragsspektrum grafisch darstellen. Berechnen Sie zur Darstellung des Betragsspektrum zunächst die FFT und geben sie dann den Betrag der erhaltenen Fourier-Koeffizienten aus. Lesen Sie nun das File signal2.dbl, das sich bereits auf der Festplatte befindet, mit loaddbl in die Variable signal2 ein und bestimmen Sie die Länge des Signals. Lassen Sie sich signal2 und dessen Leistungsdichtespektrum über der Zeit grafisch dar- stellen. Um was für ein Signal handelt es sich bei signal2? Bestimmen Sie jeweils die minimale/maximale Aussteuerung und die Leistung beider Si- gnale. Lösung: 2.7.2 Versuch B: MATLAB-Funktionen Mit Hilfe einer MATLAB-Funktion soll ein Echoeffekt implementiert werden. Das Echo soll als Rückkopplungseffekt nach Abbildung 2.18 verstanden werden. s(k) s(k) ˆ T delay g Abbildung 2.18: Erzeugung eines Echos Erstellen Sie in Ihrem Arbeitsverzeichnis ein “M-File” mit dem Namen “makeEcho.m”. Die darin zu implementierende Funktion soll als Übergabe ein Sprachsignal, die Verzögerung “delay” in Samples und einen Echogewichtungsfaktor “g” bekommen. Das echobehaftete Signal soll zurückgegeben werden. Der Header der Funktion sieht also folgendermaßen aus: function [out] = makeEcho(in,delay,g); Achten Sie bei der Implementierung auf das Einschwingen der Rückkopplung. Da in MAT- LAB for-Schleifen ineffizient programmiert sind, kann die Bearbeitung der Funktion unter 78
  • 78. Umständen lange dauern. Beschränken Sie bei Bedarf die Länge des Eingabesignals. Versehen Sie signal2 durch Ihre Funktion mit einem Echo und hören Sie sich das Ergeb- nis an. Variieren Sie die Parameter für unterschiedlich starke Echos. Was passiert, wenn “g” nahe eins gewählt wird? 2.7.3 Versuch C: DSP-Debugging mit MATLAB Im Folgenden sollen Sie mit den Möglichkeiten vertraut gemacht werden, DSP-Funktionen mit Hilfe des MATLAB-Debuggers zu verifizieren. Öffnen Sie dazu das Projekt rtProcDSP im Unterverzeichnis V3/rtProcDSP mit der Ent- wicklungsumgebung Visual DSP++. Die Funktion unknownFunction ist in der Datei al- gorithmStart.c wie folgt definiert: WORD 32 unknownFunction(float** inFields, WORD32 numArgsIn, WORD32* fLengthsIn, float** outFields, WORD32 numArgsOut, WORD32* fLengthsOut); Überprüfen Sie, welche Aufgabe die obige Funktion erfüllt, indem Sie sie über den MATLAB- Debugger (mit der Funktion rtProcDSP_executeRemoteFunctionsDSP, s. Kap. 2.5) aus- führen. Übergeben Sie dazu die beiden Vektoren in1 = [1:10] und in2 = [2:2:20] und analysieren Sie das Ergebnis. Beachten Sie, dass die Funktion bereits im Quelltext für das Debugging registriert ist. Führen Sie im Anschluß an die Verifikation mit dem MATLAB-Debugger die Funktion auf dem DSP aus, indem Sie die Funktion unknownFunction in der process-Funktion aufru- fen. 2.7.4 Versuch D: Echo-Effekt mit dem DSP / Zyklischer Speicher Der Echo-Effekt aus Versuchsteil B soll nun auf dem DSP implementiert werden. Es ist zu beachten, dass die Implementierung des Echo-Effekts auf eine blockbasierte Verarbei- tung hin angepasst werden muss, da der DSP das Audiosignal in kleine Blöcke (hier üb- licherweise mit einer Länge von 512 Samples) aufteilt und einzeln verarbeitet. Damit der Echo-Effekt auch für Verzögerungen, die größer sind als eine Blocklänge, möglich ist, ist die Verwendung eines zyklischen Speichers notwendig, dessen Arbeitsprinzip in Abbildung 2.19 verdeutlicht wird. Ein zyklischer Speicher eignet sich – im Gegensatz zu einem linea- ren Array – sehr gut als FIFO-Speicher (First In First Out). Der Zugriff auf die Elemente des zyklischen Speichers erfolgt mit einem Lese- und einem Schreibpointer. Nach jedem Lese- oder Schreibzugriff werden die Pointer um ein Speicherelement verschoben. Ein zyklischer Speicher kann auf dem DSP einfach mit Hilfe des Befehls circptr imple- mentiert werden. #include <processor_include.h> void* circptr(void *ptr. size_t, incr, void *base, size_t buflen); Weitere Informationen zu den DSP-Befehlen finden Sie im Run-Time Library Manual for SHARC Processors. 79
  • 79. Abbildung 2.19: Erzeugung eines Echos mit Hilfe eines zyklischen Spei- chers. 2.7.5 (*) Versuch E: Rückfaltungen Um an den Umgang mit SIMULINK herangeführt zu werden, soll Schritt für Schritt ein einfaches Modell aufgebaut werden. Starten Sie SIMULINK durch Eingabe von simulink am MATLAB-Prompt. Erstellen Sie nun ein Modell, das das Sinussignal eines Signalgenerators und seine Fouriertransformierte grafisch darstellt. Suchen Sie in SIMULINK einen zeitdiskreten Sinusgenerator (DSP Blockset → DSP Sources) heraus. Führen Sie einen Doppelklick mit der linken Maustaste auf den Block aus und öff- nen Sie so das Einstellungsfenster des Signalgenerators. Wählen sie die Amplitude 1 und die Frequenz 500 Hz bei einer Abtastrate von 8000 Hz. Lassen Sie sich das Signal vom Sinusgenerator durch einen Time Scope und einen rahmenbasierten Spectrum Scope (DSP Blockset → DSP Sinks) anzeigen. Die Rahmengröße wird hierzu zu 128 ohne Überlappung gewählt. Verbinden Sie die Blöcke im Modellfenster. Schließlich müssen noch die Simulationsparameter eingestellt werden, die über den entspre- chenden Menüpunkt im Menü Simulation zu finden sind. Stellen Sie hier unter Simulation time als Startzeit 0.0 und als Stoppzeit 128/8000 ein, so dass der Puffer genau einmal ge- füllt wird. Stellen Sie als Simulationsparameter Fixed-Step-Size ein und starten Sie die Simulation anschließend durch Aufruf von Start im Menü Simulation. Erhöhen Sie jetzt die Frequenz des Signalgenerators schrittweise um 1000 Hz, bis Sie 8 kHz erreicht haben. Beschreiben Sie, was passiert? 80
  • 80. Lösung: Da das Modell in einem der nächsten Termine nochmal benötigt wird, sollten Sie es abspei- chern. Rufen Sie hierzu aus dem Menü File den Speichern-Dialog auf und speichern Sie das Modell unter dem Namen Termin1V2.mdl ab. 2.7.6 (*)Versuch F: Grobquantisierung Um den Effekt der Quantisierung genauer zu untersuchen, soll ein Sprachsignal mit wach- sender Stufenhöhe quantisiert und akustisch ausgegeben werden. Ersetzen Sie den Signal Generator des Modells aus Versuch 2.7.5 durch einen Signal From Workspace-Block (DSP Blockset → DSP Sources). Stellen Sie im Einstellungsfenster als Variablenname signal2 ein, so dass als Eingang das Signal aus Versuch 2.7.1 verwendet wird (Achtung: wenn Sie den Blocks From Workspace aus Sources verwenden wollen, muss die Variable zusätzlich die Zeitbasis enthalten). Erweitern Sie das Modell außerdem mit einem Quantisierer (DSP Blockset → Quantizers), sowie einem Signal To Workspace-Block (DSP Blockset → Sinks). Dieser Ausgabeblock schreibt die Daten, die er empfängt, in die Matrix yout, auf die von MATLAB aus zugegrif- fen werden kann. Überlegen Sie sich, wo Sie den Block einstellen/anschließen müssen, um einen 1-dimensionalen Vektor der quantisierten Werte zu erhalten. Tragen Sie für die Simulationszeit einen Wert ein, so dass signal2 vollständig verarbeitet wird. Stellen Sie am Quantisierer nacheinander die Stufenhöhen 1/128, 1/16, 1/4 und 1/2 ein und lassen Sie sich yout jeweils akustisch mit der MATLAB-Funktion sound ausgeben. Isolieren Sie anschließend für die Stufenhöhen 1/128 und 1/4 in SIMULINK das Quanti- sierungsrauschen durch Differenzbildung des quantisierten Signals vom Originalsignal und Ausgabe ins MATLAB-Workspace durch einen weiteren Signal To Workspace-Block und bestimmen Sie das Signal-Rauschleistungsverhältnis in MATLAB. Achten Sie bei der Be- stimmung des SNR darauf, dass Sie den 10er-Logarithmus verwenden. 81
  • 81. Lösung: Signalleistung [dB] Störleistung [dB] SNR [dB] 1/128 1/4 2.7.7 (*)Versuch G: Amplitudenmodulation mit Hüllkurvenempfang Als Beispiel für ein komplexeres SIMULINK-Modell soll das Modell einer Übertragung durch Amplitudenmodulation mit Hüllkurvenempfang erstellt werden. Der Sender verän- dert dabei mit dem Nutzsignal s(k) die Amplitude A(k) der allg. Trägerschwingung. x(k) = A(k) · cos(Ω0 k + φ0 ) = (a0 + a1 · s(k)) · cos(Ω0 k + φ0 ) (2.13) Aus dieser noch sehr allgemeinen Form eines AM-Verfahrens (Gl. (2.13)) erhält man eine reine Zweiseitenband-Übertragung, indem a0 zu Null gewählt wird. Der Empfänger kann durch einen gewöhnlichen Hüllkurvenempfänger realisiert werden, wie Sie ihn in Abschnitt 2.6.4 der vorbereitenden Aufgaben bereits mit dem Hilbert-Transformator kennengelernt haben. Der Hüllkurvenempfänger hat den großen Vorteil, dass man auf Empfän- gerseite ohne Träger-Rückgewinnung auskommt. Ein Nachteil besteht jedoch darin, dass die Anwendung auf AM-Signale mit a0 ≥ max|a1 · s(k)| beschränkt ist. Andernfalls treten nichtlineare Effekte auf. Versuchen Sie, die Zweiseitenband-Übertragung mit Hüllkurvenempfang in einem SIMU- LINK-Modell umzusetzen. Hinweise: Allgemein Die Hilbert-Transformation ist eine zeitdiskrete Filterung. Daher sollten Sie das gesamte Modell zeitdiskret aufbauen. Versuchen Sie das Gesamtmodell durch ein schritt- weises Vorgehen zu realisieren, indem Sie zuerst ein Eingangssignal generieren, dann den Amplitudenmodulator erstellen und abschließend das modulierte Signal mit Hilfe des Hüll- kurvenempfängers decodieren. Eingangssignal Erzeugen Sie durch Kombination geeigneter diskreter Quellensignale ein Eingangssignal, das folgender Vorschrift gehorcht, und speichern Sie es als signal3.dbl ab 2 1 s(k) = · cos(Ω1 k) + · cos(2Ω1 k). (2.14) 3 3 82
  • 82. Stellen Sie hierbei die normierte Frequenz Ω1 so ein, dass sich für cos(Ω1 k) bei Normie- rung auf die Abtastrate von 8 kHz eine Schwingung von 250 Hz ergibt. Verifizieren Sie Ihr Eingangssignal, indem Sie sich mit Hilfe eines FFT Frame Scope- Blocks das Spektrum ansehen. Amplitudenmodulator Realisieren Sie nun den durch Gleichung (2.13) beschriebenen Amplitudenmodulator. Die Größen a0 und Ω0 sollten so gewählt werden, dass bei a1 = 1 und φ0 = 0 eine Modulationsfrequenz von 2 kHz eingestellt ist und nichtlinearen Effekte vermieden werden. Überprüfen Sie die Funktionalität Ihres Modulators, indem Sie sich neben dem Eingangs- signal s(k) auch das modulierte Signal x(k) mit Hilfe eines weiteren FFT Frame Scope- Blocks anschauen und zusätzlich die Modulationsfrequenz Ω0 variieren. Hüllkurvenempfänger Decodieren Sie nun das modulierte Signal x(k) mittels Hüllkurven- empfang. Ergänzen Sie hierzu das Modell um das in Abschnitt 2.6.4 entwickelte Block- schaltbild. Vergessen Sie nicht, anschließend den Gleichanteil a0 wieder abzuziehen. Die approximierte Stoßantwort eines Hilbert-Transformators erhalten Sie durch Aufruf der MATLAB- Funktion ind_hilbert(NH ) mit beispielsweise NH = 48 als Filter-Grad. Spei- chern Sie die Filter-Koeffizienten in einer Variablen und setzen Sie den Variablennamen als Zähler der Übertragungsfunktion im Einstellungsfenster des Filter-Blocks ein. Als Nen- ner tragen Sie „1“ ein. Gleichen Sie im oberen Zweig den durch Hilbert-Transformation hervorgerufenen Laufzeitunterschied von NH /2 mit Hilfe eines Delay- Blocks aus. Vergleichen Sie das demodulierte Ausgangssignal mit dem Eingangssignal, indem Sie sich beide Zeitsignale mit Scope- Blöcken ausgeben lassen. Neben der Einschwingphase des Hilbert-Transformators und dem zeitlichen Versatz von NH /2 Abtastwerten sollte keine weitere Verzerrung erkennbar sein. Speichern Sie das Modell als Termin1V4.mdl. Welcher nichtlinearer Effekt tritt im Ausgangssignal auf, wenn a0 zu Null gewählt wird? Lösung: 83
  • 83. Literaturverzeichnis [1] W. J. Hess. Digitale Filter. Teubner Verlag, Stuttgart, 2. Auflage, 1993. [2] J. Hoffmann. MATLAB und Simulink. Addison-Weslay Verlag, Bonn, 1998. [3] D. Kammeyer und K. Kroschel. Digitale Signalverarbeitung, Filterung und Spektral- analyse. Teubner Verlag, Stuttgart, 1989. [4] The Math Works Inc., Natick (Mass./USA). Matlab - User’s Guide, 1992. [5] A. Oppenheim und R. Schafer. Zeitdiskrete Signalverarbeitung. Oldenbourg Verlag, München, 3. Auflage, 1999. [6] P. Vary. Skipt zur Vorlesung Nachrichtensysteme I. Institut fü Nachrichtengeräte und Datenverarbeitung, RWTH Aachen, 1995. [7] P. Vary, U. Heute, und W. Hes. Digitale Sprachsignalverarbeitung. Teubner Verlag, Stuttgart, 1. Auflage, 1998. 84
  • 84. Kapitel 3 Diskrete Fourier-Transformation (DFT) 3.1 Einleitung In diesem Versuch möchten wir Sie mit der Diskreten Fourier-Transformation (DFT), ihrer effizienten Implementierung in Form der Schnellen Fourier-Transformation (FFT) und ih- ren speziellen Eigenschaften vertraut machen. Dazu werden im Folgenden die theoretischen Grundlagen der DFT kompakt zusammengefasst und der Einfluss der sog. Fensterung be- schrieben. 3.2 Theoretische Grundlagen 3.2.1 Definition und Eigenschaften der DFT Die Diskrete Fourier-Transformation (DFT) bildet die wesentliche Grundlage der digita- len Spektralanalyse. Es besteht ein enger Zusammenhang zur z-Transformation und der Fourier-Integral-Transformation (z.B. [2], [3]). Die DFT muss aber nicht notwendigerwei- se als Approximation der genannten Transformationen verstanden werden. Sie kann viel- mehr als eigenständige Abbildungsvorschrift interpretiert werden, die N möglicherweise komplexe Abtastwerte x(k) mit k = 0, 1, . . . N − 1 auf N komplexe Spektralwerte X(i) mit i = 0, 1, . . . N − 1 abbildet. Die eindeutig umkehrbare Transformation lautet: N−1 2π x(k) · e− j N ik DFT: X(i) = ; i = 0, 1, . . . N − 1 (3.1) k=0 N−1 1 2π X(i) · e+ j N ik IDFT: x(k) = ; k = 0, 1, . . . N − 1 (3.2) N i=0 IDFT bezeichnet dabei die inverse DFT. Ein wesentliches Merkmal dieser Transformation ist, dass sich sowohl bei der Hin- als auch der Rücktransformation periodische Folgen ergeben, wenn man die Indizierung auf den 85
  • 85. Bereich ±∞ erweitert. Es gilt DFT: X(i + l · N) = X(i) ; l = 0, ±1, ±2, . . . (3.3) IDFT: x(k + l · N) = x(k) ; l = 0, ±1, ±2, . . . (3.4) Diese Eigenschaf im Zeit- und Frequenzbereich lässt sich durch die Diskretisierung (Ab- tastung) in beiden Bereichen erklären. Für zeitkontinuierliche Signale ist die DFT durch die Diskretisierung im Allgemeinen fehlerbehaftet. Nur für den Sonderfall eines periodischen, bandbegrenzten Signals x(k) der Periodenlänge N kann mit Hilfe der DFT das Fourieinte- gral exakt berechnet werden. Wird die DFT nun zur Spektralanalyse eines Zeitsignals x(k) eingesetzt, welches durch Abtastung mit fA = 1/T erzeugt wurde, ist eine Normierung der Frequenzachse auf 2π nach Ω = 2π · f / fA (3.5) üblich. Die DFT liefert N äquidistante Spektralwerte für die normierten Frequenzen 2π Ωi = i ; i = 0, 1, . . . N − 1 (3.6) N im Bereich 0 ≤ Ω < 2π, was auf der unnormierten Skala 0 ≤ f < fA entspricht. Die spektrale Auflösung ist dann 2π ∆Ω = (3.7) . N Daraus kann man schließen, dass sich durch Vergrößern der Blocklänge N die Frequenzauf- lösung erhöhen lässt. Es ist jedoch zu beachten, dass dabei konsequenter Weise de zeitliche Auflösung abnimmt. Wenn das Zeitsignal x(k) rein reell ist, erhält man ein komplexes Spektrum mit den folgen- den Symmetrieeigenschaften: X(0) = rein reell N X = rein reell 2 X(i) = X ∗ (N − i) Das Spektrum kann demnach durch zwei reelle und N − 1 komplexe Werte beschrieben 2 werden. Die Menge der zu speichernden bzw. zu verarbeitenden Zahlen bleibt durch die Transformation unverändert. Weitere wesentliche Eigenschaften der DFT sind in Tabelle 3.1 zusammengefasst. 86
  • 86. Operation Eigenschaft N−1 2π x(k) · e− j N ik DFT X(i) = ; i = 0, 1, . . . , N − 1 k=0 N−1 2π 1 X(i) · e+ j N ik IDFT x(k) = ; k = 0, 1, . . . , N − 1 N i=0 Linearität DFT{a · x(k) + b · y(k)} = a · X(i) + b · Y(i) 2π DFT{ x(k + m)} = X(i) · e+ j N im Zeitverschiebung ˜ ; m ∈ {0, ±1, . . .} 2π ˜ DFT{x(k) · e+ j N mk } = X(i − m) Modulation N−1 1 ˜ Multiplikation DFT{x(k) · y(k)} = X(ρ) · Y(i − ρ) N ρ=0 N−1 Faltung IDFT{X(i) · Y(i)} = x(ρ) · y(k − ρ) ˜ ρ=0 Tabelle 3.1: Eigenschaften der Diskreten Fourier-Transformation (DFT) für ˜˜˜˜ Folgen x(k), y(k) der Länge N ( x, X, y, Y = periodische Fortset- zungen von x, X, y, Y) Die Zahl der spektralen Werte der DFT ist nicht notwendigerweise an die Länge des Si- gnals bzw. des Signalausschnitts gekoppelt. Bei einer vorgegebenen Signallänge L erhält man zusätzliche Werte im Frequenzbereich, indem das Zeitsignal durch Nullwerte künst- lich verlängert wird. Dieses als zero padding oder Zoom-DFT bekannte Verfahren wird in Abbildung 3.1 dargestellt. Durch zero padding wird das ursprüngliche Spektrum interpo- liert, aber die Auflösung harmonischer Anteile im Zeitsignal nicht verbessert. 3.2.2 Fensterfunktionen Zur Spektralanalyse wird die DFT jeweils auf einen N Abtastwerte umfassenden Signal- ausschnitt angewendet. Man bezeichnet diese Vorgehensweise auch als Kurzzeitspektral- analyse. Der N Abtastwerte umfassende Abschnitt stellt das Zeitfenster der DFT dar. Das resultierende (Kurzzeit-)Spektrum lässt verschiedene, aber äquivalente Interpretationen zu: • Unschärferelation: Aufgrund des endlich langen Zeitausschnitts ist auch die Spektralauflösung begrenzt. Das DFT-Kurzzeit-Spektrum kann daher nur in Sonderfällen mit dem Spektrum des gesamten Signals übereinstimmen. 87
  • 87. Abbildung 3.1: Interpolation des Spektrums durch Einfügen von Nullwer- ten a) N = L = 10 ⇒ ∆Ω = π5 π b) N = L + 10 = 20 ⇒ ∆Ω = 10 • z-Transformation einer endlich langen Folge Formal stimmt die DFT mit der z-Transformation einer Signalfolge der endlichen 2π Dauer N für z = e j N i mit i = 0, 1, . . . N − 1 überein. Damit liefert die DFT für N äquidistante Frequenzen das “wahre” Spektrum des zeitlich begrenzten bzw. gefens- terten Signals. Dieses Spektrum wird also “abgetastet”. Zwischen den Abtastpunkten ist dieses Spektrum i.a. von Null verschieden. • Periodische Fortsetzung Die Rücktransformation des DFT-Spektrums liefert ein periodisch fortgesetztes Zeit- signal. Nach dieser Interpretation stimmt das DFT-Spektrum mit dem “wahren” Li- nienspektrum des periodischen Signals überein, wobei das Linienspektrum zwischen den spektralen Abtastwerten verschwindet. Bei der periodischen Wiederholung des Zeitfensters kann es an den Fenstergrenzen je nach Signalform zu Unstetigkeitsstellen (Sprüngen) kommen, die das Ergebnis der DFT mehr oder weniger stark verändern. Im Spektrum tauchen als Folge dieser Uns- tetigkeitsstellen Frequenzanteile auf, die in dem zu analysierenden Signal (im Sinne des Langzeitspektrums) nicht vorhanden sind. Diesen Effekt nennt man Leckeffekt (engl.: spectral leakage, s.u). 88
  • 88. Alle drei Interpretationen sind gültig und widersprechen sich nicht. Insgesamt ist festzu- stellen, dass der Fenstereffekt zu berücksichtigen ist, wenn die DFT zur Schätzung des Langzeit-Spektrums herangezogen wird. Nur in den Sonderfällen eines Signals der Länge L ≤ N oder eines Signals mit der Periodenlänge P gemäß l · P = N (l ganzzahlig) besteht exakte Übereinstimmung. Die Multiplikation des Analysesignals mit einer Fensterfunktion entspricht im Frequenz- bereich einer Faltung der Diskreten Fourier-Transformierten des Analysesignals mit dem Spektrum der Fensterfunktion: w(k) : Fensterfunktion W(i) : Spektrum der Fensterfunktion x(k) : Analysesignal X(i) : Spektrum des Analysesignals x′ (k) = x(k) · w(k) (3.8) ′ X (i) = X(i) ∗ W(i), (3.9) wobei x′ (k) das mit der Fensterfunktion gewichtete Analysesignal bezeichnet. Der Leckef- fekt wird in Abbildung 3.2 für ein sinusförmiges Signal dargestellt. Im ersten Fall stimmt die Signalperiode mit der Transformationslänge überein (P = N), während im zweiten Fall N < P < 2N gilt. Abbildung 3.2: Erläuterung des Leckeffektes im Zeit- und Frequenzbereich für ein sinusförmiges Signal a) Signalperiode P = N b) Signalperiode N < P < 2N Obwohl in beiden Fällen ein sinusförmiges Signal vorliegt, zeigt nur das erste Spektrum ei- ne einzelne Spektrallinie. Im zweiten Spektrum ist der Einfluss des Rechteckfensters deut- lich sichtbar. Der Leckeffekt lässt sich abmindern, indem man das Zeitfenster mit einer geeigneteren Fensterfunktion multipliziert. 89
  • 89. Die wichtigsten Fensterfunktionen werden in Abbildung 3.3 und Abbildung 3.4 dargestellt. Es ist anzumerken, dass die spektralen Verläufe in Abbildung 3.3 mit einer gegenüber der Signallänge N wesentlich erhöhten Auflösung berechnet wurden (zero padding, N ′ = 512). Fensterfunktionen lassen sich durch eine Reihe charakteristischer Parameter beschreiben. Die wichtigsten Parameter sind dabei die Nebenzipfeldämpfung und die 3-dB-Grenze. Nebenzipfeldämpfung Hierunter versteht man die Differenz der Amplituden von Hauptmaximum und höchstem Nebenmaximum im Spektrum der Fensterfunktion. Die Nebenzipfeldämpfung ist ein Kri- terium für die Dämpfung im Sperrbereich. Sie wird in dB angegeben. 3-dB-Grenze Die 3-dB-Grenze, auch die spektrale Breite einer Fensterfunktion genannt, beschreibt die Breite des Hauptmaximums im Spektrum der Fensterfunktion. Bei der Analyse von Signa- len mit mehreren harmonischen Komponenten ist die 3-dB-Grenze ein Maß für die Fre- quenzselektivität, d.h. für die Auflösung dicht benachbarter harmonischer Komponenten. Die Angabe erfolgt dabei in Vielfachen der reziproken Fensterbreite 1/N. Fensterfunktion Höchster Nebenzipfel in dB 3-dB-Grenze /(2π/N) mit N = 33 Rechteck 0.89 −13 Bartlett (Dreieck) 1.28 −27 Hanning 1.30 −32 Hamming 1.44 −43 Blackman 1.68 −58 Kaiser (α = 3) 1.17 −25 Zwischen der Frequenzselektivität (3-dB-Grenze) und der Nebenzipfeldämpfung besteht eine Unschärferelation. Entweder besitzt die Spektralfunktion des Fensters ein schmales Hauptmaximum oder die Nebenzipfel sind stark abgeschwächt. Daher ist es nicht möglich, ein Fenster zu entwerfen, welches für alle Anwendungen der DFT optimal geeignet ist. Man sollte daher beim Fenster-Design einen für die jeweilige Anwendung möglichst guten Kompromiss finden. 90
  • 90.  1 ; k = 0, 1, . . . , N − 1  Rechteckfenster: w(k) =    0 ; sonst 0 w(k) 20*lg | W | |W(Ω)| / dB → w(k) → 1 −10 −20 0.8 −30 0.6 −40 0.4 −50 0.2 −60 0 −70 0 5 10 15 20 25 30 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 Ω/π →1 k→   2k/(N − 1) ; k = 0, 1, . . . , (N − 1)/2  Dreieckfenster: w(k) =  ,N ungerade    w(N − 1 − k) ; k = (N − 1)/2, . . . , (N − 1) 0 w(k) 20*lg | W | |W(Ω)| / dB → w(k) → 1 −10 −20 0.8 −30 0.6 −40 0.4 −50 0.2 −60 0 −70 0 5 10 15 20 25 30 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 Ω/π →1 k→ Hanning-Fenster: w(k) = 0.5 − 0.5 cos(2πk/(N − 1)) 0 w(k) 20*lg | W | |W(Ω)| / dB → w(k) → 1 −10 −20 0.8 −30 0.6 −40 0.4 −50 0.2 −60 0 −70 0 5 10 15 20 25 30 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 Ω/π →1 k→ Abbildung 3.3: Gegenüberstellung einiger Fensterfunktionen 91
  • 91. Hamming-Fenster: w(k) = 0.54 − 0.46 cos(2πk/(N − 1)) 0 w(k) 20*lg | W | |W(Ω)| / dB → w(k) → 1 −10 −20 0.8 −30 0.6 −40 0.4 −50 0.2 −60 0 −70 0 5 10 15 20 25 30 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 Ω/π →1 k→ Blackman-Fenster: w(k) = 0.42 − 0.5 cos(2πk/N − 1)) + 0.08 cos(4πk/(N − 1)) 0 w(k) 20*lg | W | |W(Ω)| / dB → w(k) → 1 −10 −20 0.8 −30 0.6 −40 0.4 −50 0.2 −60 0 −70 0 5 10 15 20 25 30 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 Ω/π →1 k→ k I0 (α 1−(1− β )2 ) Kaiser-Fenster: w(k) = I0 (α) I0 : Modifizierte Besselfunktion erster Art der Ordnung Null, α: Formparameter, β = (N − 1)/2 0 w(k) 20*lg | W | |W(Ω)| / dB → w(k) → 1 −10 −20 0.8 −30 0.6 −40 0.4 −50 0.2 −60 0 −70 0 5 10 15 20 25 30 0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 Ω/π →1 k→ Abbildung 3.4: Gegenüberstellung einiger Fensterfunktionen (Fortsetzung) 92
  • 92. 3.2.3 Schnelle Fourier-Transformation (FFT) Als Schnelle Fourier-Transformation werden Algorithmen zur aufwandsgünstigen Berech- nung der DFT bezeichnet. Das wesentliche Aufwandskriterium ist dabei die Anzahl der Multiplikationen. Die direkte Berechnung einer DFT der Länge N erfordert ZDFT = N 2 komplexe Multiplikationen. Durch geschickte Organisation der Rechenschritte lassen sich Algorithmen entwickeln, die einen erheblich geringeren Rechenaufwand erfordern und da- mit die Berechnung wesentlich schneller ausführen. Die Algorithmen beruhen auf einer Zerlegung der Summe über N Werte in Teilsummen kür- zerer Länge. Dies führt auf Untertransformationen einer kürzesten Länge, die als “Radix” des Algorithmus bezeichnet wird (z.B. [2]-[1]). Im Praktikum wird eine Radix-2 FFT verwendet, d.h. die Transformationslänge ist eine Zweierpotenz. Für diesen Algorithmus beträgt der relative Rechenaufwand (gemessen in komplexen Multiplikationen und Additionen) im Vergleich zur DFT (z.B. [5]): ZFFT ld(N) = (3.10) . ZDFT 2·N Bei einer Transformationslänge von N = 1024 ergibt sich somit eine Reduktion des Re- chenaufwandes um 99.5%. 3.2.4 Schnelle Faltung Die direkte (lineare bzw. aperiodische) Faltung eines Signals x(k) der Länge L mit einer Impulsantwort h(k) der Länge n ist gegeben durch n−1 y(k) = h(i) · x(k − i) = h(k) ∗ x(k). (3.11) i=0 Die resultierende Folge y(k) besitzt die Länge m = L + n− 1, somit erfordert die Berechnung der Ausgangsfolge y insgesamt m · n Multiplikationen. Dieser Aufwand lässt sich je nach Dimensionierung von L und n durch den Einsatz der FFT und durch Ausführung der Filte- rung im Frequenzbereich u.U. erheblich reduzieren. Die Vorgehensweise ist in Abbildung 3.5 skizziert. Abbildung 3.5: Prinzip der schnellen Faltung: −→ = reell, =⇒ = komplex Diese Anordnung realisiert die sogenannte zyklische Faltung (s. auch Tabelle 3.1), da die 93
  • 93. Rücktransformierte y(k) = IDFT{X(i) · H(i)} ˜ (3.12) als periodische Funktion mit der Periodenlänge N zu interpretieren ist. Um das gewünschte Faltungsergebnis zu erzielen, muss die Transformationslänge derart gewählt werden, dass gilt N ≥ L + n − 1, (3.13) d.h. die Folgen x(k) und h(k) sind vor der Transformation mit entsprechend vielen Nullwer- ten aufzufüllen. In der Praxis ist die Signalfolge x(k) beliebig lang, so dass das Verfahren in der beschrie- benen Form nicht angewendet werden kann. Wegen der Linearität der Faltungsoperati- on kann jedoch das Signal x(k) in Segmente der Länge L aufgeteilt werden, die nach separater schneller Faltung zeitrichtig überlagert werden. Dieses Verfahren wird deshalb Überlappungs-Summen-Methode (engl.: overlap add) genannt. Mit der Bezeichnung   x(k) ; λ · L ≤ k < (λ + 1) · L  xλ =  (3.14)   0 ; sonst gilt: x(k) = xλ (k) (3.15) λ y(k) = x(k) ∗ h(k) = xλ (k) ∗ h(k). (3.16) λ Aus dieser Beziehung lässt sich das Verfahren unmittelbar ableiten. Ein Beispiel ist in Ab- bildung 3.6 dargestellt. Neben der Überlappungs-Summen-Methode existiert eine alternative Realisierung der schnel- len Faltung, die sog. Überlappungs-Selektions-Methode (engl.: overlap save) (z.B. [2], [3], [4], [5]). Dabei wird die Eingangsfolge in einander überlappende Segmente zerlegt und aus den zyklischen Faltungsprodukten werden nur die Abschnitte herausgegriffen, die mit der linearen Faltung übereinstimmen. Nimmt man als Maß für den Rechenaufwand die Zahl der Multiplikationen pro Ausgangs- wert, dann erfordert die schnelle Faltung mit z.B. N = 128 bereits bei n = 22 einen gerin- geren Aufwand als die direkte Faltung [4]. Es ist anzumerken, dass die Zahl der Multiplikationen nur einen groben Anhaltspunkt für die benötigte Rechenzeit gibt. Der Zeitaufwand für die Adressierung und die Speicherzu- griffe ist bei einem exakten Vergleich mit zu berücksichtigen. Damit ist eine vergleichende Aussage stark von der verwendeten Prozessorarchitektur abhängig. Es zeigt sich, dass bei Verwendung moderner Signalprozessoren die direkte Faltung noch bei wesentlich höheren Werten von n der schnellen Faltung vorzuziehen ist, da die Architektur dieser Prozessoren sehr effizient die Berechnung von Skalarprodukten unterstützt (s. Termin 4). 94
  • 94. Weiterhin ist festzustellen, dass der Speicheraufwand für die schnelle Faltung u.U. deutlich größer ist als für die direkte Faltung und dass aufgrund der Blockverarbeitung die schnelle Faltung eine größere Signalverzögerung bewirkt. 95
  • 95. Abbildung 3.6: Beispiel zur schnellen Faltung nach der Overlap-Add- Methode mit L = 5, n = 3, N ≥ 8 96
  • 96. 3.3 Vorbereitende Aufgaben Die vorbereitenden Aufgaben sind zu Hause vollständig zu lösen. 3.3.1 Aufgabe I Berechnen Sie für die gegebene Abtastfolge x(k) eine DFT der Länge N = 4 nach Real- und Imaginärteil. x(k) = {x(0), x(1), x(2), x(3)} = {100, 200, −100, 100}. Lösung: 97
  • 97. 3.3.2 Aufgabe II Zeigen Sie, dass sich zwei reelle Zeitsignale x(k) und y(k) der Länge N gemeinsam mit einer DFT der Länge N in den Frequenzbereich transformieren lassen, indem beide Signale zu einem komplexen Signal z(k) = x(k) + j y(k) zusammenfasst werden. Lösung: 3.3.3 Aufgabe III Berechnen Sie für die vorgegebenen Folgen x(k) die Diskrete Fourier-Transformierte X(i) = DFT{x(k)} sowie den Betrag |X(i)|. Die Transformationslänge beträgt N = 16. Skizzieren Sie in den vorbereiteten Diagrammen |X(i)| bzw. Re{X(i)} und Im{X(i)} als dis- krete Linien. Hinweis: Es genügt die Form der kontinuierlichen Einhüllenden des Linienspektrums anzu- geben. Eine exakte numerische Berechnung der Spektralwerte ist nicht erforderlich. 98
  • 98. 1. Einzelimpuls bei k0 = 2 Welchen Einfluss hat k0 auf die Zahl der Perioden im Spektrum? 2. Rechteck 3. Exponentialfolge: x(k) = e jΩ0 k ; Ω0 = π/4 4. Kosinus 1: x(k) = cos(W0 · k) ; W0 = π/4 99
  • 99. 5. Kosinus 2: x(k) = cos(W0 · (k − k0 )) ; W0 = π/4 k0 = 1 Welchen Einfluss hat k0 ? 100
  • 100. 3.4 Versuchsdurchführung Die mit (*) gekennzeichneten Versuche sind nur zur Vertiefung des Stoffs gedacht und kön- nen weggelassen werden, falls die zur Verfügung stehende Zeit nicht ausreicht. 3.4.1 Versuch A: DFT spezieller Signale Erzeugen Sie in MATLAB das Signal x(k) der Länge N = 64 mit   1 k=k 0  x(k) = γ0 (k − k0 ) =  (mit γ0 = Einheitsimpuls)    0 sonst für k0 = 0, 1, 2 und binden Sie dieses mit Hilfe des Signal from Workspace-Blockes in ein SIMULINK Modell ein. Lassen Sie sich sowohl den Betrags- |X(Ω)| und Phasengang arg{X(Ω)} als auch die Verläufe von Real- und Imaginärteil grafisch ausgeben. Das reelle Signal x(k) kann mit dem Block FFT, der unter DSP-Blockset ⇒ Transforms zu finden ist, in den Frequenzbereich transformiert werden. FFT erfordert einen Vektor am Eingang, so dass das serielle Zeitsignal x(k) mit Hilfe eines DSP-Blockset ⇒ ⇒ Signal Ma- nagemenet ⇒ Buffers in einen Vektor gewandelt werden muss. Um schließlich den Betrags- |X(Ω)| und Phasengang arg{X(Ω)} bzw. Real- und Imaginärteil mit Time Frame Scope- Blöcken grafisch ausgeben zu können, müssen die komplexwertigen Fourier-Koeffizienten X(Ωi ) mit dem entsprechenden Block in Betrag und Phase bzw. Real- und Imaginänteil (Simulink ⇒ Math Operations) zerlegt werden. Überlegen Sie sich, welche Simulations- und Block-Parameter zu verwenden sind. Führen Sie die Simulation auch mit folgenden Eingangsvektoren durch, wobei N die Länge eines zu transformierenden Vektors bezeichnet: 2πn x(k) = cos(Ω0 k) mit Ω0 = , n = 1, 2, ... N 2πn x(k) = cos(Ω1 k) mit Ω1 , n = 1, 2, ... N Erklären Sie die Betrags- und Phasenspektren bzw. die Verläufe der Real- und Imaginärteile. Lösung: 101
  • 101. 3.4.2 Versuch B: Zero-Padding Laden Sie das SIMULINK-Modell Termin1V2.mdl, das Sie beim letzten Termin gespei- chert haben. Fügen Sie dem Modell jetzt an einer dafür geeigneten Stelle ein DSP-Blockset ⇒ Zero-Pad- Modul aus der Bibliothek hinzu. Berechnen Sie für das Signal signal1, das Sie ebenfalls beim letzten Termin erzeugt und gespeichert haben, eine FFT der Länge 16. Erhöhen Sie dann die FFT-Länge, indem Sie das Signal mittels zero padding auf 32, 64 und 512 Werte erweitern und die Anzahl der FFT-Koeffizienten dementsprechend ändern. Skizzieren Sie qualitativ die Ergebnisse. Lösung: 3.4.3 Versuch C: Fensterung und Leckeffekt Zur Demonstration des Leckeffekts sollen Sinussignale mit verschiedenen Frequenzen in den Frequenzbereich transformiert werden. Verwenden Sie dazu wieder das SIMULINK-Modell Termin1V2.mdl. Der Sinus Genera- tor-Block bietet hierbei eine einfache Möglichkeit, die Frequenz des erzeugten Signals zu verändern. Stellen Sie als Eingangssignal eine Sinusfunktion mit der Frequenz f = 500 Hz ein. Füh- ren Sie eine Fensterung der erzeugten Vektoren mit Hilfe des Signal Operations, Window Function- Block durch, wobei zunächst als Fensterfunktion die Rechteckfunktion verwen- det werden soll. Lassen Sie sich im logarithmischen Maßstab die FFT-Transformierte mit N = 512 Werten grafisch ausgeben. Vergleichen Sie das Ergebnis mit der FFT-Transformierten eines Sinussignals mit f = 510 Hz. Führen Sie die beiden Simulationen jetzt mit der Hanning-Fensterfunktion aus und verglei- chen und deuten Sie insbesondere die Ergebnisse 102
  • 102. • 500 Hz, Rechteck ←→ 510 Hz, Rechteck • 500 Hz, Rechteck ←→ 500 Hz, Hanning • 510 Hz, Rechteck ←→ 510 Hz, Hanning. 3.4.4 Versuch D: Schnelle Faltung mittels overlap add Verfahren Eine aufwandsgünstige Filterung eines beliebig langen Signals kann beispielsweise reali- siert werden, indem eine schnelle Faltung mittels Überlappungs-Summen-Verfahren (engl. overlap add) durchgeführt wird (siehe Abschnitt 3.2.4). Dimensionieren Sie die einzelnen Block-Parameter des bereits auf Festplatte vorliegenden Modells Termin2V6_Vorgabe derart, dass die im folgenden beschriebenen Randbedingun- gen eingehalten werden. Hinweise: Bestimmen Sie zunächst die Einstellungen der Blöcke Signal from Workspace und Gain. Hierzu ist bekannt, dass als Eingangssignal das mit 8 kHz abgetastete Sprachsignal signal2.dbl (siehe Termin 1) vorgesehen ist. Die Parameter der Blöcke Buffer, Window Function und Zero Pad können anschließend mit folgenden Zusatzinformationen angegeben werden. Mit Hilfe des Buffer-Blockes werden M Abtastwerte zu Verarbeitungsrahmen1 zusammengefasst, so dass nach Verdoppeln der Rahmenlänge mittels zero padding die FFT-Länge N = 2 · M erreicht wird. Zusätzlich ist eine Gewichtung der einzelnen Sprachrahmen mit einem Hamming-Fenster sinnvoll, was jedoch eine Überlappung aufeinanderfolgender Rahmen um M/2 Abtastwerte erfordert. Zur zeitrichtigen Überlagerung ist der Block Overlap Add vorgegeben. Hierin wird berück- sichtigt, dass aufgrund der Überlappung aufeinanderfolgender Rahmen um M/2 Abtastwer- te und aufgrund einer Rahmenlänge von N = 2 · M nach IFFT Teilvektoren von insgesamt 4 benachbarten Rahmen zum Ausgangssignal der Länge N/4 beitragen. Abschließend soll das verarbeitete Sprachsignal in eine Variable im MATLAB Workspace abgelegt werden. Beach- ten Sie bei den Simulationsparametern, dass das gesamte Sprachsignal signal2 verarbeitet wird. 1 Ein Vektor der Dimension M entspricht einem Verarbeitungsrahmen der Länge M. 103
  • 103. Zunächst wird die Variable fCoeffs, mit der das Signal im Frequenzbereich multipliziert wird, so gewählt, dass das Eingangssignal nicht verändert wird. Vergleichen Sie das Ergeb- nis ausgang mit dem Eingangssignal input. Wie erklären Sie sich die Unterschiede? Nun wird das Signal mit einem Halbbandfilter bearbeitet. Die Charakteristik der Übertra- gungsfunktion ist in Abbildung 3.7 dargestellt. Lassen Sie sich das Ausgangssignal akus- tisch ausgeben. Welche spektrale Färbung des Ausgangssignals vermittelt der Höreindruck im Vergleich zum Eingangssignal? Schließlich wird mit der schnellen Faltung ein Tiefpassfilter nach 3.8 implementiert. Lassen Sie sich das Ausgangssignal wiederum ausgeben und erklären Sie den Höreindruck. Lösung: 104
  • 104. Halbband−Filter (linear) 2 1.5 1 H( Ω) 0.5 0 −0.5 0 0.5 1 1.5 2 2.5 3 Ω Abbildung 3.7: Halbbandfilter Tiefpassfilter 2 1.5 1 H(Ω) 0.5 0 −0.5 0 0.5 1 1.5 2 2.5 3 Ω Abbildung 3.8: Tiefpassfilter 105
  • 105. 3.4.5 Versuch E: FFT auf dem DSP Berechnen Sie eine FFT auf dem DSP. Suchen Sie im Run-Time Library Manual for SHARC Processors, welche Funktion für Ihre Zwecke geeignet ist. Transformieren Sie einen Kanal des Eingangssignals in den Frequenzbereich (FFT) und direkt wieder in den Zeitbereich (IFFT). Verifizieren Sie Ihre Umsetzung mit dem MATLAB-Debugger und überlegen Sie, ob Ihre Umsetzung so effizient wie möglich ist. 3.4.6 (*)Versuch F: Gemeinsame Transformation zweier reeller Signale Erstellen Sie ein SIMULINK-Modell, mit dem die DFT zweier reeller Zeitsignale gemein- sam berechnet werden kann (siehe vorbereitende Aufgabe 3.3.2). Laden Sie zunächst das unvollständige Modell Termin2V4_Vorgabe.mdl sowie die Signa- le signal4.dbl in die Variable input_x und signal5.dbl in input_y ein. Starten Sie die Simulation, wobei als Stoppzeit der Wert 512/8000 (Signallänge: 512, Abtastrate: 8 kHz) eingestellt und im Workspace eine Variable size zu 512 gesetzt werden sollte. Im oberen Pfad des Modells wird das Signal input_x mit einer FFT der Länge size in den Frequenzbereich transformiert. Die Fourier-Koeffizienten werden anschließend in Form des Real- und des Imaginärteils ausgegeben. Der untere Pfad berechnet analog die Anteile des Signals input_y. Um welche Signale handelt es sich und wie kann aus der Symmetrie des Zeitsignals auf die Spektralanteile geschlossen werden? Lösung: Beide Signale sollen nun gemeinsam mit nur einer FFT in den Frequenzbereich transpo- niert werden. Ergänzen Sie das Modell, indem Sie das in der vorbereitenden Aufgabe 3.3.2 hergeleitete Verfahren implementieren. Um aus dem Real- bzw. Imaginärteilen der Fourier-Koeffizienten des komplexen Zeitsignals die Real- bzw. Imaginärteile der Fourier-Koeffizienten der beiden reellen Zeitsignale zu gewinnen, steht in der Bibliothek library_praktikum.mdl der Block split complex DFT zur Verfügung. Verifizieren Sie Ihr Modell (speichern als Termin2V4.mdl), indem Sie die nun gelieferten Ausgaben mit denen des ursprünglichen Systems Termin2V4_Vorgabe.mdl vergleichen. Verwenden Sie auch die unsymmetrischen Signale signal6 und signal7 zur Kontrolle Ihres Systems. 106
  • 106. 3.4.7 (*)Versuch G: Analyse von Signalen mit diskr. spektr. Komponenten In der Praxis tritt häufig das Problem auf, dass periodische Signalanteile in verrauschten Signalen detektiert werden müssen. Dabei kann es vorkommen, dass Signalanteile mit sehr verschiedenen Amplituden und geringem Frequenzabstand auftreten, so dass der Signalan- teil mit der größeren Amplitude den Signalanteil mit der geringeren Amplitude bei Wahl einer Fensterfunktion mit zu geringer Selektivität verdeckt. Die vorgegebene Datei signal8.dbl enthält ein aus mehreren überlagerten Sinusschwin- gungen verschiedener Frequenz zusammengesetztes Signal. Aufgabe ist es, alle enthaltenen Schwingungen durch den Einsatz verschiedener Fensterfunktionen nach Frequenz und Am- plitude zu bestimmen. Lesen Sie in MATLAB das File signal8.dbl in die Variable signal8 ein. Modifizieren Sie das SIMULINK-Modell Termin1V2.mdl so, dass Sie eine FFT auf signal8 anwenden und verschiedene Fensterfunktionen testen können. Probieren Sie in diesem Versuch alle zu Verfügung stehenden Fensterfunktionen aus. Lassen Sie sich das Ergebnis jeweils grafisch ausgeben. Aus wievielen überlagerten Sinus-Schwingungen besteht signal8? Welche Frequenz und welche Amplitude (in dB) besitzen die Sinus-Signale? Welche Fensterfunktionen sind besonders zum Detektieren nahe beieinanderliegender bzw. im Pegel sehr verschiedener Frequenzen geeignet? Lösung: 107
  • 107. Literaturverzeichnis [1] E. O. Brigham. FFT - Schnelle Fourier-Transformation. Oldenbourg Verlag, München, 1995. [2] D. Kammeyer und K. Kroschel. Digitale Signalverarbeitung, Filterung und Spektral- analyse. Teubner Verlag, Stuttgart, 1989. [3] A. Oppenheim und R. Schafer. Zeitdiskrete Signalverarbeitung. Oldenbourg Verlag, München, 3. Auflage, 1999. [4] H. W. Schüßler. Digitale Signalverarbeitung Band I: Analyse diskreter Signale und Systeme. Springer Verlag, 1988. [5] P. Vary, U. Heute, und W. Hes. Digitale Sprachsignalverarbeitung. Teubner Verlag, Stuttgart, 1. Auflage, 1998. 108
  • 108. Kapitel 4 Digitale FIR- und IIR-Filter 4.1 Einleitung Digitale Filter in nichtrekursiver und rekursiver Form sind das am häufigsten eingesetzte Werkzeug zur Bearbeitung digitaler Signale. Ziel diese Versuchs ist es, ihre Funktionsweise zu verstehen und die Probleme zu erkennen, die bei ihrem Einsatz auftreten können. 4.2 Beschreibung linearer zeitdiskreter Systeme In diesem Versuch werden digitale Filter behandelt, die als lineare zeitdiskrete Systeme zu betrachten sind. Der Zusammenhang zwischen dem Eingangssignal x(k), dem Ausgangs- signal y(k) und der Impulsantwort h(k) des Filters (siehe Abbildung 4.1) ist durch die mit dem Symbol „∗“ bezeichnete Faltungsoperation zu beschreiben. Es gilt ∞ y(k) = h(i) · x(k − i) (4.1) i=−∞ = h(k) ∗ x(k). (4.2) x(k) y(k) h(k) Abbildung 4.1: Blockdiagramm eines digitalen Filters mit der Impulsant- wort h(k). Eine alternative Beschreibung liefert die Differenzengleichung m n y(k) = bi · x(k − i) − ci · y(k − i) (4.3) i=0 i=1 mit den konstanten Koeffizienten bi und ci . Die größere der beiden Zahlen n und m wird als Ordnung der Differenzengleichung bzw. des Filters bezeichnet. Die vordere Summe beschreibt dabei den nicht-rekursiven Anteil, die hintere Summe den rekursiven Anteil des durch die Differenzengleichung (4.3) dargestellten Filters. 109
  • 109. Die Impulsantwort h(k) lässt sich mit Gleichung (4.3) bestimmen, wenn wir das Eingangs- signal x(k) gleich dem Einheitsimpuls δ(k) setzen.  1 ; k=0  x(k) = δ(k) =  (4.4)   0 ; sonst Ist die Länge von h(k) unendlich, was für reale Systeme im Allgemeinen der Fall ist, be- zeichnet man das Filter als IIR-Filter (IIR = Infinite Impulse Response). Eine endlich lange Impulsantwort ergibt sich für den Spezialfall eines rein nicht-rekursiven Systems, d.h. für ci = 0 mit i = 1, . . . n. Ein solches System nennt man ein FIR-Filter (FIR = Finite Im- pulse Response). Die Impulsantwort besitzt die Länge L = m + 1 und die Differenzenglei- chung (4.3) reduziert sich auf m m y(k) = h(i) · x(k − i) = bi · x(k − i). (4.5) i=0 i=0 Neben dem Faltungsprodukt und der Differenzengleichung ist die Darstellung des Filters als Übertragungsfunktion H(z), d.h. der z-Transformierten der Differenzengleichung von Bedeutung. Die Übertragungsfunktion eines IIR-Filters lautet damit m bi · z−i Y(z) i=0 H(z) = = mit c0 = 1. (4.6) n X(z) ci · z−i i=0 Für die Übertragungsfunktion eines FIR-Filters folgt m bi · z−i . H(z) = (4.7) i=0 Den Frequenzgang erhält man für z = e jΩ mit Ω = 2π f / fA und der Abtastfrequenz fA . Hierbei ist H(e jΩ ) eine in 2π periodische Funktion. Sie wird meist nach Betrag |H(e jΩ )| und Phase ϕ(Ω) dargestellt. H(e jΩ ) = |H(e jΩ )| · e− jϕ(Ω) (4.8) Die Ableitung des Phasengangs wird als Gruppenlaufzeit τg (Ω) bezeichnet dϕ(Ω) τg (Ω) = (4.9) . dΩ Für bestimmte Betrachtungen ist es günstig, die Übertragungsfunktion nach Gleichung (4.6) in faktorisierter Form, d.h. durch ihre Pol- und Nullstellen z∞i respektive z0i anzugeben: m (z − z0i ) i=1 H(z) = (4.10) n (z − z∞i ) i=1 110
  • 110. Aus der Lage der Pol- und Nullstellen kann auf die Eigenschaften des Filters geschlossen werden. Ein Beispiel ist in Abbildung 4.2 für ein System 2. Ordnung mit = e± j2π/3 z01,2 = 0.75 · e± jπ/3 z∞1,2 dargestellt. Pol- und Nullstellen der Übertragungsfunktion sind im Frequenzgang deutlich zu erkennen. Abbildung 4.2: Beispiel eines Systems zweiter Ordnung [10] a) Pol-Nullstellen-Diagramm b) Betragsfrequenzgang c) Phasengang d) Gruppenlaufzeit 4.3 FIR-Filter 4.3.1 FIR-Filter mit linearer Phase Von besonderem Interesse sind Filter mit linearer Phase, so dass sie eine konstante Grup- penlaufzeit aufweisen. Diese Filter beeinflussen lediglich das Amplitudenspektrum eines Signals. Das Phasenspektrum wird bis auf einen additiven linearen Term (konstante Verzö- gerung) nicht verändert. Aus der Forderung nach konstanter Gruppenlaufzeit resultieren Einschränkungen bezüglich der möglichen Nullstellenlagen. Dies führt schließlich auf eine Koeffizientensymmetrie der Form h(k) = ±h(m − k) ; k = 0, 1, . . . m. (4.11) 111
  • 111. Die Zusammenhänge, die in [10] und [4] ausführlich dargestellt werden, sollen hier nur grob skizziert werden. Für die Übertragungsfunktion eines allgemeinen nichtrekursiven Filters gilt nach Gleichungen (4.7) und (4.10) mit m = n n (z − z0i ) n 1 i=1 n−i H(z) = n h(i) · z = (4.12) . zn z i=0 Die Beiträge der n-fachen Polstelle bei z = 0 zur Phase und zur Gruppenlaufzeit lauten: ϕ∞ (Ω) = n · Ω (4.13) τg∞ (Ω) = n. (4.14) Die einzelnen Nullstellen z0i = ρi · e jψi (4.15) liefern die folgenden Beiträge sin Ω − ρi sin ψi ϕ0i (Ω) = − arctan (4.16) cos Ω − ρi cos ψi dϕ0i (Ω) τg0i (Ω) = dΩ 1 − ρi cos(Ω − ψi ) =− (4.17) . 1 − 2ρi cos(Ω − ψi ) + ρ2 i Die gesamte Gruppenlaufzeit ergibt sich zu n τg (Ω) = τg∞ + (4.18) τg0i . i=1 Aus Gleichung (4.17) geht hervor, dass eine Nullstelle auf dem Einheitskreis ρi = 1 einen konstanten Beitrag von τg0i = −0.5 liefert. Weiterhin ist festzustellen, dass bei einem zum Einheitskreis spiegelbildlich gelegenen Nullstellenpaar (siehe Abbildung 4.3) 1 1 z01 = ρ1 · e jψ1 · e jψ1 z02 = = (4.19) , z∗1 ρ1 0 der konstante Summenbeitrag von τg01 + τg02 = −1 (4.20) erzeugt wird. Für FIR Filter mit Nullstellen, die symmetrisch zum Einheitskreis liegen, ergibt sich so eine konstante Gruppenlaufzeit von τg (Ω) = n/2. (4.21) Berücksichtigt man weiter, dass unter der Voraussetzung einer reellwertigen Impulsantwort h(k) die komplexen Nullstellen als konjugiert komplexe Paare auftreten, so erhält das Zäh- lerpolynom in Gleichung (4.12) die im Gleichung (4.11) angegebene Koeffizientensymme- trie. 112
  • 112. Abbildung 4.3: Spiegelbildliche Lage der Nullstellen Für die weitere Diskussion werden vier Filtertypen unterschieden, je nachdem ob n gerade oder ungerade ist und ob in Gleichung (4.11) das positive oder das negative Vorzeichen gilt. In allen Fällen kann der Frequenzgang wie folgt dargestellt werden: n H(e jΩ ) = e− j 2 Ω · H0 (e jΩ ), (4.22) wobei H0 entweder rein reell oder rein imaginär ist. Typ 1: Gerade Koeffizientensymmetrie, ungerade Filterlänge h(k) = h(n − k) ; k = 0, 1, . . . n n = 2N N−1 jΩ H01 (e ) = h(N) + 2 h(k) cos((N − k)Ω) (4.23) k=0 Typ 2: Gerade Koeffizientensymmetrie, gerade Filterlänge h(k) = h(n − k) ; k = 0, 1, . . . n n = 2N − 1 N−1 jΩ H02 (e ) = 2 h(k) cos((n − 2k)Ω/2) (4.24) k=0 Typ 3: Ungerade Koeffizientensymmetrie, ungerade Filterlänge h(k) = −h(n − k) , h(N) = 0 ; k = 0, 1, . . . n n = 2N N−1 jΩ H03 (e ) = +2 j h(k) sin((N − k)Ω) (4.25) k=0 Typ 4: Ungerade Koeffizientensymmetrie, gerade Filterlänge h(k) = −h(n − k) ; k = 0, 1, . . . n n = 2N − 1 N−1 jΩ H04 (e ) = 2 j h(k) sin((n − 2k)Ω/2) (4.26) k=0 113
  • 113. Die verschiedenen Filtertypen werden in Abbildung 4.4 exemplarisch dargestellt. Sie unter- scheiden sich grundsätzlich durch das Verhalten bei Ω = 0 und Ω = π, bzw. im Allgemeinen durch die Anzahl der Nullstellen bei z = ±1. So lässt sich z.B. ein Tiefpass nicht mit einem Filter vom Typ 3 oder Typ 4 realisieren, da der Frequenzgang in diesen Fällen für Ω = 0 immer den Wert Null annimmt. Diese Randbedingungen sind beim Filterentwurf zu berücksichtigen. Abbildung 4.4: Linearphasige Filtertypen 114
  • 114. 4.3.2 FIR-Filterentwurf Für den Entwurf von FIR-Filtern sollen zwei Standardverfahren am Beispiel des selektiven Tiefpasses skizziert werden. Vorgegeben ist z.B. das Toleranzschema nach Abbildung 4.5. Es definiert die Eckfrequen- zen ΩD und ΩS sowie die maximalen Approximationsfehler im Durchlassbereich δD und Sperrbereich δS . Ein gutes Tiefpassfilter zeichnet sich durch kleine Approximationsfehler δD und δS , durch einen kleinen Übergangsbereich ∆Ω = ΩS − ΩD und durch eine möglichst kurze Filterlänge aus. Der Filterentwurf erfolgt in der Regel in mehreren Schritten: 1. Schätzen der Filterlänge L = n + 1 2. Optimieren der Filterkoeffizienten bezüglich eines Fehlerkriteriums 3. Vergleichen des berechneten Filters mit dem Toleranzschema. Falls das Toleranz- schema verletzt oder nicht effektiv ausgenutzt wird, muss der Prozess vom 1. Punkt an erneut durchlaufen werden. In diesem Versuch werden zwei Approximationsverfahren, die auf unterschiedlichen Feh- lerkriterien beruhen, untersucht. Abbildung 4.5: Toleranzschema und „Wunsch-Frequenzgang“ HW (Ω) für den TP-Entwurf Modifizierte Fourier-Approximation Die Impulsantwort des nichtkausalen idealen zeitdiskreten Tiefpasses kann unmittelbar durch Abtasten der entsprechenden idealen zeitkontinuierlichen Impulsantwort gewonnen werden. Mit der üblichen Frequenznormierung gilt Ωg sin(Ωg k) hW (k) = ; (4.27) π Ωg k 115
  • 115. dabei bezeichnet Ωg die Grenzfrequenz des Filters. Der Frequenzgang des zeitdiskreten Filters ist gegeben durch ∞ HW (e jΩ ) = hW (k) · e− jkΩ . (4.28) k=−∞ Dieser Ausdruck ist formal auch als Fourier-Reihenentwicklung der in Ω = 2π periodi- schen Funktion HW zu interpretieren. Es ist bekannt, dass eine derartige Reihe bei Abbruch nach endlich vielen Gliedern zu einer optimalen Approximation im Sinne des minimalen mittleren quadratischen Fehlers führt (z.B. [2]). Damit liegt eine Lösung des Approximati- onsproblems im Sinne des genannten Fehlerkriteriums vor. Der Frequenzgang hat dann als endliche Reihe die Form N jΩ hW (k) · e− jkΩ , H0 (e ) = (4.29) k=−N und die endlich lange, zunächst noch nichtkausale Impulsantwort lautet   h (k) ; −N ≤ k ≤ +N h0 (k) =  W  (4.30)   0 ; sonst Der Filterentwurf besteht also lediglich darin, die Wunsch-Impulsantwort außerhalb eines endlich langen Intervalls zu Null zu setzen. Dieser Vorgang lässt sich auch durch Multipli- kation mit einem Rechteckfenster wR (k) beschreiben: h0 = hW (k) · wR (k) (4.31) Dieser Operation entspricht im Frequenzbereich eine Faltung gemäß H0 (e jΩ ) = HW (e jΩ ) ∗ WR (e jΩ ) (4.32) 2π 1 HW (e jΘ ) · WR (e j(Ω−Θ) )dΘ = 2π 0 sin( Ω (2N + 1)) 2 mit WR (e jΩ ) = (4.33) . sin( Ω ) 2 Aus dem Faltungsprozess ist ersichtlich, dass die Breite der abfallenden Flanke des Fre- quenzgangs H0 durch die Breite des Hauptmaximums der Fensterfunktion bestimmt wird. Eine Verbesserung der Flankensteilheit ist somit nur durch längere Fenster (bzw. längere Filter) möglich. Die Approximation ist allerdings wegen des als “Gibbs’sches Phänomen” bekannten Über- schwingens (90% der Sprunghöhe unabhängig von der Fensterlänge) und wegen der damit verbundenen geringen Sperrdämpfung (21 dB) unbefriedigend. Bessere Dämpfungseigenschaften und eine geringere Welligkeit im Durchlassbereich er- hält man durch Modifikation der Fensterfunktion. Gebräuchlich sind folgende Fenster (vgl. Versuch 2): • Bartlett-Fenster (Dreieck-Funktion) • Hann-Fenster (Cosinus-Funktion) 116
  • 116. • Hamming-Fenster (angehobener Cosinus) • Blackman-Fenster (2 überlagerte Cosinus-Funktionen) • Kaiser-Fenster (modifizierte Bessel-Funktionen). Bei diesen Fenstern erkauft man sich allerdings eine Erhöhung der Dämpfung im Sperr- bereich und die Verringerung der Welligkeit im Durchlassbereich durch eine Verbreiterung des Übergangsbereichs, der man prinzipiell nur durch ein längeres Fenster entgegenwirken kann. Der Filterentwurf mit den oben genannten Fensterfunktionen wird wegen der Verwand- schaft zur Verwendung von Rechteckfenstern auch als modifizierte Fourier-Approximation bezeichnet. Von besonderem Interesse ist das Kaiser-Fenster, weil es den Filterentwurf mit beliebig einstellbarer Sperrdämpfung erlaubt. Es ist wie folgt definiert:   α 1 − (1 − 2k )2  /I (α) ;    w(k) = I0  0≤k≤n (4.34)  0   n  wobei I0 die modifizierte Besselfunktion erster Art der Ordnung Null bezeichnet (z.B. [2]). Der Formparameter α erlaubt es, Flankensteilheit gegen Sperrdämpfung in weiten Grenzen auszutauschen. Beim Filterentwurf werden die folgenden Abschätzungsformeln eingesetzt, um die Fenster- parameter n und a für die gewünschte Übergangsbreite ∆Ω und die geforderte Sperrdämp- fung a = −20 log δs zu bestimmen (z.B. [6]): a/dB − 7.95 n≥ (4.35) 2.285 · ∆Ω  0 ; a < 21      α =  C1 · (a/dB − 21)0.4 + C2 · (a/dB − 21) (4.36)  ; 21 ≤ a ≤ 50      C3 · (a/dB − 8.7) ; a ≥ 50  mit den folgenden Konstanten C1 = 0.5842 (4.37) C2 = 0.07886 (4.38) C3 = 0.1102. (4.39) Tschebyscheff-Approximation Eine bessere Ausnutzung des Toleranzschemas lässt sich durch Tschebyscheff-Approxima- tion im Durchlass- und Sperrbereich erreichen. Das Toleranzschema wird, wie in Abbildung 4.6 skizziert, im Sinne der Minimierung des maximalen absoluten Fehlers approximiert. Im Unterschied zu der Fourier-Approximation fällt der Fehler nicht zu höheren Frequenzen ab, sondern oszilliert mit konstanter Amplitude (“equi-ripple”- Approximation). 117
  • 117. Abbildung 4.6: Zur Tschebyscheff-Approximation Das Problem der Tschebyscheff-Approximation ist nur iterativ lösbar. Von Parks und Mc- Clellan wurde ein effizienter Algorithmus zur numerischen Berechnung der Koeffizien- ten entwickelt. Dieser Algorithmus basiert auf dem Tschebyscheff’schen Alternantensatz und dem Remez-Austausch-Algorithmus (z.B. [2]). Die Approximationsfehler können beim Parks-McClellan Algorithmus beliebig vorgegeben werden. Ein Entwurfsbeispiel wird in Abbildung 4.7 dargestellt. Es zeigt im Vergleich den Tiefpass- Frequenzgang bei Tschebyscheff-Approximation und bei modifizierter Fourier-Approxima- tion mit einem Hamming-Fenster. Die Sperrdämpfung des mit dem Hamming-Fenster ent- worfenen Filters beträgt a = −53 dB, während sie beim Tschebyscheff-Entwurf bei ca. a = −63 dB liegt. Abbildung 4.7: Vergleich zwischen Tschebyscheff-Approximation und mo- difizierter Fourier-Approximation mit Hamming-Fenster (n = 64, ΩD = 0.32π, Ωg = 0.375π, ΩS = 0.43π) 118
  • 118. Abschließend ist zu ergänzen, dass auch bei Tschebyscheff-Approximation der erforderli- che Filtergrad abgeschätzt werden kann. Eine Grobabschätzung des Filtergrades ergibt sich aus −10 log(δD δS ) − 13 n≥ (4.40) . 2.324 · ∆Ω 4.4 IIR-Filter 4.4.1 Stabilität Durch seine rekursive Bauweise ist bei einem IIR-Filter die Stabilität nicht immer sicherge- stellt. Ein rekursives Filter ist stabil, wenn alle Polstellen, d.h. Nullstellen des Nennerpoly- noms der Übertragungsfunktion innerhalb des Einheitskreises liegen. Dies führt dazu, dass rekursive Filter im Gegensatz zu nicht-rekursiven Filtern im allgemeinen keinen linearen Phasenverlauf besitzen. Für die Impulsantwort eines stabilen, kausalen und zeitinvarianten Filters gilt ∞ (4.41) |h(k)| < ∞. k=0 Das System reagiert auf eine beschränkte Eingangsfolge mit einer beschränkten Ausgangs- folge. Aus dieser Forderung lässt sich Beziehung 4.41 als eine für die Stabilität hinreichende und notwendige Bedingung ableiten. 4.4.2 Filterstrukturen Für die Realisierung digitaler Filter existieren eine Vielzahl unterschiedlicher Strukturen, die sich aus unterschiedlichen, aber äquivalenten Darstellungsformen der Übertragungs- funktion, der Differenzengleichung und der Zustandsbeschreibung ableiten lassen. Für nicht quantisierte Parameter und Zustandswerte sind diese Strukturen bezüglich des funktionalen Zusammenhangs zwischen y(k) und x(k) völlig identisch. Unterschiede im Filterverhalten ergeben sich erst durch die in der praktischen Ausführung zwangsläufig er- forderliche Quantisierung bzw. durch die endliche Rechengenauigkeit. Nachfolgend werden lediglich die wichtigsten Grundstrukturen aufgezeigt. Von besonderer Bedeutung sind die sog. kanonischen Formen [10], die auf eine Realisierung des Filters mit einer minimalen Anzahl von Speichern führen. Erste kanonische Struktur (Direktform 1): Diese in Abbildung 4.8 skizzierte Struktur folgt für n = m unmittelbar aus der Darstellung n (bi X(z) − ci Y(z)) · z−1 . Y(z) = b0 X(z) + (4.42) i=1 119
  • 119. Abbildung 4.8: Erste kanonische Form (Direktform 1) Die erste kanonische Struktur eignet sich besonders für die Festkommarealisierung eines Filters. Zweite kanonische Struktur (Direktform 2): Zur Ableitung dieser Struktur wird die Übertragungsfunktion nach Gleichung (4.6) als Kas- kade eines rein rekursiven und eines nichtrekursiven Filters dargestellt. n 1 bi z−i . H(z) = (4.43) · n z−i 1+ ci i=0 i=1 In der Signalfluss-Darstellung nach Abbildung 4.9 erhält man zwei parallele Ketten von Verzögerungsgliedern, die sich zu einer Kette zusammenfassen lassen. 120
  • 120. Abbildung 4.9: Signalflussdarstellung der zweiten kanonischen Form (Di- rektform 2) a) Zwischenschritt zur Ableitung der Struktur b) Zweite kanonische Struktur 121
  • 121. Dritte kanonische Struktur (Kaskaden-Form): Ausgehend von der Pol-Nullstellen-Darstellung der Übertragungsfunktion m (z − z0i ) i=1 H(z) = b0 n (4.44) (z − z∞i ) i=1 erhält man durch Zusammenfassen konjugiert komplexer Pol- und Nullstellen eine Ketten- schaltung bzw. Kaskade von Teilsystemen der Ordnung ni = 1 und ni = 2 (konjugiert komplexe Pole): p H(z) = Hi (z). (4.45) i=1 Die Teilsysteme können entweder in der ersten oder in der zweiten kanonischen Form rea- lisiert werden (Abbildung 4.10). Abbildung 4.10: Dritte kanonische Form (Kaskaden-Form) Vierte kanonische Struktur (Parallel-Form): Diese Struktur erhält man durch Partialbruchentwicklung der Übertragungsfunktion n Bi H(z) = b0 + (4.46) . (z − z∞i ) i=1 Für konjugiert komplexe Polstellen lassen sich Teilsysteme zweiten Grades bilden, die in der ersten oder der zweiten kanonischen Form zu realisieren sind. Unter der Vorausset- zung einfacher Pole ergeben sich gleichviele Teilsysteme wie bei der dritten kanonischen Struktur (Abbildung 4.11): Neben diesen kanonischen Grundstrukturen existieren zahlrei- Abbildung 4.11: Vierte kanonische Form (Parallel-Form) che weitere Strukturen, auf die im Rahmen dieses Versuches nicht eingegangen werden kann. Besonders zu erwähnen sind die Wellendigitalfilter, deren Strukturen sich nicht aus der Übertragungsfunktion, sondern mit Hilfe der Wellenparametertheorie systematisch aus den Netzwerkstrukturen von analogen Reaktanzfiltern ableiten lassen (z.B. [10], [6], [4], 122
  • 122. [3]). Dabei bleiben gewisse vorteilhafte Eigenschaften dieser Netzwerkstrukturen wie z.B. die Stabilität oder die Unempfindlichkeit gegenüber Ungenauigkeiten (Quantisierung) der Parameter erhalten. Eine für die Sprachcodierung wichtige Sonderform dieser Strukturen ist das sog. Lattice-Filter. Dieses Filter modelliert die Wellenausbreitung im akustischen Röhrenmodell der Spracherzeugung (z.B. [12]). 4.4.3 IIR-Filterentwurf Zum Entwurf zeitdiskreter IIR-Filter existiert umfangreiche Literatur (z.B. [4] [9] [7] [5]). In diesem Versuch sollen nur das wichtigste Verfahren, die Impulsinvarianzmethode darge- stellt werden. Die Anforderungen an das zu entwerfende zeitdiskrete Filter seien in Form eines Toleranz- schemas für den Frequenzgang |H(Ω)| wie z.B. in Abbildung 4.12 a) vorgegeben. |H(Ω)| |Hc(f)| 1+δD 1+δD 1 1 1-δD 1-δD δS δS πf ΩD ΩS fD fS fA f a) b) 2 40-9910 Abbildung 4.12: Toleranzschema a) für ein zeitdiskretes IIR-Filter b) für ein entsprechendes zeitkontinuierliches Filter Beim Entwurf zeitdiskreter Filter macht man sich die Tatsache zunutze, dass zahlreiche Me- thoden für den Entwurf zeitkontinuierlicher Filter zur Verfügung stehen. Man transformiert daher das Toleranzschema zunächst in ein entsprechendes Schema für den Frequenzgang |HC ( f )| eines zeitkontinuierlichen Filters (siehe Abbildung 4.12 b) ), was durch eine einfa- che Umskalierung der Frequenzachse gemäß Ω f = fA (4.47) 2π erfolgen kann. Nun kann mittels eines beliebigen Verfahrens (z.B. Tschebyscheff-Approxi- mation, Butterworth-Approximation) ein zeitkontinuierliches Filter entworfen werden, das die Spezifikationen erfüllt. Auf die Entwurfsverfahren für zeitkontinuierliche Filter soll hier nicht näher eingegangen werden, es sei auf die Literatur (z.B. [11]) verwiesen. Aus der Übertragungsfunktion HC ( f ) bzw. der Stoßantwort hC (t) des zeitkontinuierlichen Filters erhält man nun durch Rücktransformation ein zeitdiskretes Filter. Dabei soll das Verhalten des Filters im Frequenz- bzw. Zeitbereich möglichst gut erhalten bleiben. Insbe- sondere fordert man i.A., dass die imaginäre Achse der s-Ebene auf den Einheitskreis der z-Ebene abgebildet wird und dass Pole in der linken Halbebene der s-Ebene auf Pole inner- halb des Einheitskreises der s-Ebene abgebildet werden. Die zweite Forderung stellt sicher, dass ein stabiles zeitkontinuierliches Filter auch zu einem stabilen zeitdiskreten Filter führt. Bei der Impulsinvarianzmethode wird das zeitdiskrete IIR-Filter dadurch definiert, dass sei- ne Impulsantwort die mit einer beliebigen Periode T d abgetastete Stoßantwort des entspre- 123
  • 123. chenden zeitkontinuierlichen Filters ist, also h(k) = T d hc (kT d ) (4.48) Der Frequenzgang H(Ω) des zeitdiskreten Filters ∞ Ω n H(Ω) = HC (4.49) − 2πT d T d n=−∞ entspricht dem periodisch wiederholten Frequenzgang HC ( f ) des zeitkontinuierlichen Fil- ters (siehe Abbildung 4.13). Ist HC ( f ) bandbegrenzt, so dass HC ( f ) = 0 für | f | > 1/(2T d ), so stimmen die Frequenzgänge für −π ≤ Ω ≤ π exakt überein. Da ein reales zeitkontinu- ierliches Filter jedoch nie ideal bandbegrenzt sein kann, kommt es wie in Abbildung 4.13 dargestellt, zu Verzerrungen durch Rückfaltung („aliasing”). |H(Ω)| |HC(f)| Ω −2π 2π f 41-9910 Abbildung 4.13: Rückfaltung bei der Impulsinvarianzmethode (nach [7]) Konvergiert der Frequenzgang des zeitkontinuierlichen Filters für hohe Frequenzen rasch genug gegen Null, so kann das durch die Impulsinvarianzmethode gewonnene zeitdiskre- te Filter eine hinreichend gute Approximation darstellen. Daraus folgt aber auch, dass mit dieser Methode nur Filter realisiert werden können, die bei hohen Frequenzen einen Sperr- bereich aufweisen. Sollen z.B. Hochpässe oder Bandsperren realisiert werden, so ist bei hohen Frequenzen eine zusätzliche Bandbegrenzung vorzusehen. Die Impulsinvarianzmethode bildet also das Zeitverhalten des zugrunde liegenden zeitkonti- nuierlichen Filters gut nach, führt jedoch zu nichtlinearen Verzerrungen durch Rückfaltung, so dass die Anforderungen an den Frequenzgang u.U. von dem resultierenden zeitdiskre- ten Filter nicht mehr erfüllt werden. Hier kann man nur Abhilfe schaffen, indem man das Toleranzschema für das zeitkontinuierliche Filter enger definiert als eigentlich erforderlich. 124
  • 124. 4.5 Spezielle Filter 4.5.1 Differentiation Der ideale zeitdiskrete Differenzierer besitzt in Analogie zum zeitkontinuierlichen Diffe- renzierer den periodischen Frequenzgang (siehe Abbildung 4.14) HD0 (e jΩ ) = jΩ ; −π ≤ Ω ≤ π (4.50) Die zugehörige nichtkausale Impulsantwort kann durch inverse Fourier-Transformation ge- wonnen werden π 1 H0 (e jΩ ) = jΩe jΩk dΩ (4.51) 2π −π cos(πk) = k k  −1 ; k = ±1, ±2, . . .  =k   0 ; k=0 HD0 j ... π Ω 0 −π −2π 2π ... a) 1 hD0(k) 1/2 1/3 1/4 ... ... -4 -3 -2 -1 0 1 2 3 4 k -1/4 -1/3 -1/2 b) -1 37-9910 Abbildung 4.14: Idealer Differenzierer a) Frequenzgang b) Impulsantwort Das differenzierende Verhalten kann mit endlicher Filterordnung nur näherungsweise er- reicht werden. Die einfachste Näherung besteht darin, den Differentialquotienten durch den Differenzen- quotienten gemäß y(k) = x(k) − x(k − 1) (4.52) 125
  • 125. zu ersetzen. Eine bessere Approximation wird durch Anwendung der Stirling’schen Interpolationsfor- mel [2] erreicht: 1 y(k) = (x(k − 4) − 8x(k − 3) + 8x(k − 1) − x(k)). (4.53) 12 Sehr kleine Approximationsfehler lassen sich durch Tschebyscheff-Approximation unter Verwendung des im vorigen Abschnitt beschriebenen Parks-McClellan Algorithmus erzie- len. 4.5.2 Integration Das ideal integrierende System besitzt den Frequenzgang 1 H0 (e jΩ ) = (4.54) jΩ Zur Approximation können die verschiedenen Integrationsformeln der numerischen Ma- thematik herangezogen werden, die sich als rekursive Differenzengleichungen darstellen lassen: • Rechteck-Regel: y(k) = y(k − 1) + x(k) • Trapez-Regel: y(k) = y(k − 1) + 1 x(k) + 2 x(k − 1) 1 2 • Simpson-Regel: y(k) = y(k − 2) + 3 x(k) + 4 x(k − 1) + 3 x(k − 2) 1 1 3 Alle Systeme sind wegen des Pols bei z = 1 bedingt stabil und nähern das ideale Verhalten im Bereich niedriger Frequenzen an. Die beste Approximation bietet die Simpson-Regel. 4.5.3 Hilbert-Transformation Die Hilbert-Transformation bewirkt eine Phasenverschiebung um ∆φ = 90 Grad. Derartige Systeme werden im Zusammenhang mit der Quadraturmodulation, der Einseitenbandmo- dulation und der Bestimmung der Einhüllenden (analytisches Signal) eingesetzt. Der ideale zeitdiskrete (nichtkausale) Hilbert-Transformator wird beschrieben durch HH0 (e jΩ ) = − jsgn(Ω) −π≤Ω≤π (4.55) π 1 − jsgn(Ω)e jΩk dΩ hH0 (k) = (4.56) 2π −π 1 = (1 − cos(πk)) (4.57) πk   0 ; k = 0, ±2, ±4 . . .  hH0 (k) =  (4.58)  2 ; k ungerade  πk Eine kausale Approximation mit gerader Filterordnung n (Typ 3) ist von der Form.   h (k − n/2) ; 0 ≤ k ≤ n hH2 (k) =  H0  (4.59)   0 ; sonst. 126
  • 126. Bessere Ergebnisse werden mit Filtern ungerader Ordnung (Typ 4) erzielt, da diese Filter keine Nullstelle bei Ω = π aufweisen. Gute Lösungen erhält man mit dem Entwurfsprogramm von Parks und McClellan [8] bei Vorgabe einer ungeraden Filterordnung. 4.5.4 Interpolation Bei Einhaltung des Abtasttheorems können zeitdiskrete Signale durch ideale Tiefpass-Fil- terung um einen ganzzahligen Faktor r ideal interpoliert werden. Dabei werden, wie in Abbildung 4.15 dargestellt, zunächst jeweils r − 1 Nullwerte zwischen zwei Abtastwerten eingefügt und anschließend eine Tiefpass-Filterung durchgeführt. Das Entwurfsproblem re- duziert sich damit auf den Entwurf eines Tiefpasses. x(k) y(k) hTP(k) a) |HTP| −π/r π/r −π π 0 b) Ω |X| −π π 0 Ω c) |Y| −π π d) 0 Ω 38-9910 Abbildung 4.15: Ideale Interpolation um den Faktor r = 3 a) Zeitbereich b) Frequenzgang des Interpolations-Tiefpasses c) Spektrum des Eingangssignals d) Spektrum des interpolierten Signals 127
  • 127. 4.6 Eigenschaften realer Filter 4.6.1 FIR-Filter Bei der Realisierung digitaler Filter ergeben sich aufgrund der Rechenungenauigkeit (Quan- tisierung) insbesondere bei Festkomma-Arithmetik Genauigkeitsprobleme. Es sind folgende Effekte zu unterscheiden: • Endliche Genauigkeit der Filterkoeffizienten • Endliche Genauigkeit arithmetischer Operationen • Zahlenbereichsbegrenzungen • Quantisierung von Ein- und Ausgangssignal Die nichtlineare Natur dieser Effekte macht ihre exakte Untersuchung sehr schwierig. Man versucht daher lineare Ersatzmodelle einzuführen, die die Verhältnisse mit genügender Ge- nauigkeit beschreiben. Endliche Genauigkeit der Filterkoeffizienten Nach der Quantisierung der Filterkoeffizienten können die Nullstellen der Übertragungs- funktion nicht mehr an beliebigen Orten in der komplexen z-Ebene liegen. Sie sind vielmehr auf diskrete Positionen festgelegt. Die veränderte Nullstellenlage macht sich als Verände- rung des Frequenzgangs bemerkbar. Der durch Quantisierung der Koeffizienten hervorgerufene Fehler lässt sich wie folgt be- schreiben. Mit den quantisierten Koeffizienten ˆ h(k) = h(k) + ∆h(k) (4.60) folgt n H(e jΩ ) = h(k) · e− jkΩ ˆ ˆ (4.61) k=0 n n h(k) · e− jkΩ + ∆h(k) · e− jkΩ = (4.62) k=0 k=0 = H(e jΩ ) + ∆H(e jΩ ) (4.63) Infolge des Frequenzgangfehlers ∆H kann ein Toleranzschema, das vor der Quantisierung (Filterentwurf in Gleitkomma-Arithmetik) eingehalten wurde, verletzt werden. Die Linear- phasigkeit bleibt allerdings erhalten, da die Koeffizientensymmetrie auch bei Quantisierung gegeben ist. Endliche Genauigkeit arithmetischer Operationen Bei Verwendung der Festkomma-Arithmetik führt die Multiplikation zweier vorzeichen- behafteter Zahlen der Wortlänge w auf eine Vergrößerung auf 2w − 1 Binärstellen. Die 128
  • 128. vergrößerte Wortlänge ist z.B. durch Runden wieder auf w Bit zu verkürzen. Das dadurch verursachte Quantisierungsrauschen kann mit guter Näherung durch eine additive gleich- verteilte Rauschquelle mit der Varianz Q2 2 ; Q = 2−w+1 für |x| ≤ 1 σr = (4.64) 12 modelliert werden, wobei Q die Quantisierungsstufe bezeichnet. Zur Berechnung der Filter- ˆ ausgangswerte y(k) sind jeweils n Teilprodukte h(i)· x(k−i) aufzuaddieren. Wenn dabei nach jeder Multiplikation, d.h. vor der Akkumulation gerundet wird, so entsteht eine Rauschleis- tung von insgesamt σ2 = n · Q2 /12. y Werden dagegen zunächst die ungerundeten Produkte mit entsprechend größerer Wortlänge addiert und erst nach Akkumulation gerundet, dann ergibt sich eine Rauschvarianz von lediglich σ2 = Q2 /12. Signalprozessoren verfügen aus diesem Grund über Akkumulatoren y mit vergrößerter Wortbreite. Zahlenbereichsbegrenzung Ein weiteres Realisierungsproblem ergibt sich, insbesondere bei Festkomma-Arithmetik, aus der Zahlenbereichsbegrenzung auf |x| ≤ 1. Um Überläufe zu vermeiden, muss das Ein- gangssignal derart skaliert werden, dass das Ausgangssignal stets im zulässigen Zahlenbe- reich liegt. Die “sichere” Skalierung mit dem Faktor K ergibt sich aus der Forderung n |y(k)| = h(i) · K · x(k − i) (4.65) i=0 n ! ≤ K · |xmax | · |h(i)| < 1. (4.66) i=0 Daraus folgt für |xmax | = 1 1 K< (4.67) . n |h(i)| i=0 Quantisierung von Eingangs- und Ausgangssignal Die Quantisierung des Eingangssignals erfolgt bei der Analog-Digital-Umsetzung mit einer Wortlänge w x . Der Quantisierungsfehler wird durch ein additives gleichverteiltes weißes Rauschsignal ex (k) mit der Leistung σ2x = Q2 /12 (Q x = 2−wx +1 ) beschrieben. e x Am Ausgang des Filters macht sich dieses Rauschen in gefilterter Form bemerkbar. Es gilt für den Rauschanteil n n    σ2 = E ( h(i) · ex (k − i))2  = σ2x · h2 (i).   (4.68)   y e     i=0 i=0 Wird die Wortlänge am Filterausgang z.B. für die D/A-Umsetzung verkürzt auf wy < w, so erhöht sich die Rauschleistung nochmals um Q2 /12 (Qy = 2−wy +1 ). y 129
  • 129. Unter Berücksichtigung der internen Quantisierung nach der Akkumulation ergibt sich aus- gangsseitig eine Rauschbilanz von n σ2 = (Q2 · h2 (i) + Q2 + Q2 )/12. (4.69) x y i=0 Insgesamt ergeben die verschiedenen Quantisierungsoperationen das in Abbildung 4.16 dar- gestellte Modell zur Beschreibung des realen Filters. Abbildung 4.16: FIR-Filter mit Quantisierung 4.6.2 IIR-Filter Bei den digitalen IIR-Filtern treten grundsätzlich die selben Effekte durch Quantisierung auf, wie bei den FIR-Filtern. Durch die rekursive Struktur der IIR-Filter kann es jedoch zu periodischen Fehlermustern, sog. Grenzzyklen kommen, die dazu führen können, dass das Filter instabil wird. In diesem Fall reicht es nicht mehr aus, die Quantisierungseffekte durch additive Rauschquellen zu beschreiben. Grenzzyklen Da die Quantisierung eine nichtlineare Operation darstellt, ist die theoretische Behandlung der Grenzzyklen schwierig und nur in einfachen Sonderfällen möglich. Um die Problematik deutlich zu machen, soll hier das einfache System nach Abbildung 4.18 betrachtet werden (nach [9]). Ohne eine Quantisierung im Rückführungszweig lautet die Impulsantwort des Systems: y(k) = ak−1 für k ≥ 1. Das System ist also für |a| < 1 stabil. Nun werde das Ergebnis der Multiplikation mit der Konstanten a so gerundet, dass es ein ganzzahliges Vielfaches von Q ist. Abbildung 4.19 zeigt die Impulsantwort des Systems 130
  • 130. Abbildung 4.17: Gitter der möglichen Polstellenlagen eines Filters zweiten Grades (Direkte Form) und Quantisierung der Koeffizien- ten auf je 5 Bit Abbildung 4.18: System ersten Grades mit Rundung für verschiedene Werte von a und Q. Man kann drei mögliche Fälle unterscheiden: Für |a| < 1/2 nimmt die Ausgangsfolge y(k) nach einer endlichen Zahl von Taktschritten den Wert Null an. Für 1/2 ≤ a < 1 stellt sich ein von Null verschiedener stationärer Endwert ein; man kann in diesem Fall von einem Grenzzyklus der Periodenlänge 1 sprechen. Für −1 < a ≤ −1/2 schließlich ergibt sich eine alternierende Ausgangsfolge, d.h. ein Grenzzy- klus der Periodenlänge 2. Das System ist also u.U. nicht mehr asymptotisch stabil, d.h. die Ausgangsfolge y(k) klingt für k → ∞ nicht ab, obwohl die Eingangsfolge x(k) für k ≥ 1 verschwindet. Bei rückgekoppelten Systemen höheren Grades mit Quantisierung können Grenzzyklen mit größeren Periodenlängen auftreten (z.B. [9], [7]). 131
  • 131. Abbildung 4.19: Impulsantwort des Systems nach Abbildung 4.18 a) für verschiedene Werte von a (a > 9) und Q = 0.1 b) für verschiedene Werte von a (a < 0) und Q = 0.1 c) für a = 0.8 und verschiedene Werte von Q d) für a = −0.8 und Q = 1/4 bzw. ohne Quantisierung 132
  • 132. Überlaufschwingungen (große Grenzzyklen) Bei der Filterrealisierung in Zweierkomplement-Arithmetik (siehe Versuch 1) mit dem Zah- lenbereich −1 ≤ x ≤ 1 − 2−w+1 (4.70) kann bei der Addition zweier Zahlen ein Überlauf auftreten. Dieser Überlauf hat entspre- chend der Überlaufcharakteristik der Zweierkomplement-Arithmetik (siehe Abbildung 4.20) einen falschen Summenwert mit entgegengesetztem Vorzeichen zur Folge. Dieser Signal- sprung kann über die Signalrückführung ein instabiles Systemverhalten verursachen. Die dann auftretenden Oszillationen werden als Überlaufschwingungen bezeichnet. Sie können auch nach Abschalten des Eingangssignals bestehen bleiben. In einem Filterblock zweiten Grades lassen sich diese Grenzzyklen vermeiden, wenn die Zweierkomplement-Kennlinie durch die Sättigungskennlinie ersetzt wird (Abbildung 4.21). Abbildung 4.20: Üeberlaufkennlinie der Zweierkomplement-Arithmetik (Q = 2−w+1 ). Abbildung 4.21: Sättigungskennlinie 133
  • 133. 4.7 Vorbereitende Aufgaben 4.7.1 Aufgabe 1 Leiten Sie die Gleichung (4.23) her. 4.7.2 Aufgabe 2 Gegeben sind drei, durch ihre Pol-Nullstellendiagramme charakterisierte Filter. Beantwor- ten Sie die folgenden Fragen: 1. Ist das Filter linearphasig? 2. Um welchen Filtertyp handelt es sich? 4.7.3 Aufgabe 3 Gegeben ist das folgende Toleranzschema. Schätzen Sie die Filterlänge, falls das Filter mit einem Kaiser-Fenster oder mit dem Parks-McClellan Algorithmus entworfen wird. 134
  • 134. 4.7.4 Aufgabe 4 Ein rekursives Filter 2. Ordnung soll in der zweiten kanonischen Form realisiert werden. 1. Skizzieren Sie das Blockschaltbild. 2. Geben Sie die Differenzengleichung an. 3. Berechnen Sie den Frequenzgang |H(e jΩ )| in allgemeiner Form. 4. Bestimmen Sie die Koeffizienten derart, dass die Impulsantwort folgende Charakte- ristika aufweist: • Sinusförmiger Verlauf (Ω0 ). • Hüllkurve der Form αk . 4.7.5 Aufgabe 5 Die Auswirkung der Wortlängenreduktion soll am Beispiel eines rekursiven Filters 1.Ord- nung untersucht werden. X(z) Y(z) z-1 Q a 016-9812 Für die Eingangsfolge gilt   10 ; k = 0  x(k) =  (4.71)   0 ; sonst. Weiterhin wird y(k) = 0 für k < 0 vorausgesetzt. 1. Berechnen Sie die Ausgangsfolge für a = −0.92 und Q = 0 k 0 1 2 3 4 5 6 7 8 9 10 y(k) 135
  • 135. 2. Berechnen Sie die Ausgangsfolge für a = −0.92 und Runden auf den nächstliegenden Integerwert (Q = 1). k 0 1 2 3 4 5 6 7 8 9 10 y(k) 3. Berechnen Sie die Ausgangsfolge für a = −0.92 und Wortlängenverkürzung durch Abschneiden (Q = 1) k 0 1 2 3 4 5 6 7 8 9 10 y(k) 4. Berechnen Sie die Ausgangsfolge für a = +0.92 mit und ohne Runden (Q = 1). k 0 1 2 3 4 5 6 7 8 9 10 y(k) Welcher Effekt tritt nun auf? 4.7.6 Aufgabe 6 In dieser Aufgabe sollen Sie beispielhaft die Behandlung von Quantisierungseffekten mit- tels linearer Ersatzmodelle kennenlernen. Gegeben ist ein Filter zweiten Grades mit Wortlängenverkürzung durch Runden. X(z) Y(z) z-1 z-1 R1 Q R2 Q -C1 -C0 015-9812 Die Rundungsoperation werde durch ein additives gleichverteiltes weißes Rauschsignal mit der Leistung σ2 = Q2 /12 beschrieben. r 1. Skizzieren Sie die Rauschleistungsdichte des additiven Rauschsignals. 2. Skizzieren Sie ein lineares Signalflussdiagramm zur Berechnung der Rundungseffek- te. 3. Geben Sie die Störübertragungsfunktionen von den Rundungsstellen R1 und R2 zum Ausgang an. 4. Wie berechnet man die Leistung am Ausgang eines linearen Systems aus der Leistung des Eingangssignals? 136
  • 136. 4.8 Versuchsdurchführung Die mit (*) gekennzeichneten Versuche sind nur zur Vertiefung des Stoffs gedacht und kön- nen weggelassen werden, falls die zur Verfügung stehende Zeit nicht ausreicht. Für die folgenden Versuche soll, wenn nicht anders gesagt, ein Abtastfrequenz von fa = 8000 Hz zugrunde gelegt werden. 4.8.1 FIR-Versuch A: Rechteck-, Hamming- und Blackman-Fenster Es soll ein Tiefpassfilter der Länge N = 16 mit der Impulsantwort sin( π (n − 8.5)) 2 y(n) = (4.72) π (n − 8.5) 2 betrachtet werden. Transformieren Sie die Impulsantwort unter Verwendung der Rechteck-Fensterfunktion in den Frequenzbereich. Verwenden Sie hierzu die MATLAB-Funktion freqz. Stellen Sie die Übertragungsfunktion grafisch dar. Welche Grenzfrequenz hat dieser Tiefpass? Erzeugen Sie ein weiteres Tiefpass-Filter mit der Länge N = 64. Beachten Sie, dass Sie für eine symmetrische Impulsantwort die passende zeitliche Verschiebung wählen! Trans- formieren Sie auch diese Impulsantwort unter Verwendung der Rechteck-Fensterfunktion in den Frequenzbereich und stellen Sie die Übertragungsfunktion grafisch dar. Füllen Sie die ersten beiden Zeilen der Tabelle aus. Transformieren Sie die Tiefpass-Impulsantwort der Länge N = 64 mit dem Hamming- und dem Blackman-Fenster in den Frequenzbereich. Verwenden Sie hierzu die MATLAB- Funktion hamming bzw. blackman. Vergleichen Sie die verschiedenen Tiefpässe indem Sie die Tabelle vollständig ausfüllen. Minimale Dämpfung Breite des Über- Maximales Überschwingen im Sperrbereich [dB] gangsbereichs [Hz] im Durchlassber. [dB] Rechteck 16 Rechteck 64 Hamming 64 Blackman 64 Der Einfluss der Fensterfunktion: 4.8.2 FIR-Versuch B: Kaiser-Fenster Gegeben ist das folgende Toleranzschema (siehe Abbildung 4.22) entspechend Aufgabe 3. Konstruieren Sie mit Hilfe des sptool und der Algorithmus-Option Kaiser Window FIR ein Tiefpassfilter, das diese Toleranzen bei minimaler Filterlänge erfüllt. Exportieren Sie die Filterkoeffizienten auf den MATLAB-Workspace, da Sie diese noch für den nächsten Versuch benötigen. 137
  • 137. yyy yyyy |Hw(Ω)| yyy yyyy 1+ δD 1 1– δD δS π ΩD ΩS Ω 0 Ωg 007-9812 Abbildung 4.22: Toleranzschema zum Filterentwurf Verwenden Sie den Filter Viewer, um sich Amplitude, Phase, Gruppenlaufzeit, Pol-/Null- stellendiagramm, Impulsantwort und Sprungantwort anzeigen zu lassen. Skizzieren Sie die- se qualitativ. Machen Sie sich mit weiteren Funktionen und Parametern des sptool und des Filter Viewers vertraut. 4.8.3 FIR-Versuch D: Differentiation Erzeugen Sie die Impulsantworten der folgenden zwei Differenzierer: 1. Differenzbildung: y(k) = x(k) − x(k − 1) 1 2. Stirling-Formel: y(k) = 12 (x(k − 4) − 8x(k − 3) + 8x(k − 1) − x(k)) Hierzu können Sie z.B. die MATLAB-Funktion impz verwenden oder die Übertragungs- funktion H(z) im sptool importieren und die Impulsantwort dort darstellen. Entwerfen Sie mit Hilfe des Parks-McClellan Algorithmus einen Differenzierer mit folgen- den Parametern (siehe Abbildung 4.23): Filterlänge 32, Ωu = 0, Ωo = π. Verwenden Sie hierfür die MATLAB-Funktion remez. Vergleichen Sie die Übertragungsfunktionen der verschiedenen Approximationen (lineare Darstellung im Frequenzbereich) und ermitteln Sie den Frequenzbereich, in dem die Filter als Differentiatoren verwendbar sind. 4.8.4 FIR-Versuch E: FIR-Filter auf dem DSP Das FIR-Filter aus Versuchstermin 1 (s. Kap. 1.4.3) soll nun auf dem DSP realisiert wer- den. Welche Funktion der Runtime-Library ist hierfür geeignet? Nehmen Sie das Run-Time Library Manual for SHARC Processors zu Hilfe. Wo im Speicher sollten die Variablen für eine möglichst effiziente Programmausführung abgelegt werden? Wählen Sie als Filterko- effizienten die Vorgaben aus Versuchstermin 1 (s. Kap. 1.4.3). Verwenden Sie anschließend den MATLAB-Debugger, um die Implementierung Ihres Filters zu verifizieren. 138
  • 138. a) b) |Hw(Ω)| |Hw(Ω)| Ωu Ω0 πΩ Ωu Ω0 πΩ 39-9910 Abbildung 4.23: Betragsfrequenzgang a) eines Differenzierers b) eines Hilbert-Transformators 4.8.5 (*)FIR-Versuch F: Koeffizienten-Quantisierung Simulieren Sie mit Hilfe von MATLAB eine Koeffizienten-Quantisierung, indem sie die aus Versuch 2 exportierten Filterkoeffizienten auf 64 mögliche Werte runden. Importieren Sie die gerundeten Koeffizienten im sptool und überprüfen Sie, ob das vorgegeben Toleranz- schema immer noch eingehalten wird. Zur Quantisierung muss zunächst das Minimum und das Maximum der Filterkoeffizienten bestimmt werden. Anschliessend wird jeder Koeffizi- ent um das Minimum so verschoben, dass der Wertebereich nach unten durch 0 begrenzt ist. Die so entstandenen Werte werden in Integer-Zahlen der Anzahl der Quantisiererstufen entsprechend gewandelt (Maximum wird auf den maximalen Integer-Wert abgebildet) und anschliessend wieder in den Wertebereich zu Beginn gewandelt. Die Quantisierung wird bei der Rundung auf die Integer-Zahlenwerte durchgeführt. Führen Sie dieselben Untersuchun- gen auch für 4 Quantisierungsstufen durch. 4.8.6 (*) FIR-Versuch G: Tschebyscheff-Approximation Konstruieren Sie mit Hilfe des Parks-McClellan Algorithmus ein Filter für das in Versuch 2 angegebene Toleranzschema. Verwenden Sie hierfür die MATLAB-Funktion Funktion remezord. Verwenden Sie zunächst die in Versuch FIR-2 ermittelte minimale Filterlänge und verglei- chen Sie den Dämpfungsverlauf im Sperrbereich mit dem in Versuch FIR-2 konstruierten Filter. Minimieren Sie die Filterlänge. 4.8.7 IIR-Versuch A: Rekursive Differenzengleichung Zunächst soll ein einfaches rekursives Filter durch seine Differenzengleichung realisiert und der Einfluss der Abtastfrequenz auf die Grenzfrequenz des Filters untersucht werden. Erzeugen Sie die Impulsantwort des rekursiven Filters mit der Differenzengleichung y(k) = x(k) + x(k − 1) + 0.16y(k − 1). (4.73) Die Abtastfrequenz soll fa = 500 Hz betragen. Wie lautet die Übertragungsfunktion H(z) dieses Filters? Führen Sie die Fourier-Transformation der Impulsantwort aus und betrachten den Frequenz- 139
  • 139. gang. Um welchen Filtertyp handelt es sich bei diesem Filter? Bestimmen Sie die Grenzfrequenz des Filters (-3-dB-Punkt) und tragen Sie diese in die untenstehende Tabelle ein. Generieren Sie nun die Impulsantworten des Filters mit der glei- chen Differenzengleichung bei den Abtastfrequenzen fa = 1000 Hz und fa = 1500 Hz. Transformieren Sie beide Impulsantworten in den Frequenzbereich und bestimmen Sie für beide Filter die Grenzfrequenzen (-3-dB-Punkte). Abtastfrequenz Grenzfrequenz 500 Hz 1000 Hz 1500 Hz Welcher Zusammenhang besteht zwischen Grenzfrequenz und Abtastfrequenz eines Digital- filters? 4.8.8 IIR-Versuch B: Spezielle rekursive Filter Resonanzfilter Das rein rekursive Filter 2. Ordnung bildet ein Resonanzfilter. Überzeugen Sie sich von dieser Tatsache durch Generieren der Impulsantwort des rein rekursiven Filters 2. Ordnung mit der folgenden Übertragungsfunktion 1 H(z) = (4.74) . 0.7z−1 + 0.9z−2 1.8 − Wählen Sie als Abtastfrequenz fa = 1000 Hz. Berechnen Sie die Pol-Lage und bestimmen Sie die Differenzengleichung aus der Übertra- gungsfunktion. Führen Sie die Fourier-Transformation der Impulsantwort aus. Bei welcher Frequenz liegt die Resonanz? Schauen Sie sich auch den Phasenverlauf und das Zeitverhalten des Resonanzfilters an. Allpass Beim Allpassfilter kompensieren sich die Pole und Nullstellen paarweise. Die Übertra- gungsfunktion eines Allpassfilters 2. Ordnung lautet allgemein b2 + b1 z−1 + z−2 H(z) = (4.75) 1 + b1 z−1 + b2 z−2 Erzeugen Sie die Impulsantwort des Allpasses mit der Übertragungsfunktion 0.71 + 0.35z−1 + z−2 H(z) = (4.76) 1 + 0.35z−1 + 0.71z−2 Wählen Sie als Abtastfrequenz fa = 1000 Hz. Transformieren Sie die Impulsantwort in den Frequenzbereich und betrachten Sie den Frequenzgang und den Verlauf der Phase. Welche Verstärkung erwarten Sie für den gesamten Frequenzbereich? Bei welcher Frequenz beträgt die Phase -180 Grad? Wozu kann man einen Allpass einsetzen? Wie groß ist die maximale Gruppenlaufzeit? 140
  • 140. Notchfilter Zur Unterdrückung einer einzelnen Frequenz dient das Notchfilter. Relativ einfach lässt sich ein Notchfilter erzeugen, indem man bei der zu unterdrückenden Frequenz eine Nullstelle auf den Einheitskreis legt und der zugehörigen Polstelle den gleichen Winkel, jedoch einen geringeren Betrag zuordnet. Die Breite der Frequenzgangskerbe wird durch den Abstand des Pols vom Einheitskreis eingestellt. Als Beispiel soll bei einer Abtastfrequenz von fa = 1000 Hz ein Notchfilter realisiert werden, welches die Frequenz fn = 125 Hz weitgehend unterdrückt. Wählt man den Polradius zu 0.99, so ergibt sich (nachrechnen !) 1√ zN = 2(1 + j) (4.77) 2 zp = 0.7(1 + j) (4.78) 1.4142z−1 z−2 1− + H(z) = (4.79) 1 − 1.4z−1 + 0.98z−2 Konstruieren Sie mit Hilfe des sptool und der Algorithmus-Option Pole/Zero ein solches Notchfilter, indem Sie die Pole und Nullstellen entsprechend anordnen. Im z j zN zP π 4 1 Re 42-9910 Abbildung 4.24: Notch-Filter Erzeugen Sie die Impulsantwort dieses Notchfilters. Wählen Sie als Abtastfrequenz fa = 1000 Hz. Stellen Sie die Sperrdämpfung bei 125 Hz fest und ermitteln Sie die -3-dB- Bandbreite. (*) Eine bezüglich der Koeffizientenquantisierung günstigere Struktur eines Notchfilters 2. Ord- nung entsteht durch Addition des Eingangssignals eines Allpasses 2. Ordnung zu dessen Ausgangssignal, so dass die Übertragungsfunktion dieses Notchfilters, 0.5 + 0.5b2 + b1 z−1 + (0.5 + 0.5b2 )z−2 HN (z) = 0.5(1 + HALL (z)) = (4.80) 1 + b1 z−1 + b2 z−2 lautet. Wählt man b1 = 0.3 und b2 = −0.5, so erhält man die Differenzengleichung y(k) = .25x(k) + .3x(k − 1) + .25x(k − 2) − .3y(k − 1) + .5y(k − 2). (4.81) Erzeugen Sie bei einer Abtastfrequenz von fa = 1000 Hz die Impulsantwort dieses Filters. Bestimmen Sie die Notchfrequenz. Wie groß ist die Dämpfung bei der Notchfrequenz? In welchem Bereich liegt die Gruppenlaufzeit des Filters? 141
  • 141. 4.8.9 IIR-Versuch C: Sprungantwort und Einschwingzeit Eine wichtige Rolle bei der Realisierung digitaler Filter spielt das Zeitverhalten des Filters. Sollen z.B. Messwerte mit einem Tiefpass gefiltert werden, so muss zur Erzielung einer vernünftigen Messgenauigkeit die Einschwingzeit des Filters nach einer Messwertänderung abgewartet werden. Die Einschwingzeit T s wird, wie in Abbildung 4.25 skizziert, aus der Sprungantwort er- mittelt. Ab dem Zeitpunkt T s weicht das Ausgangssignal nur noch um höchstens ±δ vom stationären Endwert E ab. y(t) 2δ E t Ts 43-9910 Abbildung 4.25: Zur Definition der Einschwingzeit T S Zur Definition der Einschwingzeit T s soll die Sprungantwort eines Tiefpasses 6. Ordnung (Koeffizientenfile TP.dbl) generiert werden. Wählen Sie als Abtastfrequenz fa = 1000 Hz. Bestimmen Sie die Einstellzeit T S , in welcher der Tiefpass den stationären Endwert auf 5 Prozent Genauigkeit erreicht. 4.8.10 (*)IIR-Versuch D: Vergleich verschiedener Approximationsverfahren Die Wahl des Entwurfsverfahrens hat Auswirkungen auf die Filterordnung (und damit auf die erforderliche Rechenzeit), das Frequenz- und Phasenverhalten und auf das Zeitverhalten eines Filters. In diesem Versuch sollen diese Filtereigenschaften mit Hilfe des sptool ver- glichen werden. Entwerfen Sie hierzu mit Hilfe des Filter Designers einen Bandpassfilter 6. Ordnung unter Verwendung der verschiedenen IIR Algorithmus-Optionen. Dies lässt einen Vergleich der Filtersteilheit in den Übergangsbereichen bei gleichem Filter-Rechenaufwand zu. Vergleichen Sie das Frequenzverhalten der mit den verschiedenen Approximationsverfah- ren entworfenen Filter. In welchen Bereichen ist der Frequenzverlauf glatt oder wellig? 142
  • 142. Approximationsverfahren Durchlassbereich Sperrbereich Butterworth Chebyshev I Chebyshev II Welches Filter besitzt den steilsten Abfall beim Übergang vom Durchlassbereich in den Sperrbereich? Welches Filter besitzt den flachsten Abfall beim Übergang vom Durchlassbereich in den Sperrbereich? Untersuchen Sie nun das unterschiedliche Phasenverhalten der Filter. Bedenken Sie bei der Betrachtung der Phasenverläufe, dass im wesentlichen das Phasenver- halten im Durchlassbereich interessiert. Betrachten Sie die Lage der Pole und Nullstellen der verschiedenen Filter. Welches Filter besitzt in der z-Ebene Polstellen in der Nähe des Einheitskreises? Bei wel- chem Filter sind die Polstellen am weitesten vom Einheitskreis entfernt? Woran kann man erkennen, dass es sich bei diesen Filtern um Bandpässe handelt? Vergleichen Sie abschließend das Zeitverhalten der Filter. Welches Filter schwingt am schnells- ten ein? Welche Einheitsimpulsantworten haben die kürzesten Längen, welches Filter be- sitzt die längste Einheitsimpulsantwort? Welcher Zusammenhang besteht zwischen dem Zeitverhalten der Filter und der Lage ihrer Pole (Abstand zum Einheitskreis)? 143
  • 143. Literaturverzeichnis [1] S. A. Azizi. Entwurf und Realisierung digitaler Filter. Oldenbourg Verlag, Wien, 1988. [2] I. N. Bronstein und K. A. Semendjajew. Taschenbuch der Mathematik. Teubner, Leibzig, 21. Auflage, 1983. [3] A. Fettweis. Wave digital filters: Theory and practice. In Proceedings of the IEEE, Band 74, Seiten 270–327, 1986. [4] W. J. Hess. Digitale Filter. Teubner Verlag, Stuttgart, 2. Auflage, 1993. [5] L. B. Jackson. Digital Filters and Signal Processing. Kluwer, 1989. [6] D. Kammeyer und K. Kroschel. Digitale Signalverarbeitung, Filterung und Spektral- analyse. Teubner Verlag, Stuttgart, 1989. [7] A. Oppenheim und R. Schafer. Zeitdiskrete Signalverarbeitung. Oldenbourg Verlag, München, 3. Auflage, 1999. [8] T. W. Parks und J. H. McClellan. Chebyshev approximation for nonrecursive digital filters with linear phase. In Circuits and Systems, IEEE Transactions on, Band 19(2), Seiten 189–194, 1972. [9] H. W. Schüßler. Digitale Sysreme zur Signalverarbeitung. Springer Verlag, 1973. [10] H. W. Schüßler. Digitale Signalverarbeitung Band I: Analyse diskreter Signale und Systeme. Springer Verlag, 1988. [11] U. Tietze und C. Schenk. Halbleiter-Schaltungstechnik. Springer-Verlag, 6. Auflage, 1983. [12] P. Vary. Skipt zur Vorlesung Nachrichtensysteme I. Institut fü Nachrichtengeräte und Datenverarbeitung, RWTH Aachen, 1995. 144