Ein LCD-Display und eine Tastatur haben wir angesteuert. Was fehlt nun noch zu einer richtigen Multimedia-Maschine?
Eine Sound-Ausgabe! Einen Vorschlag, wie diese zu realisieren ist, macht diese Page. Selbstverständlich ist der 2051 kein DSP. Aber um ein geschwindigkeitsabhängiges Dampflockgeräusch beziehungsweise ein Schnaufen und Zischen bei Lokstillstand zu erzeugen, müßte die Leistung ausreichen. |
Prinzipiell gibt es 2 einfachere Wege zur Tonausgabe: Zunächst währe da die Erzeugung einer bestimmten Frequenz mittels des eingebauten Timers, die dann eine bestimmte Dauer abgespielt wird. Dazu wird der Timer mit der doppelten Frequenz programmiert und der dazu gehörende Interruptkanal aktiviert. Bei jedem Interrupt wird ein I/O mit CPL 'herumgedreht'. Diese Tonerzeugung reicht von der Qualität her nur an die Fähigkeiten des eingebauten Lautsprechers im PC heran. Wer einmal die Soundausgabe von 'Monkey Island I / II' gehört hat, kann die Grenzen dieses Systems einschätzen. Dafür ist z.B. die Umsetzung eines (maximal zweistimmigen, da 2 Timer zur Verfügung stehen) Liedes, dessen Noten bekannt sind, recht einfach: man benötigt nur eine Umsetzungstabelle der Notenwerte in Frequenzen und kann loslegen. Insgesamt ist diese Variante recht trivial. | Die Ansteuerung des Timers findet sich auf einer der
vorhergehenden Seiten beschrieben. Interessanter ist da schon die 2. Variante: Ausgabe eines Samples mit Hilfe eines Digital to Analog - Konverters. Allerdings ist die speicherbare Datenmenge des 2k-FlashROM eigentlich nicht für solche Aufgaben gedacht umd mit 2k grade ausreichend für 0,16 Sekunden bei einer Sampling-Rate von 11025 Hz oder die Hälfte bei 22050 Hz. Höhere Abtastraten währen zwar auch abspielbar, ergeben jedoch bei einem nicht für solche Anwendungen geschaffenen Controller keinen Sinn: dann müßte man am besten gleich auf einen DSP umsteigen, der auch über genügend Leistung für komplizierte Verfremdungen verfügt. zurück zum Anfang |
Zunächst einmal die Hardware: Benötigt wird nur der DA-Konverter und das Experimentierboard, beides
praktischerweise auf der selben Platine untergebracht. Der Konverter besteht im wesentlichen
aus einem Widerstandsnetz, das als Spannungsteiler zwischen Masse und dem Output der I/O-Lines wirkt.
Der Ausgang des Widerstandsnetzes wird durch einen OpAmp in einfacher Verstärkerschaltung verstärkt und deren Ausgang auf
einen Lötstift nach außen geführt, wo man bei Bedarf eine Audioverstärkerschaltung und einen Lautsprecher anschließen kann.
Den Kondensator am Eingang des Operationsverstärkers sollte man zunächst weglassen und über den Lötstift einen
geeigneten Wert ausprobieren, da der Kondensator unter umständen nicht notwendig ist und als Tiefpaß die Qualität
beeinflußt. Da jede Rechteckfrequenz in der Theorie aus unendlich vielen Sinusfrequenzen hoher Frequenz aufgebaut ist
und der Ausgang aufgrund der 'Treppenform' der 8-Bit-Abstufung viele steile Anstiege enthält, ist bei manchen Lautsprechern
eine hohe Frequenz mithörbar. Beim Anschluß von Minaturlautsprechern mit einer Plastiksicke ist ein Kondensator
mit rund 10 nF notwendig, um diesen Effekt zu unterdrücken. Ein größerer Lautsprecher
mit einer Papiersicke ist jedoch träger: bei diesem führt der Kondensator zu Lautstärkeverlust. Um die Schaltung zu eichen, kann man z.B. ein Dreieckssignal mit einem Frequenzgenerator erzeugen, mit der Soundkarte aufnehmen und auf dem 2051 abspielen. Dann kan man auf einem Oszilloskop mitverfolgen, ob man einen Fehler gemacht hat. Im Beispiel zum Download ist eine Dreiecksfrequenz mit 100 Hz enthalten, die von Maximum bis Minimum die gesamte Bandbreite ausnutzt. zurück zum Anfang |
Das Abspielen eines Samples aus dem interen Flash-ROM ist ganz einfach: Man braucht nur ein Byte aus dem Flash holen, überprüfen, ob dies das letzte Byte war und gegebenenfalls den Datenpointer wieder auf den Anfang setzen, und ansonsten das Byte auf dem Datenport des DA-Wandlers ausgeben. Alsdann wird so lange gewartet, bis das nächste Byte auszugeben ist (abhängig von der Samplingrate). Da die Warteperiode bei 11025 Hz über 80 uS und bei 22050 Hz noch 40 uS beträgt und damit ausreichend für einen einfachen Kompressionsalgorithmus ist, ließe sich die speicherbare Abspielzeit weiter steigern. |
Außerdem könnte man die Warteperiode dazu nutzen, über die verbliebenen I/O's Daten aus einem
externen Speicher wie zum Beispiel auf einem großen Flash-Eprom (die dank Massenproduktion inzwischen
recht günstig und mit hohen Speicherkapazitäten zu haben sind) zu holen. Bei einem parallelen Eprom braucht man
nur einen Zähler mit der Anzahl Stellen gleich den Adreßleitungen, über den man jeweils die Adresse weitersetzt, und einen
Datenselektor, der das High- bzw. Lownibble aus dem Datenausgang an den 2051er weitergibt.
zurück zum Anfang |
Um ein Sample aus dem PC in den 2051 zu bekommen, muß man zunächst die WAV-Datei in einem geeigneten Format, also für
dieses Beispiel 11025 Hz Abtastrate, 8 Bit Auflösung und unkomprimiert erstellen. Dann wandelt man sie in ein
Datenfeld um, das in die Assemblerdatei mit $include eingebunden wird. Die Umwandlung erledigt am einfachsten ein kleines
BASIC-Programm. Ich habe WAV-Dateien von Goldwave, einem Sharewareprogramm, benutzt, die die blanken Daten von 02Ch bis
zum mit 00h eingeleiteten Abschlußblock speichert. Da mir das WAV-Format eigentlich unbekannt ist, sind bei anderen Soundeditoren
eventuell Anpassungen vorzunehmen.OPEN "test.wav" FOR BINARY AS #1 OPEN "out.dat" FOR OUTPUT AS #2 DIM q AS STRING * 1 ' eine Byte-Variable erzeugen FOR a = &H2D TO LOF(1) GET #1, a, q ' ein Byte einlesen PRINT #2, " db 0" + HEX$(ASC(q)) + "h" ' in das Datenfeld ausgeben IF q = CHR$(0) THEN END ' aufhören wenn das letzte Zeichen erreicht NEXTNun wird die Assemblerdatei mit dem Datenfeld kompiliert und in den 2051 übertragen. $NOMOD51 $INCLUDE (89C1051.MCU) ser_Baud EQU 4800 ;Startadresse des Codes: org 0h ajmp start ; hier werden die Funktionen eingebunden $INCLUDE (time.inc) ;Stack auf 30h hinter Registerbänke und Bit-Area setzen start: mov sp,#30h mov P3,#0FFh main: mov DPTR,#datenstart strt: ; Byte holen clr a movc a,@a+DPTR ; wenn letzte Position erreicht, wieder von vorn beginnen jz main ; Zähler weitersetzen und ausgeben inc DPTR mov P1,a ; für 11025 Hz Samplingrate einige Zeit warten mov a,#90 acall F_wait_u nop ; zum Anfang zurückkehren ajmp strt ; Daten anhängen datenstart: $include(out.dat) ENDJetzt steht dem ersten Ausprobieren nichts mehr im Wege. Dieses Beispiel findet sich selbstverständlich auch auf der Download-Page. zurück zum Anfang |
Hier finden sich die im Text verstreuten Literaturquellen und Links zum Thema noch einmal zum Nachschlagen und Wiederfinden | |
http://physlab.web2010.com/amr/amf1.htm | 'New Audio Amplifiers' - eine Einführung und Anleitung zum Bau von Audioverstärkerschaltungen |
http://www.hut.fi/Misc/Electronics/audio.html | Tomi Engdahl's Audio and Hifi page - Verstärkerschaltungen |