- Was ist ein DDS-Funktionsgenerator?
- Verstehen Sie die Funktionsweise des AD9833-Funktionsgenerator-IC
- Erforderliche Komponenten zum Erstellen des AD9833-basierten Funktionsgenerators
- AD9833-basierter Funktionsgenerator - Schematische Darstellung
- AD9833-basierter Funktionsgenerator - Arduino-Code
- Testen des AD9833-basierten Funktionsgenerators
- Weitere Verbesserungen
Wenn Sie ein elektronischer Enthusiast wie ich sind, der mit verschiedenen elektronischen Schaltkreisen arbeiten möchte, ist es manchmal obligatorisch, einen anständigen Funktionsgenerator zu haben. Aber eine zu besitzen ist ein Problem, weil eine solche Grundausstattung ein Vermögen kosten kann. Der Bau eigener Testgeräte ist nicht nur billiger, sondern auch eine hervorragende Möglichkeit, Ihr Wissen zu verbessern.
In diesem Artikel werden wir einen einfachen Signalgenerator mit Arduino und AD9833 DDS-Funktionsgeneratormodul bauen, der Sinus-, Rechteck- und Dreieckswellen mit einer maximalen Frequenz von 12 MHz am Ausgang erzeugen kann. Und schließlich werden wir die Ausgangsfrequenz mit Hilfe unseres Oszilloskops testen.
Wir haben zuvor einen einfachen Sinuswellengenerator, einen Rechteckwellengenerator und einen Dreieckwellengenerator mit Hilfe grundlegender analoger Schaltungen gebaut. Sie können diese überprüfen, wenn Sie nach grundlegenden Wellenformgeneratorschaltungen suchen. Wenn Sie einen günstigeren Arduino-Funktionsgenerator ohne Verwendung des AD9833-Moduls bauen möchten, können Sie sich auch das DIY Arduino Waveform Generator-Projekt ansehen.
Was ist ein DDS-Funktionsgenerator?
Wie der Name schon sagt, ist ein Funktionsgenerator ein Gerät, das beim Einstellen eine bestimmte Wellenform mit einer bestimmten Frequenz ausgeben kann. Angenommen, Sie haben einen LC-Filter, für den Sie Ihren Ausgangsfrequenzgang testen möchten. Dies können Sie problemlos mit Hilfe eines Funktionsgenerators tun. Sie müssen lediglich die gewünschte Ausgangsfrequenz und Wellenform einstellen und dann nach unten oder oben drehen, um die Reaktion zu testen. Dies war nur ein Beispiel, Sie können im Laufe der Liste mehr Dinge damit tun.
DDS steht für Direct Digital Synthesis. Es handelt sich um eine Art Wellenformgenerator, der Digital-Analog-Wandler (DAC) verwendet, um ein Signal von Grund auf aufzubauen. Diese Methode wird speziell zur Erzeugung einer Sinuswelle verwendet. Der von uns verwendete IC kann jedoch Rechteck- oder Dreieckswellensignale erzeugen. Die Operationen, die in einem DDS-Chip ausgeführt wurden, sind digital, sodass die Frequenz sehr schnell oder sehr schnell von einem Signal zum anderen umgeschaltet werden kann. Dieses Gerät hat eine feine Frequenzauflösung mit einem breiten Frequenzspektrum.
Verstehen Sie die Funktionsweise des AD9833-Funktionsgenerator-IC
Das Herzstück unseres Projekts ist der programmierbare Wellenformgenerator-IC AD9833, der von analogen Geräten entworfen und entwickelt wird. Es ist ein geringer Stromverbrauch, programmierbarer Wellenformgenerator erzeugen kann Sinus-, dreieckige und quadratische Welle mit einer maximalen Frequenz von 12 MHz. Es ist ein sehr einzigartiger IC, der die Ausgangsfrequenz und -phase mit nur einem Softwareprogramm ändern kann. Es verfügt über eine 3-Draht-SPI-Schnittstelle, weshalb die Kommunikation mit diesem IC sehr einfach und unkompliziert wird. Das Funktionsblockdiagramm dieses IC ist unten gezeigt.
Die Arbeitsweise dieses IC ist sehr einfach. Wenn wir uns das obige Funktionsblockdiagramm ansehen, werden wir feststellen, dass wir einen Phasenakkumulator haben, dessen Aufgabe es ist, alle möglichen digitalen Werte einer Sinuswelle von 0 bis 2π zu speichern. Als nächstes haben wir das SIN-ROM, dessen Aufgabe es ist, die Phaseninformationen, die später direkt in die Amplitude abgebildet werden können, umzuwandeln. Das SIN-ROM verwendet die digitalen Phaseninformationen als Adresse für eine Nachschlagetabelle und wandelt die Phaseninformationen in Amplitude um. Und schließlich haben wir einen 10-Bit-Digital-Analog-Wandler, dessen Aufgabe es ist, die digitalen Daten vom SIN-ROM zu empfangen und in die entsprechenden analogen Spannungen umzuwandeln, die wir vom Ausgang erhalten. Am Ausgang haben wir auch einen Schalter, den wir mit nur wenig Software-Code ein- oder ausschalten können. Wir werden später in diesem Artikel darüber sprechen.Die Details, die Sie oben sehen, sind eine sehr reduzierte Version dessen, was im IC passiert. Die meisten Details, die Sie oben sehen, stammen aus dem AD9833-Datenblatt. Sie können es auch für weitere Informationen überprüfen.
Erforderliche Komponenten zum Erstellen des AD9833-basierten Funktionsgenerators
Die Komponenten, die zum Erstellen des AD9833-basierten Funktionsgenerators erforderlich sind, sind unten aufgeführt. Wir haben diese Schaltung mit sehr allgemeinen Komponenten entworfen, was den Replikationsprozess sehr einfach macht.
- Arduino Nano - 1
- AD9833 DDS-Funktionsgenerator - 1
- 128 x 64 OLED-Display - 1
- Generischer Drehgeber - 1
- DC Barrel Jack - 1
- Spannungsregler LM7809 - 1
- 470uF Kondensator - 1
- 220 uF Kondensator - 1
- 104pF Kondensator - 1
- 10K Widerstand - 6
- Taktile Schalter - 4
- Schraubklemme 5,04 mm - 1
- Weiblicher Header - 1
- 12V Stromquelle - 1
AD9833-basierter Funktionsgenerator - Schematische Darstellung
Das vollständige Schaltbild für den Funktionsgenerator AD9833 und Arduino basiert unten.
Wir werden den AD9833 mit Arduino verwenden, um unsere gewünschte Frequenz zu erzeugen. Und in diesem Abschnitt werden wir alle Details mit Hilfe des Schaltplans erklären. Lassen Sie mich einen kurzen Überblick darüber geben, was mit der Schaltung passiert. Beginnen wir mit dem AD9833-Modul. Das AD9833-Modul ist das Funktionsgeneratormodul und gemäß Schaltplan mit dem Arduino verbunden. Zur Stromversorgung der Schaltung verwenden wir einen Spannungsregler-IC LM7809 mit einem anständigen Entkopplungskondensator. Dies ist erforderlich, da das Versorgungsrauschen das Ausgangssignal stören und zu einer unerwünschten Ausgabe führen kann. Wie immer arbeitet der Arduino als Gehirn für dieses Projekt. Um die eingestellte Frequenz und andere wertvolle Informationen anzuzeigen, haben wir ein 128 x 64 OLED-Anzeigemodul angeschlossen. Um den Frequenzbereich zu ändern, verwenden wir drei Schalter. Der erste setzt die Frequenz auf Hz, der zweite setzt die Ausgangsfrequenz auf KHz und der dritte setzt die Frequenz auf MHz. Wir haben auch eine andere Taste, mit der der Ausgang aktiviert oder deaktiviert werden kann. Schließlich haben wir den Drehgeber,und wir müssen einen Pull-up-Widerstand daran anschließen, sonst funktionieren diese Schalter nicht, weil wir das Tastendruckereignis bei der Pooling-Methode überprüfen. Der Drehgeber dient zum Ändern der Frequenz und der Tastschalter im Drehgeber zum Auswählen der eingestellten Wellenform.
AD9833-basierter Funktionsgenerator - Arduino-Code
Der vollständige Code, der in diesem Projekt verwendet wird, befindet sich unten auf dieser Seite. Nach dem Hinzufügen der erforderlichen Header- und Quelldateien sollten Sie in der Lage sein, die Arduino-Datei direkt zu kompilieren. Sie können die ad9833 Arduino-Bibliothek und andere Bibliotheken über den unten angegebenen Link herunterladen oder die Board-Manager-Methode verwenden, um die Bibliothek zu installieren.
- Laden Sie die AD9833 Library von Bill Williams herunter
- Laden Sie die SSD1306 OLED Library von Adafruit herunter
- Laden Sie die Adafruit GFX-Bibliothek herunter
Die Erklärung des Codes im Ino. Datei ist wie folgt. Zunächst schließen wir alle erforderlichen Bibliotheken ein. Auf die Bibliothek für das AD9833-DDS-Modul folgt zunächst die Bibliothek für OLED, und für einige unserer Berechnungen wird die Mathematikbibliothek benötigt.
#include // Bibliothek für AD9833-Modul #include
Als nächstes definieren wir alle erforderlichen Eingangs- und Ausgangspins für die Tasten, den Schalter, den Drehgeber und die OLEDs.
#define SCREEN_WIDATA_PINH 128 // OLED-Anzeige Breite in Pixel #define SCREEN_HEIGHT 64 // OLED-Anzeigehöhe in Pixel #define SET_FREQUENCY_HZ A2 // Drucktaste zum Einstellen der Frequenz in Hz #define SET_FREQUENCY_KHZ A3 // Drucktaste zum Einstellen der Frequenz A6 // Drucktaste zum Einstellen der Frequenz in MHz #define ENABLE_DISABLE_OUTPUT_PIN A7 // Drucktaste zum Aktivieren / Deaktivieren der Ausgabe #define FNC_PIN 4 // Fsync, die vom AD9833-Modul benötigt wird #define CLK_PIN 8 // Clock Pin des Encoders #define D_ / Daten-Pin des Encoders #define BTN_PIN 9 // Interner Druckknopf am Encoder
Danach definieren wir alle notwendigen Variablen, die in diesem Code benötigt werden. Zuerst definieren wir einen ganzzahligen variablen Zähler, der den Drehgeberwert speichert. Die nächsten beiden Variablen clockPin und clockPinState speichern die Pin-Statue, die zum Verständnis der Encoderrichtung erforderlich ist. Wir haben eine Zeitvariable, die die aktuellen Timer-Zählerwerte hält, diese Variable für Taste Entprellung verwendet wird. Als nächstes haben wir ein vorzeichenloses langes variables Modul Frequenz, das die berechnete Frequenz enthält, die angewendet werden soll. Als nächstes haben wir die Entprellungsverzögerung. Diese Verzögerung kann nach Bedarf angepasst werden. Als nächstes haben wir drei boolesche Variablen set_frequency_hz,set_frequency_Khz und set_frequency_Mhz Diese drei Variablen werden verwendet, um die aktuelle Einstellung des Moduls zu bestimmen. Wir werden später in diesem Artikel ausführlicher darauf eingehen. Als nächstes haben wir die Variable, die den Status der Ausgangswellenform speichert. Die Standardausgangswellenform ist eine Sinuswelle. Und schließlich haben wir die Variable encoder_btn_count, die die Anzahl der Encoder-Schaltflächen enthält, mit denen die Ausgangswellenform eingestellt wird.
int counter = 1; // Dieser Zählerwert erhöht oder verringert sich, wenn der Drehgeber int clockPin gedreht wird. // Platzhalter für den vom Drehgeber verwendeten Pin-Status int clockPinState; // Platzhalter für den vom Drehgeber verwendeten Pin-Status vorzeichenlose lange Zeit = 0; // Wird zum Entprellen von unsigned long moduleFrequency verwendet; // dient zum Einstellen der Ausgangsfrequenz long debounce = 220; // Verzögerung entprellen bool btn_state; // wird verwendet, um die Deaktivierungsausgabe des AD98333-Moduls zu aktivieren. bool set_frequency_hz = 1; // Standardfrequenz des AD9833-Moduls bool set_frequency_khz; bool set_frequency_mhz; String waveSelect = "SIN"; // Startwellenform des Moduls int encoder_btn_count = 0; // wird verwendet, um das Drücken der Encoder-Taste zu überprüfen. Als nächstes haben wir unsere beiden Objekte, eines für das OLED-Display und eines für das AD9833-Modul.Adafruit_SSD1306-Anzeige (SCREEN_WIDATA_PINH, SCREEN_HEIGHT & Wire, -1); AD9833 gen (FNC_PIN);
Als nächstes haben wir unsere setup () -Funktion. In dieser Setup-Funktion beginnen wir mit der Aktivierung der Serial zum Debuggen. Wir initialisieren das AD9833-Modul mit Hilfe der begin () -Methode. Als nächstes setzen wir alle zugewiesenen Drehgeberstifte als Eingang. Und wir speichern den Wert des Clock-Pins in der Variablen clockPinState. Dies ist ein notwendiger Schritt für den Drehgeber.
Als nächstes setzen wir alle Schaltflächenstifte als Eingabe und aktivieren die OLED-Anzeige mit Hilfe der display.begin () -Methode. Außerdem prüfen wir mit einer if-Anweisung, ob Fehler vorliegen . Wenn dies erledigt ist, löschen wir die Anzeige und drucken einen Start-Begrüßungsbildschirm, fügen eine Verzögerung von 2 Sekunden hinzu, die auch die Verzögerung für den Begrüßungsbildschirm darstellt, und rufen schließlich die Funktion update_display () auf, die den Bildschirm löscht und den Bildschirm aktualisiert noch einmal anzeigen. Die Details der update_display () -Methode werden später in diesem Artikel erläutert.
void setup () {Serial.begin (9600); // Serial @ 9600 Baud aktivieren gen.Begin (); // Dies MUSS der erste Befehl sein, nachdem das AD9833-Objekt pinMode (CLK_PIN, INPUT) deklariert wurde. // Pins als EingangspinMode setzen (DATA_PIN, INPUT); pinMode (BTN_PIN, INPUT_PULLUP); clockPinState = digitalRead (CLK_PIN); pinMode (SET_FREQUENCY_HZ, INPUT); // Pins als Eingang setzen pinMode (SET_FREQUENCY_KHZ, INPUT); pinMode (SET_FREQUENCY_MHZ, INPUT); pinMode (ENABLE_DISABLE_OUTPUT_PIN, INPUT); if (! display.begin (SSD1306_SWITCHCAPVCC, 0x3C)) {// Adresse 0x3D für 128x64 Serial.println (F ("SSD1306-Zuordnung fehlgeschlagen")); zum (;;); } display.clearDisplay (); // Bildschirm löschen display.setTextSize (2); // Text festlegen Größe display.setTextColor (WHITE); // setze LCD Color display.setCursor (30, 0); // Cursorposition setzen display.println ("AD9833"); // Diese Textanzeige drucken.setCursor (17, 20); // Cursorposition setzen display.println ("Function"); // Drucke diesen Text display.setCursor (13, 40); // Cursorposition setzen display.println ("Generator"); // Drucke diesen Text display.display (); // Aktualisiere die Anzeigeverzögerung (2000); // Verzögerung von 2 SEC update_display (); // Update_display Funktion aufrufen}
Als nächstes haben wir unsere loop () -Funktion, alle wichtigen Funktionen sind im Abschnitt loop geschrieben.
Zuerst lesen wir den Clock-Pin des Drehgebers und speichern ihn in der zuvor deklarierten clockPin-Variablen. Als nächstes prüfen wir in der if- Anweisung, ob der vorherige Wert des Pins und der aktuelle Wert des Pins ähnlich sind oder nicht, und wir überprüfen auch den aktuellen Wert des Pins. Wenn alles wahr ist, suchen wir nach dem Daten-Pin. Wenn wahr, bedeutet dies, dass sich der Encoder gegen den Uhrzeigersinn dreht, und wir dekrementieren den Zählerwert mit Hilfe des Befehls counter--. Andernfalls erhöhen wir den Zählerwert mit dem Befehl counter ++. Schließlich setzen wir eine weitere if- Anweisung, um den Mindestwert auf 1 zu setzen. Als Nächstes aktualisieren wir den clockPinState mit dem aktuellen clockPinWert für die zukünftige Verwendung.
void loop () {clockPin = digitalRead (CLK_PIN); if (clockPin! = clockPinState && clockPin == 1) {if (digitalRead (DATA_PIN)! = clockPin) {counter -; } else {counter ++; // Encoder dreht CW, also inkrementiere} if (counter <1) counter = 1; Serial.println (Zähler); update_display (); }}
Als nächstes haben wir unseren Code, um einen Knopfdruck zu erkennen. In diesem Abschnitt haben wir die Schaltfläche im Encoder mithilfe einiger verschachtelter if-Anweisungen erkannt. Wenn (digitalRead (BTN_PIN) == LOW && millis () - time> denounce), überprüfen wir in dieser Anweisung zunächst, ob die Schaltfläche vorhanden ist Stift ist niedrig oder nicht, wenn er niedrig ist, wird er gedrückt. Dann überprüfen wir erneut den Timer-Wert mit der Entprellungsverzögerung. Wenn beide Anweisungen wahr sind, erklären wir ihn für eine erfolgreiche Tastendruckaktion, wenn wir den Wert encoder_btn_count erhöhen. Als nächstes deklarieren wir eine andere if-Anweisung, um den maximalen Zählerwert auf 2 zu setzen. Wir benötigen sie, weil wir sie zum Setzen der Ausgangswellenform verwenden.Die drei aufeinanderfolgenden if-Anweisungen tun dies. Wenn der Wert Null ist, wird die Sinuswellenform ausgewählt. Wenn es eins ist, ist es eine Rechteckwelle, und wenn der Wert 2 ist, ist es eine Dreieckswelle. In allen drei if-Anweisungen aktualisieren wir die Anzeige mit der Funktion update_display () . Und schließlich aktualisieren wir die Zeitvariable mit dem aktuellen Timer-Zählerwert.
// Wenn wir ein LOW-Signal erkennen, wird die Taste gedrückt, wenn (digitalRead (BTN_PIN) == LOW && millis () - time> debounce) {encoder_btn_count ++; // Inkrementiere die Werte wenn (encoder_btn_count> 2) // wenn der Wert größer als 2 ist, setze ihn auf 0 zurück {encoder_btn_count = 0; } if (encoder_btn_count == 0) {// wenn der Wert 0 ist, wird Sinuswelle ausgewählt waveSelect = "SIN"; // aktualisiere die String Variable mit dem Sin Wert update_display (); // Anzeige aktualisieren} if (encoder_btn_count == 1) {// wenn der Wert 1 ist Rechteckwelle ausgewählt WaveSelect = "SQR"; // aktualisiere die String Variable mit dem SQR Wert update_display (); // Anzeige aktualisieren} if (encoder_btn_count == 2) {// wenn der Wert 1 ist Dreieckwelle ist ausgewählt waveSelect = "TRI"; // aktualisiere die String Variable mit dem TRI Wert update_display ();// Anzeige aktualisieren} time = millis (); // Aktualisiere die Zeitvariable}
Als nächstes definieren wir den gesamten erforderlichen Code, der erforderlich ist, um alle Schaltflächen mit einer Entprellungsverzögerung einzurichten. Da die Tasten mit den analogen Pins des Arduino verbunden sind, verwenden wir den analogen Lesebefehl, um einen Tastendruck zu identifizieren, wenn der analoge Lesewert unter 30 liegt. Dann stellen wir fest, dass die Taste erfolgreich gedrückt wurde, und warten 200 ms bis Überprüfen Sie, ob es sich um einen tatsächlichen Tastendruck oder nur um ein Geräusch handelt. Wenn diese Aussage wahr ist, weisen wir den booleschen Variablen Werte zu, mit denen die Hz-, Khz- und Mhz-Werte des Funktionsgenerators festgelegt werden. Als nächstes aktualisieren wir die Anzeige und aktualisieren die Zeitvariable. Wir machen das für alle vier Tasten, die mit dem Arduino verbunden sind.
if (analogRead (SET_FREQUENCY_HZ) <30 && millis () - time> debounce) {set_frequency_hz = 1; // boolesche Werte aktualisieren set_frequency_khz = 0; set_frequency_mhz = 0; update_display (); // aktualisiere die Anzeigezeit = millis (); // aktualisiere die Zeitvariable} if (analogRead (SET_FREQUENCY_KHZ) <30 && millis () - time> debounce) {set_frequency_hz = 0; // boolesche Werte aktualisieren set_frequency_khz = 1; set_frequency_mhz = 0; moduleFrequency = counter * 1000; update_display (); // aktualisiere die Anzeigezeit = millis (); // aktualisiere die Zeitvariable} if (analogRead (SET_FREQUENCY_MHZ) <30 && millis () - time> debounce) {// überprüfe den analogen Pin mit der Debounce-Verzögerung set_frequency_hz = 0; // boolesche Werte aktualisieren set_frequency_khz = 0; set_frequency_mhz = 1; moduleFrequency = counter * 1000000; update_display ();// aktualisiere die Anzeigezeit = millis (); // aktualisiere die Zeitvariable} if (analogRead (ENABLE_DISABLE_OUTPUT_PIN) <30 && millis () - time> debounce) {// überprüfe den analogen Pin mit der Debounce-Verzögerung btn_state =! btn_state; // Invertiere den Schaltflächenstatus gen.EnableOutput (btn_state); // Ausgabe des Funktionsgenerators je nach Schaltflächenstatus aktivieren / deaktivieren update_display (); // Anzeigezeit aktualisieren = millis (); // Zeitvariable aktualisieren}}// Aktualisiere die Zeitvariable}}// Aktualisiere die Zeitvariable}}
Schließlich haben wir unsere Funktion update_display (). In dieser Funktion haben wir viel mehr getan, als nur diese Anzeige zu aktualisieren, da ein bestimmter Teil der Anzeige in einer OLED nicht aktualisiert werden kann. Um es zu aktualisieren, müssen Sie es mit neuen Werten neu streichen. Dies macht den Codierungsprozess viel schwieriger.
Innerhalb dieser Funktion beginnen wir mit dem Löschen der Anzeige. Als nächstes stellen wir unsere gewünschte Textgröße ein. Danach setzen wir unseren Cursor und den gedruckten Funktionsgenerator mit der Anzeige.println ("Funktionsfunktion"); Befehl. Wir setzen die Textgröße erneut auf 2 und den Cursor mit Hilfe der Funktion display.setCursor (0, 20) auf (0,20).
Hier drucken wir die Informationen für die Welle aus.
display.clearDisplay (); // Zuerst die Anzeige löschen display.setTextSize (1); // setze Text Größe display.setCursor (10, 0); // Cursorposition setzen display.println ("Function Generator"); // drucke den Text display.setTextSize (2); // setze die Textgröße display.setCursor (0, 20); // setze die Cursorposition
Als Nächstes überprüfen wir die booleschen Variablen auf Frequenzdetails und aktualisieren den Wert in der moduleFrequency- Variablen. Wir tun dies für Hz-, kHz- und MHz-Werte. Als nächstes überprüfen wir die WaveSelect- Variable und identifizieren, welche Wave ausgewählt ist. Jetzt haben wir die Werte, um den Wellentyp und die Frequenz einzustellen.
if (set_frequency_hz == 1 && set_frequency_khz == 0 && set_frequency_mhz == 0) {// prüfe, ob die Taste zum Einstellen der Frequenz in Hz gedrückt wird moduleFrequency = counter; // aktualisiere die Variable moduleFrequency mit dem aktuellen Zählerwert} if (set_frequency_hz == 0 && set_frequency_khz == 1 && set_frequency_mhz == 0) {// prüfe, ob die Taste zum Einstellen der Frequenz in KHz gedrückt wird moduleFrequency = counter * 1000; // Aktualisieren Sie die Variable moduleFrequency mit dem aktuellen Zählerwert, aber wir multiplizieren 1000, um sie auf KHZ zu setzen.} if (set_frequency_hz == 0 && set_frequency_khz == 0 && set_frequency_mhz == 1) {// Überprüfen Sie, ob die Taste zum Einstellen der Frequenz in MHz auf moduleFrequency gedrückt wird = Zähler * 1000000; if (moduleFrequency> 12000000) {moduleFrequency = 12000000;// lass die Frequenz nicht größer sein als der 12Mhz Zähler = 12; }} if (waveSelect == "SIN") {// Sinuswelle ist ausgewählt display.println ("SIN"); gen.ApplySignal (SINE_WAVE, REG0, moduleFrequency); Serial.println (moduleFrequency); } if (waveSelect == "SQR") {// Sqr Welle ist ausgewählt display.println ("SQR"); gen.ApplySignal (SQUARE_WAVE, REG0, moduleFrequency); Serial.println (moduleFrequency); } if (waveSelect == "TRI") {// Tri Wave ist ausgewählt display.println ("TRI"); gen.ApplySignal (TRIANGLE_WAVE, REG0, moduleFrequency); // Aktualisiere das AD9833 Modul. Serial.println (moduleFrequency); }}} if (waveSelect == "SQR") {// Sqr-Welle ist ausgewählt display.println ("SQR"); gen.ApplySignal (SQUARE_WAVE, REG0, moduleFrequency); Serial.println (moduleFrequency); } if (waveSelect == "TRI") {// Tri Wave ist ausgewählt display.println ("TRI"); gen.ApplySignal (TRIANGLE_WAVE, REG0, moduleFrequency); // Aktualisiere das AD9833 Modul. Serial.println (moduleFrequency); }}} if (waveSelect == "SQR") {// Sqr Welle ist ausgewählt display.println ("SQR"); gen.ApplySignal (SQUARE_WAVE, REG0, moduleFrequency); Serial.println (moduleFrequency); } if (waveSelect == "TRI") {// Tri Wave ist ausgewählt display.println ("TRI"); gen.ApplySignal (TRIANGLE_WAVE, REG0, moduleFrequency); // Aktualisiere das AD9833 Modul. Serial.println (moduleFrequency); }}
Wir setzen den Cursor erneut und aktualisieren die Zählerwerte. Wieder überprüfen wir den Booleschen Wert, um den Frequenzbereich auf dem Display zu aktualisieren. Wir müssen dies tun, da das Funktionsprinzip der OLED sehr seltsam ist.
display.setCursor (45, 20); display.println (Zähler); // Drucke die Zählerinformationen auf dem Display. if (set_frequency_hz == 1 && set_frequency_khz == 0 && set_frequency_mhz == 0) {display.setCursor (90, 20); display.println ("Hz"); // drucke Hz auf dem Display display.display (); // wenn alle Sätze die Anzeige aktualisieren} if (set_frequency_hz == 0 && set_frequency_khz == 1 && set_frequency_mhz == 0) {display.setCursor (90, 20); display.println ("Khz"); display.display (); // wenn alle Sätze die Anzeige aktualisieren} if (set_frequency_hz == 0 && set_frequency_khz == 0 && set_frequency_mhz == 1) {display.setCursor (90, 20); display.println ("Mhz"); display.display (); // wenn alle gesetzt sind, aktualisiere die Anzeige}
Als nächstes überprüfen wir die Tastendruckvariable, um die Ausgabe an die OLED zu drucken. Auch dies muss aufgrund des OLED-Moduls erfolgen.
if (btn_state) {display.setTextSize (1); display.setCursor (65, 45); display.print ("Ausgang EIN"); // Ausgabe auf dem Display drucken display.display (); display.setTextSize (2); } else {display.setTextSize (1); display.setCursor (65, 45); display.print ("Ausgang AUS"); // Ausgabe auf dem Display ausdrucken display.display (); display.setTextSize (2); }}
Dies markiert das Ende unseres Codierungsprozesses. Wenn Sie an dieser Stelle verwirrt sind, können Sie die Kommentare im Code zum weiteren Verständnis überprüfen.
Testen des AD9833-basierten Funktionsgenerators
Zum Testen der Schaltung wird das obige Setup verwendet. Wie Sie sehen können, haben wir ein 12-V-DC-Netzteil an die DC-Zylinderbuchse angeschlossen und das Hantek-Oszilloskop an den Ausgang der Schaltung angeschlossen. Wir haben das Oszilloskop auch an den Laptop angeschlossen, um die Ausgangsfrequenz zu visualisieren und zu messen.
Sobald dies erledigt ist, stellen wir die Ausgangsfrequenz mit Hilfe des Drehgebers auf 5 kHz ein und testen die Ausgangssinuswelle. Sicher ist es eine 5-kHz-Sinuswelle am Ausgang.
Als nächstes haben wir die Ausgangswellenform in eine Dreieckswelle geändert, aber die Frequenz blieb gleich. Die Ausgangswellenform ist unten gezeigt.
Dann haben wir den Ausgang in eine Rechteckwelle geändert und den Ausgang beobachtet, und es war eine perfekte Rechteckwelle.
Wir haben auch die Frequenzbereiche geändert und den Ausgang getestet, und es hat gut funktioniert.
Weitere Verbesserungen
Diese Schaltung ist nur ein Proof of Concept und muss weiter verbessert werden. Erstens benötigen wir eine hochwertige Leiterplatte und einen hochwertigen BNC-Anschluss für den Ausgang, da wir sonst keine höhere Frequenz erhalten können. Die Amplitude des Moduls ist sehr niedrig. Um dies zu verbessern, benötigen wir einige Operationsverstärkerschaltungen, um die Ausgangsspannung zu verstärken. Ein Potentiometer kann angeschlossen werden, um die Ausgangsamplitude zu variieren. Ein Schalter zum Versetzen des Signals kann angeschlossen werden; Dies ist auch ein Muss. Außerdem muss der Code stark verbessert werden, da er ein wenig fehlerhaft ist. Schließlich müssen OLED-Anzeigen geändert werden, da sonst kein leicht verständlicher Code geschrieben werden kann.
Dies markiert das Ende dieses Tutorials. Ich hoffe, Ihnen hat der Artikel gefallen und Sie haben etwas Neues gelernt. Wenn Sie Fragen zu diesem Artikel haben, können Sie diese im Kommentarbereich unten hinterlassen oder unser Elektronikforum nutzen.