01signal.com

Normale Kopfhörer an einen digitalen Ausgangspin anschließen und Musik hören

Diese Webseite gehört zu einer Gruppe kleiner Projekte, die die Funktionen des Smart-Zynq-Boards untersuchen.

Dieses Projekt ist auch bei HelloFPGA veröffentlicht, das chinesischen Lesern empfohlen wird.

Einführung

Dieses Tutorial erklärt, wie man normale Kopfhörer an das Smart-Zynq-Board anschließt und Musik hört. Ziel dieses Projekts ist es, die Verwendung eines Xillybus-Datenstroms zu demonstrieren, um kontinuierlich Daten an das FPGA zu senden. Der Verilog-Code, der einen PWM-Modulator implementiert, wird hier ebenfalls gezeigt.

Der hier gezeigte Code ist kein Beispiel dafür, wie ein Audioausgang implementiert wird. Die übliche Methode zur Erzeugung eines analogen Ausgangs ist eine kompliziertere Technik namens Sigma-Delta. Diese Technik lässt sich zwar auf einem FPGA umsetzen, aber der theoretische Hintergrund ist wesentlich schwieriger zu verstehen.

Ein weiterer Nachteil dieser Implementierung ist, dass die Abtastrate (sample rate) ungenau ist (48828 Hz statt 48000 Hz). Das lässt sich leicht beheben, indem man die Frequenz des Takts ändert, den die Logik verwendet. Das Thema der Takterzeugung bzw. Taktmanipulation für diesen Zweck wird hier nicht behandelt, da dieses Beispiel eher auf Einfachheit als auf Genauigkeit ausgerichtet ist.

Die Ausstattung für diese Demonstration ist:

Vorbereitung des Vivado-Projekts

