Abschlussbericht - emsp.tu

Werbung
Prof. Dr.-Ing. R. Orglmeister
Abschlussbericht
DSP-Labor WS06/07
Analyse und Erweiterung eines DPOAEGerätes zur Messung von
Verzerrungsprodukten im menschlichen
Ohr
Betreuer:
Gruppe:
Dr.-Ing. Guntram Liebsch
Sinan Akay
Jorgose Estrella
Thomas Wotschke
Quyet Vu Trung
Inhaltsverzeichnis:
1
Einleitung _____________________________________________________________ 4
1.1
1.1.1
1.1.2
1.1.3
1.2
1.2.1
1.2.2
1.2.3
1.2.4
2
4
Neue Benutzeroberfläche _______________________________________________________ 5
Neues Übertragungsmodul ______________________________________________________ 5
Goertzel-Algorithmus für noch schnellere FFT-Berechnung ____________________________ 5
Probleme und Fehler _____________________________________________________ 5
Eingangssignal von ADC nicht berücksichtigt _______________________________________
Falsche Umrechnung von ADC-Wert auf Spannungswert ______________________________
Aufnahmefehler_______________________________________________________________
Versorgungsproblem ___________________________________________________________
6
6
6
6
Änderungen ___________________________________________________________ 7
2.1
Einige Worte zur FFT: Schnelle Fouriertransformation ________________________ 7
2.2
Wie Arbeitet der Algorithmus? ____________________________________________ 7
2.3
Der Goertzel-Algorithmus_________________________________________________ 7
2.3.1
2.3.2
2.3.3
2.3.4
2.3.5
3
Neuerungen / Änderungen ________________________________________________ 5
Motivation ___________________________________________________________________ 7
Herleitung ___________________________________________________________________ 8
Vergleich der Berechnungsaufwand ______________________________________________ 10
Goertzel und die DPOAE Messung_______________________________________________ 10
Graphische Darstellung eines Beispiels ___________________________________________ 10
Analyse der ADC-Platine ________________________________________________ 13
3.1
Rauschverhalten________________________________________________________ 13
3.2
Umrechnung des ADC-Ergebnisses auf Volt_________________________________ 15
3.3
Testaufnahme / Nachbildung der DPOAE-Umgebung ________________________ 16
Neuerungen __________________________________________________________ 18
4.1
4.1.1
4.1.2
4.1.3
4.2
4.2.1
4.2.2
4.2.3
4.2.4
4.3
4.3.1
4.3.2
4.4
4.4.1
4.4.2
4.4.3
LCD-Anzeige __________________________________________________________ 18
Vorbemerkungen_____________________________________________________________ 18
Hardware___________________________________________________________________ 18
Software ___________________________________________________________________ 20
GUI __________________________________________________________________ 24
Einleitung __________________________________________________________________
Aufbau_____________________________________________________________________
Programmierung _____________________________________________________________
Kommunikation mit dem DSP __________________________________________________
24
25
26
28
Notch-Filter ___________________________________________________________ 28
Theoretischen Grundlagen _____________________________________________________ 28
Das Design _________________________________________________________________ 29
Module _______________________________________________________________ 31
Interpreter (kurze Einführung) __________________________________________________ 32
Modul „help“(dev_help.c/dev_help.h)_____________________________________________ 32
Modul “transfer” (dev_transfer.c/dev_transfer.h) ____________________________________ 34
5
Abschluss ____________________________________________________________ 37
6
Anhang ______________________________________________________________ 38
6.1
Abbildungsverzeichnis: __________________________________________________ 38
6.2
Tabellenverzeichnis: ____________________________________________________ 38
6.3
Literaturverzeichnis ____________________________________________________ 38
2
6.4
Abkürzungen __________________________________________________________ 39
3
1 Einleitung
Die Gruppe des Praktikums Signalverarbeitung, die von Guntram Liebsch betreut wird,
beschäftigt sich in diesem Semester mit dem Thema: Distorsionsprodukte otoakustischer
Emissionen, kurz DPOAE. Es wird ein aus den letzten Semestern bereits vorhandenes Gerät
und dessen Software weiterentwickelt.
Dabei geht es darum, dass dem Innenohr mehrere Sinustöne bestimmter Frequenz und
Amplitude zugeführt und gleichzeitig mit einem Mikrofon die Reaktion des Ohres darauf
gemessen wird. Diese Reaktion wird durch die äußeren Haarzellen im Cortischen Organ
erzeugt und kann in Form einer weiteren Schwingung gemessen werden.
Diese Methode bietet frühzeitig die Möglichkeit bei Neugeborenen Hörschäden zu erkennen
beziehungsweise auszuschließen.
Abbildung 1 Aufbau der Ohres
In dem vorliegenden Projekt werden zwei Sinustöne als Eingangssignal erzeugt und die aus
medizinischer Sicht besonders bedeutende Frequenz
f3 = 2 ⋅ f1 − f 2 , mit f1 und f2 als Eingangssignale
ausgewertet.
Da aus den letzten Semestern bereits Hard- und Software zur Verfügung steht (Überblick in
Abbildung 2), wird nur noch an deren Verbesserung gearbeitet.
4
Abbildung 2: Überblick von Soft- und Hardware
1.1 Neuerungen / Änderungen
1.1.1 Neue Benutzeroberfläche
Über den USB werden Daten vom DSP zum PC übertragen. Die alte Oberfläche basiert auf
C++-Programmierung mit Visual Studio und funktioniert nicht richtig. Die neue Oberfläche,
die auch auf C++ basiert, aber die freie Bibliothek Qt verwendet, wird in Kapitel 4.2 GUI
näher erläutert.
1.1.2 Neues Übertragungsmodul
Mit dem Modul „transfer“ ist es zum ersten Mal möglich, Daten nach Wunsch zu übertragen.
Im Unterschied zum alten Projekt, werden Daten nicht mehr automatisch nach jeder
FFT-Berechnung zum PC geschickt. Alle Informationen bleiben im DSP gespeichert und
kann durch die Funktionen des Moduls „transfer“ einzeln übertragen werden. Näheres steht
in Kapitel 4.4.3 Modul “transfer”.
1.1.3 Goertzel-Algorithmus für noch schnellere FFT-Berechnung
Das Modul „fft“ wird um die Berechnung des Goertzel-Algorithmus erweitert. Nicht alle
Frequenzanteile werden berechnet, sondern nur die Anteile die uns interessieren (f1, f2 und
f3). Die Geschwindigkeit ist hier deutlich schneller als die FFT.
1.2 Probleme und Fehler
Unten werden Probleme und Fehler geschildert, die bei der Durchführung des Versuches
auftreten. Diese sollen im nächsten Projekt beseitigt werden.
5
1.2.1 Eingangssignal von ADC nicht berücksichtigt
Die ADC-Platine wurde analysiert. Wir erhalten Rauschen am Eingang mit 50Hz.
Weiterhin haben wir bei der Durchführung nur das Ausgangssignal vom DDS gemessen aber
nicht direkt das Signal am ADC-Eingang. Die Wirkung von der Filterschaltung und der
Eingangsbegrenzungsschaltung konnte somit nicht festgestellt werden.
1.2.2 Falsche Umrechnung von ADC-Wert auf Spannungswert
Wie oben geschildert haben wir die Spannung am DDS gemessen. Und auf diese Werte haben
wir den Ausgang der ADC normiert. Die Umrechnung von Float auf Volt ist somit nicht
korrekt und gibt eine falsche Beschreibung der Analog-Digital-Wandlung wieder.
Diese Umrechnung soll korrigiert werden.
1.2.3 Aufnahmefehler
Beim Aufnehmen des Audiosignals ist der Fehler aufgetreten, dass die ersten Zahlen nicht
stimmen. Es sieht so aus als würden diese Werte aus der letzten Aufnahme stammen. Wird
eine Aufnahme neu gestartet, so beginnt es erst ab der 146. Stelle.
1.2.4 Versorgungsproblem
Die Versorgung für den DDS und ADC sind nicht optimal, da die Leitungen manchmal
abgerissen werden können. Hier sollen neue Stecker angebracht werden.
Wird mit dem Laptop gearbeitet, so muss immer sichergestellt werden, dass die Versorgung
des Laptops potentialgetrennt ist. Ein Kurzschluss der Schaltung oder Probleme mit der USBSchnittstelle können hier auftreten.
6
2 Änderungen
2.1 Einige Worte zur FFT: Schnelle Fouriertransformation
Die Fouriertransformation ist ein Verfahren in der Signalverarbeitung, das Signale von der
Darstellung {(Zeitpunkt, Abtastwert)} in die Darstellung {(Frequenzanteil, Amplitude,
Phase)} überträgt. Viele Operationen, z.B. Filterung, lassen sich im Frequenzraum leichter als
im Zeitraum durchführen. Nach der Transformation ist es möglich das Signal mit der inversen
Fouriertransformation wieder zurück zu transformieren.
In der Digital Technik werden zeitdiskrete Signale (Samples) verarbeitet. Das
Transformationsverfahren für diese Art von Signale heißt DFT Diskrete FourierTransformation. Da nun die Amplituden und Phasen der einzelnen Schwingungen gezielt
analysiert werden können, ist die DFT in der digitalen Signalverarbeitung wichtig. Zudem
gibt es schnelle Algorithmen zum Durchführen der Transformation und ihrer Inversen. Am
bekanntesten ist die FFT (Fast Fourier Transformation), die schnelle Fourier- Transformation
nach James Cooley und John W. Tukey. Die Beschleunigung gegenüber der direkten DFT
Berechnung beruht darauf, schon berechnete Zwischenergebnisse schnell zusammenzusetzen.
Dieser Algorithmus ist ein klassisches „Teile-und-herrsche-Verfahren“. Voraussetzung für
seine Anwendung ist, dass die Anzahl der Stützstellen eine Zweierpotenz ist. Da die Anzahl
solcher Punkte im Allgemeinen frei gewählt werden kann, handelt es sich dabei nicht um eine
gravierende Einschränkung.
2.2 Wie Arbeitet der Algorithmus?
Das Problem der Berechnung einer DFT der Größe 2n wird in zwei Berechnungen der DFT
der Größe n aufgeteilt, der Vektor der Messwerte wird in Teilvektoren zu geraden bzw.
ungeraden Indizes aufgeteilt und von beiden die DFT bestimmt. Die beiden Teilergebnisse
werden dann wieder zu einem Gesamtergebnis zusammengefügt. Zur Berechnung der beiden
Hälften werden die Eigenschaften der Einheitswurzeln aus der Fouriermatrix genutzt. Eine
rekursive Anwendung dieser Grundidee ermöglicht schließlich eine Berechnung in nlog(n)
Schritten.
2.3 Der Goertzel-Algorithmus
2.3.1 Motivation
Der Goertzel-Algorithmus wurde in diesem Semester als neues Modul eingesetzt. Die
theoretischen Grundlagen werden in den folgenden Abschnitten erläutert, sowie der Bezug
zur DPOAE Messung anhand einer beispielhaften Anwendung graphisch dargestellt.
Dieser Algorithmus bietet eine sehr schnelle Möglichkeit der Frequenzdarstellung, wenn die
Anzahl der zu betrachtenden Punkte klein ist. Anders als bei Berechnungsmethoden der DFT
(diskrete Fouriertransformation), welche immer alle diskreten Spektralkomponenten in einen
Block berechnen, ist es mit dem Goertzel-Algorithmus möglich, nur einzelne diskrete
Spektralanteile zu ermitteln.
7
2.3.2 Herleitung
Viele Anwendungen brauchen die Bewertung von nur wenigen Frequenzen. Wenn man die
DFT als N parallel geschaltete Bandpassfiltern betrachtet, ist der Goertzel-Algorithmus die
Berechnung von nur einzelnen Bandpässe.
Die DFT ist für N Punkte definiert als:
Aufgrund der notwendige Periodizität gilt:
Damit wird folgende Multiplikation gültig:
Das Ergebnis unter Betrachtung von Kausalität und endliche Anzahl von Samples hat die
Form einer Multiplikation mit dem Einheitssprung:
deshalb gilt:
Der Ausdruck für yk hat die Form einer diskreter Faltung der Folge x[n], 0 ≤ n ≤ N-1 mit der
Folge
.
yk[n] ist also die Antwort eines Systems mit der Übertragungsfunktion
auf die
Zahlenfolge x[n]. Der Nte Wert der Ausgangsfolge yk[n] entspricht dabei dem Wert der kten
Spektrallinie der DFT.
8
Solch ein Filter hat die Struktur:
Abbildung 3: Goertzel erster Ordnung
Um den
Anzahl
der
Multiplikationen weiter
Übertragungsfunktion mit den Faktor
reduzieren
zu
können,
wird
die
multipliziert.
Welches einem System zweiter Ordnung entspricht.
Abbildung 4 Goertzel zweiter Ordnung
9
2.3.3 Vergleich der Berechnungsaufwand
Der Goertzel Algorithmus ist ein sehr schnelles Verfahren, wenn die Anzahl von Punkten
klein ist. Umso mehr diese Zahl steigt, desto aufwendiger wird die Berechnung.
DFT
N2
kompl. Mult.
N(N -1) kompl. Add
FFT
Nlog2(N) kompl. Mult.
Nlog2(N) kompl. Add.
Goertzel
(pro Frequenzpunkt)
2(N+2) reelle Mult.
4(N+1) reelle Add.
Tabelle 1: Vergleich Aufwand DFT, FFT, Goertzel
2.3.4 Goertzel und die DPOAE Messung
Für die Auswertung einer DPOAE Messung ist nur eine begrenzte Anzahl von Frequenzen
von Interesse. Diese Frequenzen sind die Anregungsfrequenzen F1 und F2 und insbesondere
die Beziehungen: F2 –F1, 2F1 – F2, 2F2 – F1, 3F1 – F2.
Wichtig für eine präzise Darstellung ist, dass die Anregungsfrequenzen F1 und F2
ganzzahlige Perioden eines Buffers (Zweierpotenz, z.B. 8192 Samples) entsprechen.
Ist diese Bedingung erfüllt, so wird sie ebenso für die genannten Frequenz- Beziehungen
garantiert.
Nach dieser Eigenschaft sind F1 und F2 durch folgende Formel zu ermitteln:
Wobei n die Anzahl von Perioden entspricht.
2.3.5 Graphische Darstellung eines Beispiels
Folgende Bilder wurden mit Hilfe von Matlab, anhand einer beispielhaften Anwendung mit
den Anregungsfrequenzen F1 und F2 erstellt:
F1 = 1669.92 Hz
F2 = 2003.9 Hz
F3 = 2F1 –F2 = 1335.94 Hz
F4 = 3F1 -2F2 = 1001.96 Hz
F5 = F2 – F1 = 333.98 Hz
F6 = 2F2 – F1 = 2337.9 Hz
10
Abbildung 5 Darstellung der Summe der Signale mit Frequenzen F1 bis F6
Abbildung 6 Frequenzdarstellung mit FFT
11
Abbildung 7 Frequenzdarstellung durch Goertzel
12
3 Analyse der ADC-Platine
Als wichtigste Komponent des Projektes muss der ADC getestet werden, ob es für die
DPOAE geeignet ist.
3.1 Rauschverhalten
Als erstes wird das Rauschen am Eingang des ADC gemessen, wenn keine Signale anliegen.
Abbildung 8: Rauschen des ADC, wenn keine Signale anliegen
Wir sehen in Abbildung 8, dass es Rauschen gibt durch EMV-Einflüsse und dass diese bis
8,5mV betragen kann. Die FFT wird in der unteren Abbildung berechnet.
13
Abbildung 9: FFT des Rauschen mit single-FFT
Die Abbildung 9 zeigt deutlich, dass das Rauschen die 50Hz-Netzfrequenz besitzt. Eine
Abschirmung kann die Messung des Audiosignals somit verbessern.
Als nächstes erzeugen wir mit dem DDS ein Signal mit dem Volumen von 0 und eine
Frequenz von 0Hz. Die Netzeinwirkung auf der DDS-Platine kann einigermaßen bestimmt
werden.
Abbildung 10: Netzeinwirkung auf der DDS-Platine
Hier sehen wir die Netzeinwirkung auf der DDS-Platine. Das Signal hat eine Amplitude von
0,1V und hat eine Frequenz von 50Hz. Speist man zwei Signale mit der Frequenz f1 und f2
14
ins Ohr der Versuchspersonen, so erhalten wir zweimal dieses Rauschen. Eine Abschirmung
(Platinen in Gehäuse einbauen) oder der Batteriebetrieb kann hier das Ergebnis verbessern.
3.2 Umrechnung des ADC-Ergebnisses auf Volt
Es wurde versucht das Ergebnis der AD-Wandlung auf Volt um zu rechnen, um es besser
darstellen zu können. Wie in Kapitel 1.2.2 Falsche Umrechnung von ADC-Wert auf
Spannungswert beschrieben wurde, ist die Umrechnung nicht ganz richtig und soll korrigiert
werden.
In einem Versuch wird ein Signal durch den DDS erzeugt mit vbass = 246.
Die minimale und maximale Spannung betragen -2,098V und 2.11V.
Das Sinussignal wird mehrmals aufgenommen um das Verhältnis Float/Volt zu bestimmen:
vbass=246
erste Aufnahme
max. Spannung 5362058
2.110V
min. Spannung -5728233
-2.098
zweite Aufn.
5353203
dritte Aufn.
5357630,5
Mittelwert
5357630,5
-5737719
-5732976
5732976
Tabelle 2: Messdaten für Umrechnung
2.11V − ( −2, 098V ) = 4, 208V
Spannungsbereich
=
,
1V = 2635600,40
Ergebnisbereich( ADC ) 5357630,5- ( -5732976 ) = 11090606,5
Nach kurzer Rückrechnung können wir ein Offset bestimmen, was durch die ADC-Schaltung
verursacht wird: Offset = -203486,35.
Nach dem Aufnehmen von Audiosignalen wird dieses Offset immer abgezogen.
ADC_start();
//
TSK_sleep(1000);
LOG_printf(&LOG0,"vor schleife: %i", SEM_count(&SEM_PING_PONG));
for(i = 0; i < 6 ; i++)
{
LOG_printf(&LOG0,"iteration %i: %i", i, SEM_count(&SEM_PING_PONG));
SEM_pend(&SEM_PING_PONG,SYS_FOREVER);
for(n = 0; n < BUFFSIZE; n++)
{
bRawData[i*BUFFSIZE + n] = (float) p_BufferRcvData[n];
LOG_printf(&LOG0,"iteration %i:", n);
}
}
ADC_stop();
// hier wird das Ergebnis korrigiert, da der ADC-Platine ein Offset hat.
// Also Offset aufaddieren, und mit dem Verhältnis multiplizieren um Spannung zu bekommen
// Der Recorder beginnt erst nach 147 Werten richtig auf zu nehmen
// wenn dieser Fehler nicht beseitigt wird, muss ein Shiftverfahren durchgeführt werden
for(n = 0; n < 6*BUFFSIZE-146; n++)
{
temp = bRawData[n];
bRawData[n] = (bRawData[n+146] +203486.35)/2635600.40;
bRawData[n+146] = temp;
}
Tabelle 3:Quelltext von dev_recorder.c (Offset wird vom Audiosignal subtrahiert)
Da unsere Rechnung sich auf die Spannung des DDS-Ausganges bezieht, erhalten wir ein
Offset, was die Wirkung der Filterschaltung und der Eingangsbegrenzungsschaltung vor der
ADC darstellt. Diese Einwirkung ist frequenzabhängig und bleibt nicht konstant wie wir
15
berechnet haben. Wir nehmen aber an, dass das Offset sich nicht stark mit der Frequenz
ändert. Der Fehler bei der Umrechnung wird unsere Ergebnisse nicht groß verfälschen.
3.3 Testaufnahme / Nachbildung der DPOAE-Umgebung
Zu einer praktischen Durchführung am Ohr sind wir nicht mehr gekommen. Als Nachbildung
einer DPOAE-Umgebung haben wir ein Netzwerk aufgebaut. Wir erzeugen mit dem DDS
drei Sinussignale mit der gleichen Amplitude aber unterschiedliche Frequenz (f1=1669.92Hz,
f2=2003.9Hz, f3=1335.94 Hz). Diese Signale werden in dem Netzwerk geführt. Die Signalen
mit der Frequenz f1 und f2 (1699, 2000) werden ungehindert durchgelassen und das Signal
mit der Frequenz f3 wird gedämpft. Schickt man die Signale mit den Frequenzen f1 und f2 in
das Ohr, so wird es auch mit einem so stark gedämpften Signal antworten mit der Frequenz
f3.
Das Netzwerk simuliert also das Ohr und leitet die drei Signale weiter an das ADC.
Das Ergebnis der Aufnahme sehen wir in der nächsten Abbildung.
Abbildung 11: Zeitsignal des Netzwerkes für die DPOAE
16
Abbildung 12: FFT des Netzwerkes für die DPOAE
Wir sehen in der Abbildung 12, dass das dritte Signal (die Antwort des Ohres) sehr klein ist,
was zu erwarten war. Man kann es dennoch in dB-Darstellung deutlich erkennen. Es zeigt
somit, dass die Schaltung generell funktioniert.
Ein ähnliches Ergebnis sehen wir auch mit dem Görtzel-Algorithmus. Der GörtzelAlgorithmus nutzt hier den Vorteil, dass wir alle Frequenzen kennen und ist somit deutlich
schneller.
Abbildung 13: Görtzel-Algorithmus für die DPOAE
Bei der Analyse ist es erstmal entscheidend, dass wir alle Frequenzanteile sehen können und
dass die Verhältnisse einigermaßen stimmen.
17
4 Neuerungen
4.1 LCD-Anzeige
4.1.1 Vorbemerkungen
Am Anfang des Projekts gab es den Gedanken für die Weiterentwicklung der bestehenden
DPOAE-Hardware eine LCD-Anzeige anzuschließen, womit die Messergebnisse oder evtl.
Fehlermeldungen unabhängig von einem PC angezeigt werden könnten.
Zu diesem Zweck wurde eine alte LCD-Anzeige von einem Telefongerät besorgt, welche
einen 2x20 Zeichen-Bildschirm und einen HD44780U-Controller besitzt und diese über einen
Seriell/Parallel-Umwandler an die als SPI-Interface initialisierte McBSP0-Schnittstelle
angeschlossen.
4.1.2 Hardware
4.1.2.1 Überblick
An sich ist es eine leichte Aufgabe, die Anzeige über einen vorhandenen LCD-Controller
anzusprechen, wenn dazu genügende (in unserem Fall mindestens 6) GPIO-Pins vorhanden
sind. Zwar konnte man bei der bestehenden Hardware über die USB-Platine an die 6-Pins des
McBSP0, die man auch als GPIO-Pins initialisieren kann, rankommen, aber so eine
Anwendung wäre Verschwendung von Mitteln. Deshalb wurde die McBSP0 als SPI-Interface
initialisiert, dafür eine geeignete Interface-Schaltung mit einem 8Bit-Serial-In-Parallel-Out
Schieberegister aufgebaut und diese in ein Gehäuse untergebracht. Auf diese Weise ist die
Anzahl der für die Ansteuerung der Anzeige benötigten Pins auf 3 gesunken.
Abbildung 14: Blockschaltbild der aufgebauten Hardware
4.1.2.2 HD4478U-LCD Controller
Der Datenbus kann bei diesem Controller 4-Bit oder 8-Bit groß sein. In dieser Anwendung
wurde der 4-Bit-Datenbus benutzt. Diese 4 Datenleitungen werden nachstehend als DB7-DB4
bezeichnet, wobei DB7 dem MSB und DB4 dem LSB entspricht. Dennoch werden 3 ControlLeitungen, die als RS, EN und R/W genannt werden, benutzt.
Dabei ist EN die Enable-Leitung. Um auf den Beginn einer Datenübertragung hinzudeuten,
wird diese Leitung auf High gebracht. Wenn die Übertragung beendet worden ist, wird sie
wieder auf Low gebracht. Für EN ist der Transmit-Frame-Select-Pin (FSX) von der McBSP0Schnittstelle geeignet, die am Anfang des Schreibprozesses auf High und am Ende auf Low
gebracht wird.
18
RS ist die Register-Select-Leitung. Diese gibt an, ob das Daten-Byte als Kommando
behandelt (RS auf Low) oder als Text auf dem Display (RS auf High) angezeigt werden muss.
RW ist die Schreib/Lese-Leitung. Wenn diese Leitung auf Low gebracht ist, werden die Daten
auf dem Bus in das ausgewählte Register geschrieben. Wenn diese Leitung auf High steht,
können Daten von dem LCD Controller gelesen werden, um den Status des Controllers zu
überprüfen. Bei dieser Anwendung wird die RW-Leitung auf Masse gesetzt und anstatt den
Status des Controllers zu überprüfen, wird nach jedem Schreibprozess auf den Ablauf von der
längst möglichen Zeitdauer gewartet, die der Controller für den jeweiligen Befehl benötigt.
Für nähere Informationen zum Timing des Controllers wird an dieser Stelle auf [XX]
(HD44780U Manual) verwiesen. Bei dieser Anwendung muss man jedoch beachten, dass der
zeitliche Abstand zwischen dem Setzen von Datenleitungen mit entsprechenden Bits und der
fallenden Flanke von dem Enable-Bit zumindest 80ns betragen muss. Diese Anforderung ist
leicht erfüllt, wenn das SPI-Interface mit einer Taktfrequenz von 12.5Mhz oder niedriger
betrieben wird.
4.1.2.3 Schieberegister
In diesem Baustein soll die Seriell-Parallel-Wandlung des vom DSP übertragenen
Datenstromes vollzogen werden. Hierbei wurde ein 8-Bit Serial-In-Parallel-Out
Schieberegister benutzt. Abbildung 15 zeigt das Funktionsdiagramm des Bausteins.
Abbildung 15: Funktionsdiagramm eines 74HCT164-Bausteins
Das Schieberegister wird an einem von seinen beiden seriellen Dateneingängen mit den
Datenimpulsen vom McBSP belegt. Die Taktimpulse bekommt er vom CLKX-Pin. Auf diese
Weise werden die Daten am Eingang des Registers bei jedem Takt um je ein Bit eine Stelle
(ein Flip-Flop) weitergerückt. Am Ende von einer 8-Bit Datenübertragung erhält man das
gewünschte Bitmuster an den 8 Ausgängen des Registers.
Abbildung 16 zeigt die gesamte Interface-Schaltung.
19
Abbildung 16: Interface-Schaltung für LCD
4.1.3 Software
4.1.3.1 McBSP
Wie schon vorher erwähnt, wird die McBSP-Schnittstelle in dieser Anwendung als SPI
Interface initialisiert. Dies geschieht, indem man verschiedene Register richtig initialisiert.
Zur Initialisierung des SPI Interfaces kann die Funktion SPI_init() verwendet werden. Diese
benötigt jedoch noch die Funktion ConfigMcbsp(). Diese setzt die Register des McBSP so,
dass es danach als SPI Interface verwendet werden kann. Die wichtigsten Elemente von
diesen Registern bei dieser Anwendung sind nachfolgend aufgelistet:
20
Mit CLXP wird angegeben, dass das Clocksignal vor und nach dem Datenübertragung inaktiv
ist und dass mit jeder steigenden Flanke des Clock SCKL ein Bit durch den McBSP gelesen
wird. Durch FSXP wird dafür gesorgt, dass das als Enable-Bit benutzte Frame Signal vor und
nach dem Sendeprozess auf Low steht. CLKXM legt fest, dass SCLK auf der DSP-Seite ein
Output ist (getrieben durch CLKG) und somit der DSP die Rolle des Masters übernimmt.
Durch die Konfiguration von CLKSTP wird eingestellt, dass das Clock-Signal mit halber
Takt-Verzögerung nach dem Daten-Signal gestartet wird.
Der McBSP-Clock-Stop-Modus benötigt einphasige Rahmen, deshalb wird XPHASE auf 0
gesetzt. Dennoch wird wird durch XWDLEN1 die Größe dieses Rahmen festgelegt und durch
XCOMPAND wird angegeben, dass das MSB zuerst geschickt wird.
FSGM gibt an, wann das Frame Synchronization Signal erzeugt werden soll und CLKSM
bestimmt, welche Clock für den Sample Rate Generator benutzt wird.
Als letztes gibt der Parameter CLKGDV an, durch welchen Wert der Eingangstakt (CPUClock/2) geteilt wird. Zu beachten ist, dass durch den angegebenen Wert plus eins geteilt
wird. Man hat durch das Aufrufen von SPI_init() die Möglichkeit, die SPI-Clock-Frequenz
erneut einzustellen.
Außer die Konfiguration von einzelnen Registern werden bei der Initialisierung die in der
[XX] (spru580g McBSP Manual – Seite 61) angegebene Schritte durchgeführt. Auf diese
Weise erhält man folgendes SPI Timing, welches für die Benutzung des Schieberegisters
geeignet ist:
Abbildung 17: SPI Timing
Nach dieser Initialisierung können Daten gesendet werden.
21
Wie man auch mit Hilfe der Abbildung 16 nachvollziehen kann, wird für das Ansprechen der
5 Pins, die an dem Schieberegister angeschlossen sind (RS, DB7-4), das folgende ByteMuster verwendet:
Xx
RS
xx
xx
DB7
DB6
DB5
DB4
Zum Beispiel, um nur RS und DB4 auf High und die Anderen auf Low zusetzen wird
folgende Befehl aufgerufen:
SPI_write(0x41);
4.1.3.2 LCD Treiber
Bevor die Anzeige benutzt werden kann, muss sie initialisiert werden. Dies geschieht durch
void lcd_init(void). Die benötigten Initialisierungsschritte und Kommandos, wie Clear
Display, New Line, usw. sind im Dokument [XX] (HD44780U Manual) erklärt worden. Bei
der Initialisierung wird vor allem an den LCD-Controller gegeben, dass das LCD in 4-BitInterface angesteuert wird. Dabei werden mit Hilfe von der Funktion void
lcd_send_byte(int regadd, char data) einzelne Bytes in zwei 4-Bit-Paketen an das
LCD geschickt.
22
Um nach der Initialisierung die Anzeige direkt anzusprechen, sind Funktionen wie, void
lcd_gotoxy(int x, int y), void lcd_putc(char c), void lcd_puts(char *s) oder
void lcd_write_float(char *s,unsigned int i) vorhanden. Aber die Verwendung
von diesen Basis-Funktionen könnte zu unerwünschten Wartezeiten waehrend der
Durchführung von wichtigen Prozessen führen. Deshalb wurde ein Task von niedrigster
Priorität void lcd_mainTSK(void)und zwei Funktionen void lcd_send_float(float*
buf, unsigned int mBytes) sowei void lcd_send_message(char* msgtext)
implementiert, welche es ermöglichen das LCD durch eine “Mailbox” anzusteuern. Diese
Mailbox-Eigenschaft des DSP-Bios ist im Grunde genommen nichts anderes als ein
Semaphor. Der einzige Unterschied liegt darin, dass man dabei auch eine Nachricht senden
kann. Durch diese Eigenschaft wird das gesendete String erst dann angezeigt, wenn
lcd_mainTSK() durchgeführt wird oder anders gesagt, wenn der DSP nichts Wichtigeres zu
tun hat.
23
4.2 GUI
4.2.1 Einleitung
Um das DPOAE-Gerät einfach von einem PC aus steuern zu können und die auszuwertenden
Daten grafisch darstellen zu können, benötigt man sowohl eine GUI - eine grafische
Benutzeroberfläche - als auch eine Verbindung zwischen PC und DSP. Beides lag bereits aus
den letzten Semestern vor. Die Verbindung wird über USB realisiert wobei DSP-seitig ein
USB-Chip vorliegt und PC-seitig über einem bestimmten Treiben eine virtuelle COMSchnittstelle benutzt wird.
Die GUI, die in C++ unter Microsoft Visuell Studio geschrieben wurde und auf einige
zusätzlich Klassen zur Vereinfachung der Kommunikation über den virtuellen COM-Port
basierte, funktionierte jedoch nicht einwandfrei und wird deshalb neu implementiert.
24
Dazu benutzen wir als Programmiersprache ebenfalls C++, im Gegensatz zu unseren
Vorgängern aber die freie Bibliothek QT der Firma trolltech (trolltech.com) für die
Oberfläche sowie QextSerial zur einfacheren Anbindung des COM-Ports.
4.2.2 Aufbau
Wie man in Abbildung 18 sieht, besteht die GUI aus einem Menü, einem Konfigurationsteil,
einem Terminal-Fenster und einem Grafikbereich.
Abbildung 18 DPOAE-GUI mit Zeitverlauf
Im Konfigurationsteil können sowohl die Frequenzen, die die DDS-Module erzeugen sollen,
als auch die Frequenzen, die der Goertzel-Algorithmus zu messen hat, sowie deren
Amplituden eingestellt werden. Diese können dann durch die Ausführung eines Menüeintrags
an den DSP übertragen werden. Des Weiteren wird festgelegt, über welchen COM-Port
kommuniziert wird. Zur einfacheren Kommunikation sind Pushbuttons vorhanden, bei deren
Betätigung Befehle gesendet werden (Verbindung herstellen und trennen, Daten aufnehmen,
berechnen, übertragen und anzeigen). Mit den Radiobuttons kann noch angegeben werden,
welche Daten bearbeitet werden (FTT single, FFT mean, Goertzel, Zeitverlauf).
Das Terminalfenster besteht aus einer Befehlszeile zur direkten Eingabe von Befehlen an den
DSP und einem Bereich in dem die Antworten des DSP dargestellt werden.
Im dritten Bereich werden die entsprechenden Daten nach der Übertragung angezeigt. Es
besteht die Möglichkeit Zeitverläufe, Frequenzspektren und die Amplituden bestimmter
Frequenzen nach dem Goertzel-Algorithmus sowohl linear als auch in Dezibel anzuzeigen.
Dabei stehen auf der x-Achse entweder Zeit- oder Frequenzwerte und auf der y-Achse der
Minimal- und Maximalwert der angezeigten Daten als Achsenbeschriftung. Bei der
25
Übertragung der Goertzel-Daten werden nur drei Werte übertragen, die dann in ein leeres
Frequenzspektrum an der entsprechenden Stelle eingefügt werden.
Im Hintergrund werden die angezeigten Daten in folgenden Dateien gespeichert:
Dateiname
in_fft_single.txt
in_fft_mean.txt
in_goertzel.txt
in_time.txt
darin gespeicherte Daten
Frequenzspektrum mit fft sinlge
Frequenzspektrum mit fft mean
Frequenzspektrum mit Goertzel
Zeitverlauf
Tabelle 4: Dateinamen
Wenn man die Verbindung herstellt oder trennt, wird man mit einem Icon im System-Tray
durch einen grünen bzw. roten Kreis und einem jeweiligen Infotext darüber informiert.
Abbildung 19: Systemtray (links: verbunden, rechts: getrennt)
4.2.3 Programmierung
An dieser Stelle soll nicht auf C++ eingegangen werden, da das den Rahmen des
Abschlussberichts sprengen würde. Stattdessen sollen hier einige Funktionsweisen der
benutzten Bibliothek Qt erläutert werden.
4.2.3.1 GUI-Elemente
In der Qt-Bibliothek sind für alle denkbaren GUI-Elemente bereits Klassen vorhanden, die
nur noch eingebunden werden müssen und dann zur Benutzung bereit stehen. Das sind zum
Beispiel Menüs, Pushbuttons, Eingabefelder, Beschriftungen, Grafikfelder,und Checkboxen.
Darüber hinaus gibt es noch zusätzliche Klassen wie Timer und Strings, die besser auf die
anderen Qt-Klassen abgestimmt sind.
Das Einbinden der einzelnen Klassen geschieht in der Header-Datei der eigenen zu
implementieren Klasse mit dem Eintrag
class QPushButton;
oder
#include <QPushbutton>
vor dem Beginn der eigenen Klasse. Danach müssen Elemente, auf die man von allen
Methoden der Klasse aus zugreifen will, unbedingt im Header-File deklariert werden. Zum
Beispiel
QPushButton *pb_verbinden;
In der .cpp-Datei muss das Element dann mit
pb_verbinden = new QPushButton("verbinden");
noch erstellt und in diesem Fall mit einer Aufschrift versehen werden.
Beschriftungen, die nur auf der GUI erscheinen müssen und auf die man nicht weiter
zugreifen muss, brauchen dann auch nur in der .cpp-Datei deklariert werden.
26
QLabel *f1_label = new QLabel("DDS1 Frequenz [Hz]");
Mehrere GUI-Elemente sollten in Layouts zusammengefasst werden. Diese Layouts können
in Tabellenform (QGridLayout), in vertikaler Anordnung (QVBoxLayout) oder horizontaler
Anordnung (QHBoxLayout) sein. Mit der Methode addWidget(QWidget) werden die
einzelnen Elemente dem Layout hinzugefügt. Dabei kann natürlich auch ein Layout ein oder
mehrere andere Layouts beinhalten. Ein Hauptlayout muss schließlich alle anderen Layout
und somit alle Elemente der GUI beinhalten und wird mit dem Befehl
setLayout(Hauptlayout);
als in der Rangfolge höchstes Layout festgelegt.
4.2.3.2 Mechanismen von Signal und Slot
Mit den vorher beschriebenen Anweisungen würden die Elemente zwar auf dem Bildschirm
erscheinen, aber noch keine Funktion erfüllen. Einen Pushbutton beispielsweise könnte man
drücken, es würde jedoch keine Auswirkung haben.
Dafür gibt es in Qt den Signal-Slot-Mechanismus. Wenn man einen Pushbutton klickt wird
das Signal clicked() ausgelöst, was dann mit
connect(pb_verbinden, SIGNAL(clicked()), this, SLOT(verbinden()));
mit einem sogenannten Slot (in diesem Fall verbinden()) verknüpft wird. Ein Slot ist eine
Methode, die im Header-File unter public slots: oder private slots: deklariert sein muss und in
diesem Beispiel jedes Mal nach dem Signal clicked() aufgerufen wird.
4.2.3.3 Methoden
Neben den Slots gibt es unter Qt noch einige andere Methoden mit einer speziellen
Bedeutung. Hierbei soll auf
QSize sizeHint() const;
und
void paintEvent(QPaintEvent *event);
eingegangen werden.
Die erste Methode muss in eigenen Klassen überladen werden, wenn man eine bestimmte
Größe der Elemente der Klasse festlegen will. In unserem Fall soll die Klasse RenderArea,
die den Bereich zur grafischen Darstellung der Signale darstellt, in ihrer Größe begrenzt
werden.
Das geschieht mit
QSize RenderArea::sizeHint() const {
//benötigter Platz
QSize s(1024,220);
return s;
}
Die zweite Methode muss überladen werden, wenn man eigene Grafiken (Punkte, Linien)
darstellen will. Diese Methode wird dann nicht nur abgearbeitet, wenn man sie mit update()
aufruft, sondern auch wenn die Maus oder anderen Fenster über den eigenen Grafiken bewegt
werden und somit Teile davon löschen. In unserem Fall wird dann jedes Mal der Vektor, der
die Zeit- oder Frequenzdaten anhält, neu in den entsprechenden Bereich geplottet.
27
4.2.4 Kommunikation mit dem DSP
Damit von den eigenen Klassen besonders einfach auf die serielle Schnittstelle und somit auf
den DSP zugegriffen werden kann, benutzen wir zusätzlich die Klasse QextSerialPort. Im
Programm wird ein Objekt dieser erzeugt, mit dem ausgewählten COM-Port verknüpft,
spezielle Eigenschaften für die Übertragung festgelegt und der Port schließlich geöffnet:
comport->setName("COM1");
comport->setBaudRate(BAUD115200);
comport->setDataBits(DATA_8);
comport->setParity(PAR_NONE);
comport->setStopBits(STOP_1);
comport->setFlowControl(FLOW_HARDWARE);
comport->setTimeout(0,20);
comport->open();
Wenn die Verbindung hergestellt ist, wird über einen Timer alle 10ms der Slot empfangen()
aufgerufen, um zu prüfen, ob Daten bereit stehen und empfangen werden können.
Will man Zeit- oder FFT-Daten empfangen, wird der normale Empfangstimer deaktiviert und
ein zweiter Timer aktiviert, der dann die Daten schneller empfangen kann und im Anschluss
weiterverarbeitet, speichert und für die Anzeige bereit stellt.
4.3 Notch-Filter
Die Einsetzung eines Notch-Filters zur Unterdrückung von Netzstörungen wurde auch in
diesem Semester berücksichtigt, aus zeitlichen Gründen wurde aber dieses Modul leider nicht
vollständig optimiert.
4.3.1 Theoretischen Grundlagen
Ein Notch-Filter ist ein schmalbandiger Filter, der meistens zur Unterdrückung von Störungen
eingesetzt wird. Er besteht aus zwei Passbänder und einen Bandsperren Bereich.
Abbildung 20 Typische Notch-Filter Blockdiagramm
Eine Implementierung mit Digitaltechnik ist durch IIR (Infinite Impulse Response) Filter
möglich. Diese Struktur hat die Form:
28
Abbildung 21 IIR Filter Direkt Form II
Nachteil diese Art von Filter ist die Empfindlichkeit zum Wortlängen Effekt. Der Grund dafür
ist, dass die gegebene Rekursivität diesen Effekt verstärkt. Darum ist es üblich eine möglichst
geringe Ordnung zu bevorzugen, die in der kaskadierte Form von Stufen zweiter Ordnung
implementiert werden soll.
H ( z) =
b1 + b2 Z −1 + b3 Z −2
a1 + a2 Z −1 + a3 Z −2
IIR Filter zweiter Ordnung
4.3.2 Das Design
Für die DPOAE Messung ist es wichtig, so wenige Verzerrungen wie möglich im
Messbereich zu haben. Deswegen haben wir uns für ein Notch Filter 2. Ordnung entschieden,
da Filter höhere Ordnungen größere Phasenverzerrungen verursachen.
Es wurde ein Filter entwickelt, der eine Center- Frequenz von 50 Hz und eine Bandbreite von
40Hz hat.
29
Abbildung 22 Frequenzgang eines Notch Filters zur Unterdrückung von Brummstörungen
Die Koeffizienten wurden mit Hilfe von Matlab in den 32 Bit Floating Point Format erstellt
und in einen Algorithmus der Direkt Form I implementiert.
Anhand eines Beispiels wird die Einsetzung graphisch dargestellt.
Abbildung 23 Drei Frequenzen plus 50 Hz Brummen vor Einsetzung des Filters
30
Abbildung 24 Drei Frequenzen plus 50 Hz Brummen nach Einsetzung des Filters
Abbildung 25 Phasen und Frequenzgang des Filters
4.4 Module
Um das Projekt besser zu unterstützen wurden zwei neue Module entwickelt. Diese heißen
„help“ (Hilfe bei Befehlseingabe) und „transfer“ (Übertragung von Daten).
31
4.4.1 Interpreter (kurze Einführung)
Eine Befehlseingabe im Terminal sieht so aus (ohne eckige Klammer):
[devicesname] [functionname]
oder bei Änderung von Parametern
[devicesname] [functionname] [parameter=parametervalue]
Beispiel:
dds change fbass=1000
Der Interpreter sucht zuerst nach, ob das Modul dds schon deklariert wurde oder nicht.
Existiert dieses Modul, so wird nach der Funktion und nach dem Parametername gesucht. Der
Befehl wird ausgeführt, wenn alle Informationen stimmen.
In diesem Beispiel kann man die DDS-Platine ansprechen und die Frequenz für den Bass auf
1000Hz setzen.
4.4.2 Modul „help“(dev_help.c/dev_help.h)
Dieses Modul unterstützt den Benutzer beim Ausführen von Befehlen.
Bei falscher Befehlseingabe wird die Hilfe aufgerufen.
- Wird der Name des Moduls falsch geschrieben, so erkennt der Interpreter nicht, auf
welches Modul der Benutzer zugreifen möchte. In diesem Fall wird die Funktion
help_general aufgerufen, die das Problem näher erläutert.
- Ist der Name des Moduls richtig aber die Funktionsname oder Parameter falsch, so
erkennt der Interpreter das Modul und ruft eine Hilfefunktion aus, die nur das Modul
beschreibt
Die einzelnen Funktionen von help werden nun näher erläutert:
4.4.2.1 help_general
Diese Funktion wird aufgerufen mit dem Befehl „help“.
Automatisch wird sie auch ausgeführt, wenn der Interpreter nicht erkennt, auf welches Modul
der Nutzer zugreifen möchte.
help_general gibt an, dass alle Module aufgelistet werden, wenn man den Befehl devices im
Terminal aufruft. Kennt man die Modulenname, so kann man mit dem Aufruf
help [devicename] eine konkrete Hilfe zu dem Modul bekommen.
Weiterhin weist es auf die Befehle list und func hin, dass sie die Parameter und Funktionen
eines Moduls auflisten.
Zum Schluss wird noch die Funktion help_start vorgestellt, die den Benutzer helfen wird,
Schritt für Schritt die Versuche durchzuführen.
4.4.2.2 help_dds
Diese Funktion wird ausgeführt, wenn der Befehl „help dds“ aufgerufen wird.
Das Modul wird nun erläutert. Mit
- 'dds list'
- listet die Parameter (Frequenz und Volumen) des DDS auf
- 'dds func'
- listet alle Funktionen des DDS auf
- 'dds default' - setzt die Parametern auf default-Werte
- 'dds change [ParameterName]=[ParameterValue]' – setzt den Parameter auf einen
neuen Wert
- 'dds off'
- schaltet den DDS aus
32
-
'dds dpoae'
- startet den DDS und Sinustöne werden erzeugt
4.4.2.3 help_fft
Diese Funktion wird aufgerufen mit dem Befehl „help fft“
Hier wird gezeigt, welche Funktionen das Modul fft besitzt:
- 'fft mean'
- berechnet die FFT mit der mean-Methode
- 'fft single'
- berechnet die FFT mit der single-Methode
- 'fft goertzel' - berechnet die FFT mit dem Görtzel-Algorithmus
- 'fft gchange [frequenz]=[value]' – ändert die Stützfrequenzen frequenz1,2 oder 3 für
den Görtzel-Algorithmus
4.4.2.4 help_recorder
Das Modul recorder generiert oder speichert Daten in das Array bRawData. Auf dieses Array
kann man die FFT durchführen, um den Algorithmus des FFT zu überprüfen. Da wir wissen,
dass die FFT funktioniert, ist die Funktion ‚recorder generate’ jetzt überflüssig.
help_recorder wird aufgerufen mit dem Befehl „help recorder“.
-
'recorder start' - startet die Aufnahme des Audiosignals (speichert auf bRawData)
'recorder generate' – generiert einen Sinusverlauf. Dies dient zur Überprüfung der
FFT.
4.4.2.5 help_getting_started
Diese Funktion ist für neue Benutzer nützlich, denn sie erklärt Schritt für Schritt, wie man den
Terminal benutzt und den Versuch startet.
Mit „help start“ wird diese Funktion aufgerufen:
1. 'devices' eingeben um alle Module aufzulisten
2. 'dds list' eingeben um über alle Parameter einen Überblick zu verschaffen
3. Parametern können geändert werden, z.Bsp. 'dds change fbass=1000'
o Das Volumen des DDS kann in ähnlicher Weise geändert werden (255 ist
maximaler Wert): 'dds change vbass=255'
4. Audiosignal aufnehmen:
o 'recorder start' eingeben um Signal aufzunehmen
5. FFT ausführen um die Antwort des Ohres zu analysieren
o 'help fft' eingeben um mehr Informationen zu FFT zu bekommen
4.4.2.6 help_transfer
Als letzte Funktion ist die Hilfe für das transfer-Modul. Sie wird mit „help transfer“
aufgerufen.
Mit diesem Modul kann man auswählen, welche Daten man zum PC übertragen will.
-
'transfer recorded'
'transfer meanfft'
-
'transfer singlefft'
-
'transfer goertzel'
- überträgt aufgenommenes Audiosignal zum PC
- überträgt das Spektrum, welches durch die Methode der
mean-FFT berechnet wurde (Audiosignal muss vorher
aufgenommen sein)
- überträgt das Spektrum, welches durch die Methode der
single-FFT berechnet wurde
- überträgt das Spektrum, welches durch den
Görtzel-Algorithmus berechnet wurde
33
4.4.3 Modul “transfer” (dev_transfer.c/dev_transfer.h)
Für die Übertragung zum PC dient dieses neue Modul. Man hat zum ersten Mal die
Möglichkeit zu wählen, welche Daten zum PC übertragen werden soll.
Die Daten, die übertragen werden können sind das aufgenommene Audiosignal, die FFTErgebnisse mit der mean- und single-Funktion und die vom Görtzel-Algorithmus berechnete
FFT.
Über einen neuen Task DataTransferTSK wird die Übertragung zum PC gesteuert. Dieser
Task hat eine niedrigere Priorität als der Interpreter. Zurzeit wird eine blockweise
Datenübertragung von 1024 Werten realisiert.
Zukünftige Projekte können an diesem Basis anknüpfen und neue Funktionen einfügen.
Sinnvolle Funktionen sind die Überprüfung des übertragenen Datenblocks auf Fehler, die
wiederholte Übertragung des Datenblocks bei Fehler und die Variation der Blockgröße.
Zum Aufbau:
Der Task wird in terminal.c aufgerufen. Ein globaler String DataNew wird in terminal.c
definiert. Das Modul „transfer“ kann diesen String umbenennen auf „record“, “meanFFT“,
“singleFFT“ oder „goertzel“. Anhand dieses Strings kann der Task erkennen, welche Daten er
übertragen soll. Der Task wird immer gestoppt durch die Semaphore SEM_TRANSFER
(SEM_pend(&SEM_TRANSFER,SYS_FOREVER)).
…
// Datenübertragung
SEM_Obj SEM_TRANSFER;
int Buffer_Start = 0;
int Buffer_End = 1024;
int zaehler = 0;
String DataOld;
String DataNew;
float * DataFloat;
extern float bRawData[6*8192];
extern float dev_goertzel_out[3];
//extern float resultGoertzel[8];
extern float dev_meanFFT_out[8192];
extern float dev_singleFFT_out[8192];
…
void DataTransfer(void)
{
String str;
while(1)
{
SEM_pend(&SEM_TRANSFER,SYS_FOREVER);
if(strcmp(DataNew,"record")==0)
{
DataFloat = bRawData;
Buffer_End = 1024;
}
else if(strcmp(DataNew,"meanFFT")==0)
{
DataFloat = dev_meanFFT_out;
Buffer_End = 1024;
}
else if(strcmp(DataNew,"singleFFT")==0)
{
DataFloat = dev_singleFFT_out;
Buffer_End = 1024;
}
34
//
//
else if(strcmp(DataNew,"goertzel")==0)
{
DataFloat = dev_goertzel_out;
DataFloat = resultGoertzel;
Buffer_End = 3;
}
if (strcmp(DataOld,DataNew)!=0)
{
DataOld = DataNew;
Buffer_Start = 0;
zaehler = 0;
}
if (Buffer_Start == Buffer_End)
{
Buffer_Start = 0;
zaehler = 0;
}
zaehler = Buffer_Start;
usbWriteString("TASK start");
//while(zaehler < Buffer_Start + 1024)
while(zaehler < Buffer_End)
{
sprintf(str,"%.4f ",DataFloat[zaehler]);
// von usbWriteFloatBuffer kopiert
usbWriteString(str);
zaehler++;
}
newline();
usbWriteString(DataNew);
usbWriteString(" von ");
sprintf(str,"%.1f ",Buffer_Start);
usbWriteString(str);
usbWriteString(" bis ");
sprintf(str,"%.1f ",Buffer_End);
usbWriteString(str);
newline();
Buffer_Start = zaehler;
}
}
Tabelle 5: Quelltext des Task DataTransferTSK in terminal.c
Für das Umbenennen des Strings und das Starten der Task sind die unten aufgelisteten
Funktionen verantwortlich.
1. transfer_recorded
- aufgerufen durch den Befehl „transfer recorded“
- setzt den String auf „record“; reset und post der Semaphore
SEM_TRANSFER
2. transfer_meanfft
- aufgerufen durch den Befehl „transfer meanfft“
- setzt den String auf „meanFFT“; reset und post der Semaphore
SEM_TRANSFER
3. transfer_singlefft
- aufgerufen durch den Befehl „transfer singlefft“
- setzt den String auf „singleFFT“; reset und post der Semaphore
SEM_TRANSFER
4. transfer_goertzel
- aufgerufen durch den Befehl „transfer goertzel“
- setzt den String auf „goertzel“; reset und post der Semaphore
SEM_TRANSFER
35
#include
#include
#include
#include
"dpoae0607cfg.h"
"terminal.h"
"dev_transfer.h"
"usb.h"
TDevice transfer;
extern String DataNew;
extern SEM_Obj SEM_TRANSFER;
void transfer_recorded(void)
{
DataNew = "record";
usbWriteString("Start transfer recorded data.\n\r");
SEM_reset(&SEM_TRANSFER,0);
SEM_post(&SEM_TRANSFER);
usbWriteString("End of transfer of recorded data.");
}
void transfer_meanfft(void)
{
DataNew = "meanFFT";
usbWriteString("Start transfer mean_fft data.\n\r");
SEM_reset(&SEM_TRANSFER,0);
SEM_post(&SEM_TRANSFER);
usbWriteString("End of transfer of recorded data.");
}
void transfer_singlefft(void)
{
DataNew = "singleFFT";
usbWriteString("Start transfer single_fft data.\n\r");
SEM_reset(&SEM_TRANSFER,0);
SEM_post(&SEM_TRANSFER);
usbWriteString("End of transfer of recorded data.");
}
void transfer_goertzel(void)
{
DataNew = "goertzel";
usbWriteString("Start transfer goertzel data.\n\r");
SEM_reset(&SEM_TRANSFER,0);
SEM_post(&SEM_TRANSFER);
usbWriteString("End of transfer of recorded data.");
}
Tabelle 6: Funktionen des Moduls "transfer"
36
5 Abschluss
Die DPOAE ist ein interessantes Projekt und erfordert viel DSP-Programmierung. Softwareund Hardwarekomponente wurde geschaffen. Sind die Fehler und Mängel beseitigt, so kann
der Versuch praktisch umgesetzt werden. Man kann dann sehen, welches Ergebnis unser
Aufbau in der wahren Umgebung liefert. In der durch das Netzwerk simulierten Umgebung
konnte man zumindest sehen, dass der Versuchsaufbau für den praktischen Einsatz bereit ist.
Es kann sein, dass unsere Platine nicht für die DPOAE geeignet ist und verbessert (neu
designt) werden muss.
Funktionen können erweitert oder verbessert werden, wie die GUI, Datenübertragung (Kapitel
4.4.3Modul “transfer” (dev_transfer.c/dev_transfer.h)), Signalaufnahme und die FFT.
Spannende Aufgaben erwartet das nächste DPOAE-Projekt.
37
6 Anhang
6.1 Abbildungsverzeichnis:
Abbildung 1 Aufbau der Ohres _________________________________________________ 4
Abbildung 2: Überblick von Soft- und Hardware___________________________________ 5
Abbildung 3: Goertzel erster Ordnung ___________________________________________ 9
Abbildung 4 Goertzel zweiter Ordnung __________________________________________ 9
Abbildung 5 Darstellung der Summe der Signale mit Frequenzen F1 bis F6_____________ 11
Abbildung 6 Frequenzdarstellung mit FFT_______________________________________ 11
Abbildung 7 Frequenzdarstellung durch Goertzel _________________________________ 12
Abbildung 8: Rauschen des ADC, wenn keine Signale anliegen ______________________ 13
Abbildung 9: FFT des Rauschen mit single-FFT __________________________________ 14
Abbildung 10: Netzeinwirkung auf der DDS-Platine _______________________________ 14
Abbildung 11: Zeitsignal des Netzwerkes für die DPOAE___________________________ 16
Abbildung 12: FFT des Netzwerkes für die DPOAE _______________________________ 17
Abbildung 13: Görtzel-Algorithmus für die DPOAE _______________________________ 17
Abbildung 14: Blockschaltbild der aufgebauten Hardware __________________________ 18
Abbildung 15: Funktionsdiagramm eines 74HCT164-Bausteins ______________________ 19
Abbildung 16: Interface-Schaltung für LCD _____________________________________ 20
Abbildung 17: SPI Timing ___________________________________________________ 21
Abbildung 18 DPOAE-GUI mit Zeitverlauf______________________________________ 25
Abbildung 19: Systemtray (links: verbunden, rechts: getrennt) _______________________ 26
Abbildung 20 Typische Notch-Filter Blockdiagramm ______________________________ 28
Abbildung 21 IIR Filter Direkt Form II _________________________________________ 29
Abbildung 22 Frequenzgang eines Notch Filters zur Unterdrückung von Brummstörungen_ 30
Abbildung 23 Drei Frequenzen plus 50 Hz Brummen vor Einsetzung des Filters _________ 30
Abbildung 24 Drei Frequenzen plus 50 Hz Brummen nach Einsetzung des Filters________ 31
Abbildung 25 Phasen und Frequenzgang des Filters _______________________________ 31
6.2 Tabellenverzeichnis:
Tabelle 1: Vergleich Aufwand DFT, FFT, Goertzel________________________________ 10
Tabelle 2: Messdaten für Umrechnung __________________________________________ 15
Tabelle 3:Quelltext von dev_recorder.c (Offset wird vom Audiosignal subtrahiert) _______ 15
Tabelle 4: Dateinamen ______________________________________________________ 26
Tabelle 5: Quelltext des Task DataTransferTSK in terminal.c________________________ 35
Tabelle 6: Funktionen des Moduls "transfer" _____________________________________ 36
6.3 Literaturverzeichnis
-
Zürcher Hochschule Winterthur „der Goertzel Algorithmus“ 2005
www.wikipedia.de.
Rulph Chassaing “Digital Signal Processing with the C6713” Worcester Polytechnic
Institut. – Wiley Intercience 2005.
www.cnx.org Douglas Jhonsohn IIR Rewiew.
Technische Universität Berlin „Digital Signalverarbeitung in der Akustik“ Prof. Dr.
Michael Moser 1997
38
6.4 Abkürzungen
Abk.
ADC
DDS
DPOAE
DSP
FFT
GUI
Bedeutung
Analog Digital Converter
Direct Digital Synthesizer
Distorsionsprodukte otoakustischer Emissionen
Digital Signal Processor
Fast Fourier Transformation
Graphical User Interface
39
Herunterladen