Erstellen Sie ein neues Vivado-Projekt aus der Zip-Datei des Demopakets (demo bundle), also des Boot-Partition-Kits. Öffnen Sie verilog/src/xillydemo.v in einem Texteditor. Löschen Sie den Teil des Codes, der mit „PART 2“ gekennzeichnet ist. Fügen Sie stattdessen den folgenden Codeschnipsel ein:

   /*
    * PART 2
    * ======
    *
    * This code demonstrates a PWM-based audio output
    */

   reg [10:0]   pwm_level, threshold_left, threshold_right;
   reg 		pwm_left, pwm_right;
   reg 		fifo_out_valid;
   wire [31:0] 	fifo_out;
   wire 	fifo_empty;

   wire 	fifo_rd_en = !fifo_out_valid && !fifo_empty;
   wire 	next_word = (pwm_level == 11'h7ff);

   assign J6 = { pwm_right, pwm_left };

   always @(posedge bus_clk)
     begin
	pwm_level <= pwm_level + 1;

	if (next_word && fifo_out_valid)
	  begin
	     // The audio samples are signed integers. Change them to
	     // unsigned by adding 1024.
	     threshold_left <= fifo_out[15:5] + 1024;
	     threshold_right <= fifo_out[31:21] + 1024;
	  end
	else if (next_word) // FIFO's output not valid, keep silent
	  begin
	     threshold_left <= 0;
	     threshold_right <= 0;
	  end

	pwm_left <= (threshold_left > pwm_level);
	pwm_right <= (threshold_right > pwm_level);

	if (fifo_rd_en)
	  fifo_out_valid <= 1;
	else if (next_word)
	  fifo_out_valid <= 0;
     end

   // 32-bit FIFO for audio samples
   fifo_32x512 fifo_32
     (
      .clk(bus_clk),
      // Interface with Xillybus IP core
      .srst(!user_w_write_32_open),
      .din(user_w_write_32_data),
      .wr_en(user_w_write_32_wren),
      .full(user_w_write_32_full),

      // Interface with application logic
      .rd_en(fifo_rd_en),
      .dout(fifo_out),
      .empty(fifo_empty)
      );

   // Send the text "PWM" to reassure that the correct bitstream is used.
   assign user_r_read_32_eof = 0;
   assign user_r_read_32_empty = 0;
   assign user_r_read_32_data = 32'h0a_4d_57_50; // "PWM" + LF

Alternativ können Sie die Datei xillydemo.v von hier herunterladen.

Erzeugen Sie aus dem aktualisierten Projekt eine Bitstromdatei (bitstream), und zwar auf dieselbe Weise, wie Sie es für das Demopaket (demo bundle) getan haben. Kopieren Sie die Bitstromdatei außerdem auf dieselbe Weise auf die TF-Karte. Überschreiben Sie dabei die alte Datei xillydemo.bit mit der in diesem Projekt erzeugten Datei.

Anschließen der Kopfhörer

Verbinden Sie einen 50-Ω- bis 200-Ω-Widerstand mit dem I/O-Pin, der das Audiosignal führt: J6/1 (linker Kanal) oder J6/2 (rechter Kanal). Um J6 zu finden, suchen Sie auf der Rückseite des Smart-Zynq-Boards nach der Aufschrift „Bank 33 VCCIO Vadj“. Die Pinreihe nahe dieser Markierung ist die Stiftleiste, mit der wir arbeiten. J6/1 ist also der Pin, der am nächsten zum HDMI-Stecker liegt.

Verbinden Sie die andere Seite des Widerstands mit der Spitze des Kopfhörersteckers. Dazu kann eine Krokodilklemme verwendet werden.

Verbinden Sie den Schaft des Kopfhörersteckers mit der Masse des Smart Zynq. Die Masse der Stiftleiste liegt an J6/35 oder J6/36. Es ist jedoch nicht empfehlenswert, diese Pins zu verwenden, da sie neben den Pins für die Spannungsversorgung liegen.

Stattdessen kann man auch jeden Pin im Bereich von J6/3 bis J6/34 verwenden. Das FPGA behandelt diese als Ausgangspins und hält sie auf einem logischen Pegel von „0“. Man kann diese Pins daher als Masse verwenden.

Es ist auch möglich, die Masseverbindung herzustellen, indem man eine Krokodilklemme an das äußere Metallteil eines der Board-Steckverbinder anschließt: an den Ethernet-Steckverbinder, den HDMI-Steckverbinder oder einen der USB-Steckverbinder.

Board starten

Schalten Sie das Smart Zynq wie gewohnt ein (oder starten Sie es neu). Im nächsten Schritt stellen Sie sicher, dass die richtige Bitstromdatei (bitstream) in das FPGA (PL-Teil) geladen ist.

Geben Sie an der Shell-Eingabeaufforderung den Befehl „head /dev/xillybus_read_32“ ein. Dieser Befehl liest die ersten Zeilen aus /dev/xillybus_read_32 und gibt das Ergebnis aus:

# head /dev/xillybus_read_32
PWM
PWM
PWM
PWM
PWM
PWM
PWM
PWM
PWM
PWM

Wenn dieser Befehl keine Ausgabe liefert oder die Ausgabe von der oben gezeigten abweicht, ist die falsche Bitstromdatei in Gebrauch.

Abspielen einer Audiodatei

Kopieren Sie eine Audiodatei in das Dateisystem von Xillinux. Mit anderen Worten: Die Audiodatei soll den Befehlen innerhalb des Linux-Systems zur Verfügung stehen.

Die Datei sollte das WAV-Format haben: unkomprimiertes PCM, 2 Kanäle, s16le (das ist fast immer das Format von WAV-Dateien). Die Abtastrate (sample rate) sollte 48000 Hz betragen; 44100 Hz funktioniert aber auch einigermaßen gut.

Eine geeignete Audiodatei kann von diesem Link heruntergeladen werden.

Es gibt verschiedene Methoden, um eine Datei auf ein Linux-System zu kopieren. Zum Beispiel kann man die Datei über das Ethernet-Netzwerk mit folgendem Befehl von einem anderen Rechner in das Home-Verzeichnis von Xillinux kopieren:

$ scp sample.wav root@192.168.1.10:~/

Das funktioniert sowohl in der Eingabeaufforderung von Microsoft Windows als auch in einer Linux-Shell. Ändern Sie die IP-Adresse (im Beispiel 192.168.1.10) in die IP-Adresse des Boards.

Es gibt weitere Methoden, um eine Datei nach Xillinux zu kopieren, zum Beispiel mit NFS oder CIFS.

Sobald die Datei in das Dateisystem von Xillinux kopiert wurde, verwenden Sie folgenden Befehl zum Abspielen der Audiodatei:

# cat sample.wav > /dev/xillybus_write_32

Ersetzen Sie „sample.wav“ durch den Namen der Datei, die Sie abspielen möchten. Der gezeigte Befehl funktioniert, wenn sich die Datei im aktuellen Verzeichnis befindet.

Der Befehl spielt die Datei auf den Kopfhörern ab, bis eine neue Shell-Eingabeaufforderung erscheint. Sie sollten die Musik auf einem Ohr hören (oder auf beiden Ohren, wenn Sie sowohl J6/1 als auch J6/2 mit getrennten Teilen des Kopfhörersteckers verbunden haben).

Sie können diesen Befehl mit CTRL-C in der Mitte abbrechen.

Das war es. Der Rest dieser Seite erklärt, wie das funktioniert.

Wie die Audiodaten zum FPGA gelangen

Der Befehl „cat“ kopiert den Inhalt der Audiodatei (sample.wav) in eine Gerätedatei namens „xillybus_write_32“. In Linux-Systemen ist das die übliche Methode, Daten an einen Hardware-Treiber zu senden. In diesem Beispiel kommuniziert der Treiber mit dem IP-Kern (IP core) von Xillybus. Dadurch werden die Daten an ein FIFO innerhalb der FPGA-Logik gesendet.

Sehen wir uns den zugehörigen Teil des oben gezeigten Verilog-Codes an:

   fifo_32x512 fifo_32
     (
      .clk(bus_clk),
      // Interface with Xillybus IP core
      .srst(!user_w_write_32_open),
      .din(user_w_write_32_data),
      .wr_en(user_w_write_32_wren),
      .full(user_w_write_32_full),

      // Interface with application logic
      .rd_en(fifo_rd_en),
      .dout(fifo_out),
      .empty(fifo_empty)
      );

Das ist eine Instanziierung (instantiation) eines Standard-FIFOs. Eine allgemeine Erklärung, wie ein FIFO funktioniert, finden Sie auf dieser Seite.

Dieses FIFO besitzt drei Ports, die mit dem Einfügen von Daten in das FIFO zu tun haben: din, wr_en und full (voll). Alle drei Ports sind mit dem Xillybus-IP-Kern verbunden. Mit anderen Worten: Die drei Signale (user_w_write_32_data, user_w_write_32_wren und user_w_write_32_full) sind mit einem Modul namens xillybus verbunden. Diese Anordnung erlaubt es dem Xillybus-IP-Kern, Daten in das FIFO zu schreiben.

Xillybus nutzt diese Anordnung, um das FIFO mit den Daten zu füllen, die die Software in /dev/xillybus_write_32 schreibt. Xillybus versucht kontinuierlich, so viele Daten wie möglich in das FIFO zu schreiben, erzeugt aber niemals einen Überlauf (overflow). Es befolgt also das full-Signal (voll) des FIFO.

Zusammenfassend passiert Folgendes:

Simplified data flow diagram for data playback with Xillybus

Alle diese Vorgänge laufen gleichzeitig und kontinuierlich ab.

Weitere Informationen über Xillybus finden Sie in dieser Reihe von Seiten, insbesondere auf dieser Seite.

Wie das Audiosignal erzeugt wird

Die bisherige Beschreibung hat erklärt, wie die Daten zur Anwendungslogik im FPGA gelangen. Nun sehen wir uns an, wie aus den Daten ein Audiosignal wird.

Beachten Sie zuerst diese Zeile im Verilog-Code:

   assign J6 = { pwm_right, pwm_left };

Dieser Zeile zufolge bestehen die beiden Audioausgänge aus pwm_right und pwm_left. Diesen beiden Registern werden folgendermaßen Werte zugewiesen:

   always @(posedge bus_clk)
     begin
	pwm_level <= pwm_level + 1;

 [ ... ]
	pwm_left <= (threshold_left > pwm_level);
	pwm_right <= (threshold_right > pwm_level);
 [ ... ]
    end

Beachten Sie, dass pwm_level ein einfacher Zähler ist. Dieses Register besteht aus 11 Bits, zählt also von 0 bis 2047 und beginnt anschließend wieder bei 0.

Der Wert von pwm_left ist „1“, wenn threshold_left größer als pwm_level ist. Mit anderen Worten: threshold_left wird mit einem Zähler verglichen, der wiederholt alle Zahlen von 0 bis 2047 durchläuft. Je höher der Wert von threshold_left ist, desto länger ist pwm_left auf „1“. Das ist das Prinzip der Pulsweitenmodulation (PWM): Die Länge des Impulses ist linear proportional zum Wert des analogen Signals, das wir erzeugen möchten.

pwm_right funktioniert auf dieselbe Weise im Verhältnis zu threshold_right.

threshold_left und threshold_right enthalten die Daten aus der WAV-Datei, die über den Xillybus-IP-Kern gesendet werden. Wir sehen uns nun im Detail an, wie das geschieht.

Zunächst betrachten wir den Teil der FIFO-Instanziierung, der das Lesen aus dem FIFO betrifft:

      // Interface with application logic
      .rd_en(fifo_rd_en),
      .dout(fifo_out),
      .empty(fifo_empty)

fifo_rd_en ist folgendermaßen definiert:

wire 	fifo_rd_en = !fifo_out_valid && !fifo_empty;

Der Read-Enable des FIFO ist also high, wenn das FIFO nicht empty (leer) ist und wenn fifo_out_valid low ist. Sehen wir uns daher die Definition von fifo_out_valid an:

   always @(posedge bus_clk)
     begin
 [ ... ]
	if (fifo_rd_en)
	  fifo_out_valid <= 1;
	else if (next_word)
	  fifo_out_valid <= 0;
     end

Die Bedeutung von fifo_out_valid ist, dass dieses Register high ist, wenn der Ausgang des FIFO gültig ist. Genauer gesagt ist fifo_out_valid high, wenn der Ausgang des FIFO noch nicht verbraucht wurde. Deshalb wechselt dieses Register einen Taktzyklus nach dem High-Zustand von fifo_rd_en auf high. Es wechselt auf low, wenn next_word high ist. Wie wir unten sehen werden, verbraucht die PWM-Logik den FIFO-Ausgang, wenn next_word high ist.

next_word ist folgendermaßen definiert:

   wire 	next_word = (pwm_level == 11'h7ff);

Zur Erinnerung: pwm_level ist ein Zähler, der alle Werte von 0 bis 2047 durchläuft. Die hexadezimale Darstellung von 2047 ist 7ff. next_word ist also kurz davor high, dass pwm_level wieder auf null zurückgeht.

Wie oft ist next_word high? Die Frequenz von bus_clk beträgt 100 MHz. next_word ist bei jedem Durchlauf von 2048 Taktzyklen genau einmal high. 100 MHz ÷ 2048 ≈ 48828 Hz. next_word ist also etwa 48828 Mal pro Sekunde high.

Ich habe weiter oben erwähnt, dass next_word high ist, wenn der FIFO-Ausgang verbraucht wird. Hier ist der zugehörige Teil des Verilog-Codes:

   always @(posedge bus_clk)
     begin
 [ ... ]

	if (next_word && fifo_out_valid)
	  begin
	     // The audio samples are signed integers. Change them to
	     // unsigned by adding 1024.
	     threshold_left <= fifo_out[15:5] + 1024;
	     threshold_right <= fifo_out[31:21] + 1024;
	  end
	else if (next_word) // FIFO's output not valid, keep silent
	  begin
	     threshold_left <= 0;
	     threshold_right <= 0;
	  end
 [ ... ]
    end

Wir stellen zunächst fest, dass bei next_word high sowohl threshold_left als auch threshold_right neue Werte zugewiesen bekommen. Ist fifo_out_valid low, werden die Werte dieser beiden Register null. Das passiert, wenn keine Daten an das FIFO gesendet werden, sodass es empty (leer) wird.

Ist fifo_out_valid high, enthält der dout-Port des FIFO den Wert eines Audio-Samples. Dieser Wert repräsentiert das analoge Signal der beiden Stereokanäle. Jedes Sample enthält zwei vorzeichenbehaftete Zahlen im 16-Bit-Zweierkomplement.

Das Audio-Sample des linken Stereokanals steht in fifo_out[15:0]. Es ist eine vorzeichenbehaftete Zahl zwischen -32768 und 32767. Die fünf niederwertigsten Bits werden entfernt, daher liegt fifo_out[15:5] im Bereich von -1024 bis 1023. Der Ausdruck „fifo_out[15:5] + 1024“ ist also eine vorzeichenlose Zahl zwischen 0 und 2047. Dieser Zahlenbereich ist für den Vergleich mit pwm_level geeignet.

Dementsprechend erhält threshold_left den Wert null, wenn fifo_out[15:0] gleich -32768 ist. Die Bedingung „threshold_left > pwm_level“ ist dann nie erfüllt, sodass pwm_left dauerhaft low bleibt. Ist fifo_out[15:0] dagegen gleich 32767, erhält threshold_left den Wert 2047. Folglich ist pwm_left fast die ganze Zeit high. Auf diese Weise steuert fifo_out[15:0], wie lange pwm_left bei jedem Impuls high ist. fifo_out[31:16] steuert pwm_right auf dieselbe Weise.

Um den gesamten Mechanismus zusammenzufassen: next_word ist einmal in 2048 Taktzyklen high. Wenn next_word high ist, wird der Ausgang des FIFO übernommen und in threshold_left und threshold_right kopiert. Dabei wird der FIFO-Ausgang verbraucht, sodass fifo_out_valid low wird. Wenn das FIFO also nicht empty (leer) ist, wird fifo_rd_en high, um ein neues Audio-Sample aus dem FIFO zu lesen.

Zur Erinnerung: Der Xillybus-IP-Kern füllt dieses FIFO mit dem Inhalt von sample.wav. Es gibt also einen Datenfluss von Audio-Samples aus sample.wav zu threshold_left und threshold_right. Wie oben erwähnt, ist next_word etwa 48828 Mal pro Sekunde high. Das ist die Abtastrate (sampling rate) dieses Mechanismus.

threshold_left steuert das Zeitverhältnis, in dem pwm_left high ist. Entsprechendes gilt für threshold_right und pwm_right. Schließlich sind pwm_right und pwm_left mit dem Ausgangsport J6 verbunden. Das sind also die Signale, die an der Stiftleiste anliegen.

Beachten Sie, dass bei next_word high zwei Dinge geschehen: Ein Audio-Sample wird verbraucht, und pwm_level beginnt wieder bei null zu zählen. Für jedes Audio-Sample wird also genau ein Impuls erzeugt.

„PWM“ ausgeben

Weiter oben habe ich vorgeschlagen, den Befehl „head /dev/xillybus_read_32“ auszuführen, um sicherzustellen, dass das FPGA die richtige Bitstromdatei (bitstream) enthält. Das erwartete Ergebnis war, dass „PWM“ mehrfach ausgegeben wird. Das wird durch diesen Teil des Verilog-Codes implementiert:

   // Send the text "PWM" to reassure that the correct bitstream is used.
   assign user_r_read_32_eof = 0;
   assign user_r_read_32_empty = 0;
   assign user_r_read_32_data = 32'h0a_4d_57_50; // "PWM" + LF

Wenn Sie sich xillydemo.v in der ursprünglichen Fassung ansehen, stellen Sie fest, dass user_r_read_32_rden, user_r_read_32_data und user_r_read_32_empty mit dem FIFO verbunden waren. Der Xillybus-IP-Kern verwendet diese Signale, um Daten aus einem FIFO zu lesen und als Datenstrom über /dev/xillybus_read_32 verfügbar zu machen.

Vor der Änderung in xillydemo.v waren diese Signale mit demselben FIFO verbunden, in das der Xillybus-IP-Kern schreibt. Das Ergebnis war ein Loopback: Die Software schrieb Daten in /dev/xillybus_write_32, die der Xillybus-IP-Kern zunächst in das FIFO einfügte. Danach las der Xillybus-IP-Kern die Daten aus dem FIFO und stellte sie über /dev/xillybus_read_32 bereit. Dieser Loopback dient als Ausgangspunkt zum Lernen, wie Xillybus funktioniert.

Nach der Änderung in xillydemo.v sind diese Signale vom FIFO getrennt. Stattdessen ist user_r_read_32_data stets 0x0a4d5750, und user_r_read_32_empty ist immer null. Außerdem wird user_r_read_32_rden von der Logik ignoriert. Dadurch entsteht ein imaginäres FIFO, das nie empty (leer) ist. Der Ausgang dieses imaginären FIFO hat immer denselben Wert: 0x0a4d5750. Der Xillybus-IP-Kern verhält sich so, als gäbe es ein FIFO, das ständig mit diesem konstanten Wert gefüllt wäre. Beim Lesen aus /dev/xillybus_read_32 kommt daher wiederholt das Wort 0x0a4d5750 an. Wenn dieses Wort ausgegeben wird, wird es als vier Bytes interpretiert: 0x50, 0x57, 0x4d und 0x0a. Mit anderen Worten: die Zeichen P, W, M und ein Zeilenvorschub (der in Linux das Zeilenende markiert).

Der Zusammenhang zwischen Verilog-Code und echten Pins

Der obige Verilog-Code verbindet die PWM-Signale mit J6. Wie gelangen diese Signale aber zur Stiftleiste? Die Antwort finden Sie in xillydemo.xdc. Diese Datei gehört zu dem Vivado-Projekt, das den Bitstrom erzeugt (im Verzeichnis „vivado-essentials“).

xillydemo.xdc enthält verschiedene Informationen, die erforderlich sind, damit das FPGA als elektronisches Bauelement korrekt funktioniert. Unter anderem enthält diese Datei folgende Zeilen:

[ ... ]

## J6 on board (BANK33 VADJ)
set_property PACKAGE_PIN U22  [get_ports {J6[0]}];   #J6/1  = IO_B33_LN2
set_property PACKAGE_PIN T22  [get_ports {J6[1]}];   #J6/2  = IO_B33_LP2
set_property PACKAGE_PIN W22  [get_ports {J6[2]}];   #J6/3  = IO_B33_LN3
set_property PACKAGE_PIN V22  [get_ports {J6[3]}];   #J6/4  = IO_B33_LP3
set_property PACKAGE_PIN Y21  [get_ports {J6[4]}];   #J6/5  = IO_B33_LN9
set_property PACKAGE_PIN Y20  [get_ports {J6[5]}];   #J6/6  = IO_B33_LP9
set_property PACKAGE_PIN AB22 [get_ports {J6[6]}];   #J6/7  = IO_B33_LN7
set_property PACKAGE_PIN AA22 [get_ports {J6[7]}];   #J6/8  = IO_B33_LP7

[ ... ]

Die erste Zeile besagt, dass das Signal J6[0] mit U22 verbunden werden soll. Dabei handelt es sich um eine Position auf dem physischen Gehäuse des FPGA. Laut den Schaltplänen des Smart Zynq ist dieser FPGA-Pin mit dem ersten Pin der Stiftleiste verbunden. Die Positionen der übrigen Ports sind auf dieselbe Weise festgelegt.

Ich habe oben erwähnt, dass jeder Pin im Bereich von J6/3 bis J6/34 als Masse verwendet werden kann, weil diese Ausgangspins den Wert „0“ haben. Das stimmt, weil J6 laut dieser Zeile am Anfang von xillydemo.v aus 34 Bits besteht:

  inout [33:0] J6,  //BANK33 VADJ

Zur Erinnerung: Die Wertzuweisung an J6 sieht folgendermaßen aus:

 assign J6 = { pwm_right, pwm_left };

Das bedeutet: J6[0] ist gleich pwm_left und J6[1] ist gleich pwm_right. Was ist mit dem Rest? Gemäß der Syntax von Verilog erhalten alle übrigen Bits den Wert null.

Der Gleichspannungsanteil

Die Stiftleiste ist mit den Logikausgängen des FPGA verbunden. Jeder dieser Pins hat bei einem Logikzustand „1“ eine Spannung von ungefähr 3,3 V. Bei einem Logikzustand „0“ beträgt die Spannung ungefähr 0 V.

Wenn der Wert des ursprünglichen Audio-Samples null ist, dann erhalten threshold_left und threshold_right den Wert 1024. Mit anderen Worten: pwm_right und pwm_left sind im Durchschnitt während der Hälfte der Zeit high. Die mittlere Spannung (Gleichspannung) beträgt daher 3,3 V ÷ 2 = 1,65 V. Selbst wenn also die Audio-Samples der WAV-Datei einen perfekten Gleichspannungsausgleich (DC balance) haben, liegt an den Kopfhörern als Gleichspannungsanteil 1,65 V an.

Der Zweck des 100-Ω-Widerstands ist also nicht nur, die Lautstärke zu verringern, sondern auch den Gleichstrom zu begrenzen. Aber selbst ohne den Widerstand ist der elektrische Strom wahrscheinlich ungefährlich, wegen der eigenen Strombegrenzung des FPGA und des elektrischen Widerstands der Kopfhörer. Der Widerstand ist lediglich eine Vorsichtsmaßnahme.

Zusammenfassung

Dieses Projekt hat gezeigt, wie man einen digitalen Ausgangspin nutzen kann, um ein analoges Audiosignal zu erzeugen, das direkt an Kopfhörer angeschlossen werden kann. Der Schwerpunkt dieses Projekts war die Verwendung eines Xillybus-Datenstroms, um Daten von der Software an das FPGA zu senden. Außerdem wurde eine einfache Implementierung einer PWM gezeigt.

Diese Seite wurde maschinell aus dem Englischen übersetzt. Im Zweifelsfall siehe den Originaltext.
Copyright © 2021-2026. All rights reserved. (dcc38493)