Armeleute-DDS-Funktionsgenerator

DDS-Funktionsgenerator

Die Zeit war nun doch reif, einen in den 1970er Jahren entstandenen Funktionsgenerator mit einem ICL8038 durch etwas Neues zu ersetzen. Das Gerät mit einer ausladenden Rundskala und einem Doppelknopf-Feintrieb am Frequenz-Poti beanspruchte reichlich Platz, der ihm nicht mehr zustand.

Ersatz? Klarer Fall, DDS (Direct Digital Synthesis) mit Microcontrollersteuerung. Da nur das NF-Spektrum zu bedienen ist, wäre eine Lösung mit einem ADxxxx schon Overkill. Sie produzieren außerdem nur Sinus. Die nächst einfachere Variante mit einem diskret aufgebauten DAC (Digital-Analog Converter) sollte ausreichen. Bauvorschläge einschließlich Software hierzu gibt es im Netz genügend, z.B. [1] bis [6]. Die Beschreibung in [3] erschien vielversprechend. Warum nicht auch mal eine fertige Software von der Stange nehmen, zumal der C-Quellcode mitgeliefert wird?!

Dieser Funktionsgenerator erzeugt bis ca. 65 kHz:

  • Sinus
  • Rechteck
  • Dreieck
  • Sägezahn (ansteigend und abfallend)
  • Rauschen
  • ECG (=EKG, Elektro-Kardiogramm) wozu das auch immer gut sein mag
  • "High speed"-Rechteck von 1, 2, 4 und 8 MHz.

Referenzen

[1]   http://www.myplace.nu/avr/minidds/
[2]   http://www.scienceprog.com/avr-dds-signal-generator-v10/
[3]   http://www.scienceprog.com/avr-dds-signal-generator-v20/
[4]   http://www.radiolocman.com/shem/schematics.html?di=70216
[5]   http://www.radiolocman.com/shem/schematics.html?di=134073
        http://www.radiolocman.com/shem/schematics.html?di=134936
[6]   http://stromchaos.de/mini-dds.html
[7]   http://de.wikipedia.org/wiki/Th%C3%A9venin-Theorem
[8]   http://www.analog.com/static/imported-files/tutorials/450968421DDS_Tutor...
[9]   http://www.radio-electronics.com/info/rf-technology-design/pll-synthesiz...
[10] http://www.zeitnitz.eu/scms/scope_de
 

Download: 

Tags:

1 Funktionsweise

Wenn die Software schon da ist, wäre es mal eine Überlegung wert, warum sie so funktioniert wie sie funktioniert. Die integrierten DDS machen es nicht anders, wenn auch unsichtbar im Chip. Sie erzeugen aus einer digitalen Bitfolge, was nichts anderes als eine bestimmte Zahl ist, ein fast analoges, d.h. treppenförmiges Ausgangssignal. Bei der Zu-Fuß-Lösung mit einer diskreten R2R-Kette wird ein 8 Bit breiter AVR-Port zur Ansteuerung verwendet.

1.1 R2R-DAC

R2R-Kette

Abb. 1.1: R2R-Anordnung an einem AVR-Port.

Jeder Port-Pin kann die Zustände High (1=5V) oder Low (0=0V=Masse) einnehmen. Der OpAmp entkoppelt den DAC von der Folgeelektronik. Die Widerstandswerte 10k (R) und 20k (2R) sind offenbar Standard, wenn auch kein unumstößliches Diktat. Sie sollten einerseits eng toleriert sein (1% oder besser), andererseits hinreichend groß im Vergleich zum Innenwiderstand der AVR-Ports sein.

Des Rätsels Lösung zum Verständnis dieses Widerstandsnetzwerk-Puzzles ist das Thevenin-Theorem [7]: Wenn eine Schaltung aus linearen Elementen wie Spannungsquellen, Stromquellen und Widerständen besteht, kann sie an jedem Punkt aufgetrennt werden. Alles auf einer Seite des Schnittpunkts (nachfolgend links) kann durch eine Spannungsquelle und einem einzigen Widerstand in Serie ersetzt werden. Die Spannungsquelle ist die Leerlaufspannung am Schnittpunkt. Der Serienwiderstand ergibt sich, wenn alle Spannungsquellen nach Masse kurzgeschlossen werden.

Damit es nicht zu kompliziert wird, beschränken wir uns auf 4 Bits (P0 bis P3), an die die Bitfolge
(P3, P2, P1, P0) = 0001 gelegt wird. Die Spannung für logisch 1 ist Vr, am AVR +5V.

Thevenin-1

Abb. 1.2: Erste Zerlegung an P0.

  1. Die Leerlaufspannung zwischen den beiden 20k-Widerständen ist Vr/2.
  2. Wenn P0 nach Masse kurzgeschlossen wird, ergeben 2 Mal 20k parallel = 10k. Damit ist der wirksame Serienwiderstand an Vr/2 nun 2 Mal 10K = 20k (rechte Seite in Abb. 1.2).

Thevenin-2

Abb. 1.3: Zweite Zerlegung an P1.

  1. Speisespannung ist nun Vr/2.
  2. Die Leerlaufspannung zwischen den beiden 20k-Widerständen ist Vr/4.
  3. Wenn beide Spannungsquellen (P1 und Vr/2) nach Masse kurzgeschlossen werden, ergeben 2 Mal 20k parallel = 10k. Damit ist der wirksame Serienwiderstand an Vr/4 nun 2 Mal 10K = 20k (rechte Seite in Abb. 1.3).

Thevenin-3

Abb. 1.4: Dritte Zerlegung an P2.

  1. Speisespannung ist nun Vr/4.
  2. Die Leerlaufspannung zwischen den beiden 20k-Widerständen ist Vr/8.
  3. Wenn beide Spannungsquellen (P2 und Vr/4) nach Masse kurzgeschlossen werden, ergeben 2 Mal 20k parallel = 10k. Damit ist der wirksame Serienwiderstand an Vr/8 nun 2 Mal 10K = 20k (rechte Seite in Abb. 1.4).

Thevenin-4

Abb. 1.5: Vierte und letzte Zerlegung an P3.

  1. Speisespannung ist nun Vr/8.
  2. Die Leerlaufspannung zwischen den beiden 20k-Widerständen ist Vr/16.
  3. Wenn beide Spannungsquellen (P3 und Vr/8) nach Masse kurzgeschlossen werden, ergeben 2 Mal 20k parallel = 10k als Ausgangswiderstand (rechte Seite in Abb. 1.5).

Ergebnis: Für die Bitfolge 0001 (=dezimal 1) erzeugt die R2R-Widerstandskette am unbelasteten Ausgang eine Spannung Vr / 16 (16 = 2^4) bei 4 Bit Auflösung.

Wenn dieses Simpelbeispiel mit variablen Bitfolgen an P0 bis P3 erweitert wird, ergibt sich am Ausgang der R2R-Kette:

Ur = Vr { P0 / 16 + P1 / 8 + P2 / 4 + P3 / 2 } mit P0...P3 = 0 oder 1.

Für die Bitfolge 0000 ist Ur = 0.
Für die Bitfolge 1111 ist Ur = Vr {1/16 + 1/8 + 1/4 + 1/2) = 0,9375 * Vr.

Munter erweitert auf die 8 Bit-Konfiguration nach Abb. 1.1 (2^8=256):

Ur = Vr { P0 / 256 + P1 / 128 + P2 / 64 + P3 / 32 + P4 / 16 + P5 / 8 + P6 / 4 + P7 / 2 }.

Für die Bitfolge 00000000 ist Ur = 0.
Für die Bitfolge 11111111 ist Ur = Vr {1/256 + 1/128 + ... + 1/2) = 0,9961 * Vr.

Der invertierende OpAmp (Abb. 1.1) verstärkt diese Spannung um den Faktor -(Rf / Ri).

Mit Vr = 5V ergibt sich also als kleinste Stufung 5/256 = 19,5 mV bei der 8 Bit-Kette. Oder andersherum für die Zeitachse über eine zu erzeugende Schwingungsperiode: Die Schwingung, z.B. eine Sinusperiode, kann in max. 256 Zeitabschnitte zerlegt werden. Da es ein AVR nun doch nicht schafft, für jede Zeitscheibe den Sinus zu berechnen, werden gespeicherte Lookup-Tabellen (LUT) verwendet. In diesen sind die gerundeten Funktionswerte der gewünschten Schwingungsform abgelegt, hier, passend zur Zeitauflösung, mit 8 Bit (1 Byte) Genauigkeit. Da das Byte kein Vorzeichen +/- kann, sind die Funktionswerte so verschoben, dass der Minimalwert Null ist. Die Werte für einen Sinus (-1 bis +1) bewegen sich also von 0 [sin(270°)=-1] bis 255 [sin(90°)=+1]. Die Nulllinie für sin(0°) entspricht damit dem Wert 127. Einfach ist es beim Rechteck: eine Periodenhälfte ist 0, die zweite ist 255.

1.2 Software-DDS

Wie wird nun die Bitfolge für den DAC erzeugt? Das alles versteckt sich in der Software des AVR, die offenbar auf den Assembler-Code von Jesper Hansen [1] zurückgeht. Wie eine DDS funktioniert, haben schon kundigere Leute als ich beschrieben, z.B. [8], [9]. Hier in Kürze:

Ein DDS besteht aus drei Funktionsblöcken, die hier im AVR einschl. diskreter DAC-Widerstandskette nachgebildet sind.

Blockdiagramm DDS

Abb. 1.6: Funktionsblöcke des DDS.

Im Phasenakkumulator werden die u.a. aus der gewünschten Ausgangsfrequenz fout bestimmten Phaseninkremente zu einer Phasenrampe aufsummiert.

Digitalisierung

Abb. 1.7: Digitalisierung einer Schwingungsperiode, hier Sinus.

Die Phaseninkremente M ergeben sich aus
M = fout * Breite des Phasenakkumulators / Controller-Takt fCPU

Im AVR-Programm festgelegte Werte:
fCPU = 16 MHz
Breite des Phasenakkumulators: N = 24 Bit, also 2^N = 16.777.216.

Das Schreiben der Sinus-Funktionswerte aus der Lookup-Tabelle in den DAC benötigt ein paar CPU-Takte, im hier verwendeten AVR-Programm sind es n = 10. Um diesen Faktor reduziert sich der verfügbare CPU-Takt. Damit wird das Phaseninkrement für eine bestimmte Wunschfrequenz fout

M = fout * 2^N / (fCPU / n)

Der Kehrwert des Faktors 2^N... ist nichts anders als die aus dem CPU-Takt und der Phasenakkumulator-Breite resultierende Frequenzauflösung, im AVR-Programm "resolution":
Resolution = fCPU / (2^N * n)
Resolution = 16.000.000 / (16.777.216 * 10) = 0,0953674...

Den Charme an dieser in Software gegossenen DDS machen die Lookup-Tabellen aus, in Abb. 1.6 für einen Sinus dargestellt. Damit können beliebige Kurvenformen erzeugt werden, in dieser Anwendung auch Sägezahn, Dreieck und Rechteck, ja sogar EKG. Dafür gehen andere Leute zum Arzt.

 

2 Schaltung

2.1 Controller

Ausgehend von den Vorschlägen in [3] und [4] stellt sich der Digitalteil wie folgt dar.

Controller Schaltung

Abb. 2.1: Schaltbild Controller.

Der ATmega16 ist aus Sicht der Software vermutlich überdimensioniert, bringt aber genügend Pins mit. Mit dem üppigen Platzangebot im vorgesehenen Gehäuse (AUS22, reichelt.de) wollte ich einen meiner seit Ewigkeiten gelangweilt herumliegenden ATmegas im PDIP-Gehäuse zum Einsatz bringen. Deshalb ist das Controller-Board entgegen meiner sonstigen Gewohnheit mal nicht in SMD (bis auf die Kondensatoren) ausgeführt. Es heißt also mal wieder Platine bohren.

Es gibt zwei Rechteckausgänge:

  1. High speed Square1 ist der von der Software vorgesehene Rechteckausgang für die High-Speed-Signale 1, 2, 4 und 8 MHz.
  2. Square2 wird alternativ in einem Rechteckformer (Squarer) mit einem Komparator erzeugt, s.u. Abschnitt 3.3.

Die Verbindungen zum Frontpanel-Board werden mit Flachkabeln hergestellt.

2.2 Frontpanel-Board: Analogteil und Display

Der Analogteil in [3] und [4] gefiel mir nun gar nicht. Der Autor von [5] war der gleichen Meinung.

  1. Der eher fußlahme LM358 (slew rate 0,3V/µs, Unity gain bandwidth 0,7 MHz) ist keine gute Wahl für einen Funktionsgenerator. Stattdessen wurde ein schnellerer und dennoch günstiger TL074 (slew rate 13V/µs, Unity gain bandwidth 3 MHz) eingesetzt.
  2. Der DAC im Controller liefert ein Signal mit einem Gleichspannungs-Offset von 2,5V (halbe AVR-Betriebsspannung wegen der o.a. Verschiebung in den Lookup-Tabellen). Um die symmetrische Aussteuerbarkeit der Folgestufen sicherzustellen, kann das Eingangs-Offset mit IC1a und P1 kompensiert werden.
  3. Die treppenförmigen DAC-Ausgangssignale enthalten unerwünschte Oberwellen. Die gilt es mit einem Tiefpass auszufiltern. Dieser wurde mit dem Programm FilterPro von Texas Instruments für eine Grenzfrequenz 150 kHz ausgelegt (IC1b). Für die Nicht-Sinus-Signale lässt sich der Filter überbrücken (Filter On/off).
  4. Die Reihenfolge Offset- vor Amplitudeneinstellung in [3] bzw. [4] ist ungünstig. Da der TL074 noch zwei Verstärker übrig hat, wurden die Einstellmöglichkeiten den IC1c und IC1d zugeordnet und vor allem umgedreht, also zuerst Amplitude (Level), danach Offset.
  5. Es fehlt eine Endstufe, die auch höhere Ausgangslasten verträgt.

Herausgekommen ist folgende Schaltung, Ausführung in SMD auf einem Board, das alle Bedien-elemente für die Frontplatte einschließlich LCD enthält. Die Spiegelung von konventionellem Aufbau auf der Controller-Platine nach SMD auf der Frontpanel-Platine hatte leider einige Brücken zur Folge. Um das verwendete LCD (TC1602A-09, pollin.de) hinter die Frontplatte und die Taster (DT 6 xx, reichelt.de) durch die Frontplattenbohrungen zu bekommen, ist das LCD auf einer eigenen Platine hinter dem Frontpanel-Board aufgesteckt. Die Komplementär-Endstufe ist auf einer gesonderten Platine untergebracht.

Analogteil

Abb. 2.2: Analogteil und Display.

In den Rechteck- und Sägezahnsignalen zeigten sich Überschwinger. Diese wurden mit C1 parallel zum Gegenkopplungswiderstand R3 von IC1a reduziert, hier 6,8pF, was natürlich ein gewisses Verschleifen der Flanken zur Folge hat; ggf. ausprobieren oder auch weglassen.

Die Komplementär-Endstufe mit IC2 und T1/T2 wurde zugefügt, um IC1d vor Überlastung zu schützen und fallweise höhere Leistungen abzuliefern. Für T1/T2 wurden gerade vorhandene Transistoren eingesetzt: NPN: 2N2919, PNP: 2N2905, beide im TO5-Gehäuse mit Kühlsternen. Beide wurden mit einem Kennlinienschreiber auf annähernd gleiche Kennlinien selektiert. Alternativen z.B. BC107/BC177, 300 mW; BC548/BC558, 500 mW; BC337/BC327, 800 mW; BC140/BC160, 3,7W; BD135/BD136, 8W. Je nach Lastauslegung müssen die Emitterwiderstände R13/R14 angepasst werden, ggf. auch die Trafobelastbarkeit für die BD13x-Variante.

Die Endstufe verschlechtert allerdings die Frequenzlinearität der Generatorausgangsspannung. Die gemessenen ca. 0,5dB Abfall bei 10Hz und 50kHz mögen wenig erscheinen, bedeuten aber auf der linearen Skala etwa 5%! Im Mustergerät wurde sie wieder stillgelegt. So ist darauf Verlass, dass der Generator über den gesamten Frequenzbereich eine ziemlich konstante Amplitude abliefert. Siehe dazu Abschnitt 3.4.

2.3 Netzteil

Netzteil

Abb. 2.3: Netzteil +/- 12V und +5V.

Ohne Endstufe reduzieren sich die Anforderungen an Trafo und Spannungsregler.

2.4 Firmware brennen

Zum Brennen reicht das kostenlose AVR Studio. Mit AVR Studio wurden die Fuses gesetzt und das Programm main.hex (Firmware im Download) gebrannt, siehe auch "AVR-Programmieren mit BASCOM und AVR Studio" im Register "Software".

ATmega Fuses

Abb. 2.4: Setzen der Fuses im ATmega16 mit AVR Studio.

Na so was aber auch, das Programm lief auf Anhieb.

3 Erzielte Ergebnisse

3.1 Bedienung in Kürze

  • Die Einstellung der Betriebsart und der Frequenz ist nur im Signal off-Modus, Displayanzeige "OFF", möglich.
  • Betriebsarten und Frequenzschrittweite werden mit den Tastern "Mode Select" auf- oder abwärts ausgewählt.
  • Entsprechend der gewählten Frequenzschrittweite kann die Frequenz auf- oder abwärts eingestellt werden.
  • Erst nach Einstellen des Signal on-Modus, Displayanzeige "ON", wird ein Signal an den Ausgang "DDS out" bzw. "High speed TTL out" gelegt.
  • Der Ausgang "High speed TTL out" wird nur im Modus "High speed" aktiv. Im Signal off-Modus wählbare Frequenzen sind 1, 2, 4 und 8 MHz.

3.2 Signalformen

Sinus

Abb. 3.1: Sinus 10 kHz, Filter On.

Der Sinus sieht bildschön aus. Kein Vergleich zu dem, was der ICL8038 abzuliefern imstande war. Das Tiefpassfilter glättet das Signal sichtbar, was nur mit einem analogen Scope erkennbar ist. Mit dem Soundcard-Scope [10] wurde ein Klirrfaktor (THD) von 0,18% bei 1 kHz gemessen .

Sägezahn

Abb. 3.2: Sägezahn 10 kHz, Filter off.

Dreieck

Abb. 3.3: Dreieck 10 kHz, Filter off.

Rechteck

Abb. 3.4: Rechteck 10 kHz, Filter off.

Die "kantigen" Signale Sägezahn, Drei- und Rechteck haben infolge des Kondensators C1 an IC1a (Abb. 2.2) zur Reduzierung der Überschwinger leichte Verrundungen an den Spitzen bzw. Flanken. Das Rechteck zeigt bei einer Frequenz von 10 kHz eine Anstiegszeit von ca. 2 µsec – nicht besonders schön. Der Überschwinger ist in Abb. 3.5 noch andeutungsweise zu sehen.

Rechteckflanke

Abb. 3.5: Rechteckflanke 10 kHz, Filter off, horizontal 800 nsec/Div.

3.3 Verbesserung des Rechtecksignals

Die Form des Rechtecksignals ist unbefriedigend. Die High speed-Signale sind mit ca. 65 nsec zwar wesentlich steiler, aber die Frequenzen 1, 2, 4 und 8 MHz am zweiten BNC-Ausgang werden nicht wirklich gebraucht.

Was liegt da näher, als an dieser BNC-Buchse ein TTL-Signal mit wie oben fein einstellbarer Frequenz, aber besserer Flankensteilheit bereitzustellen. Das muss ein hinreichend schneller Komparator besorgen. Die Auswahl ist zwar groß, aber wirklich schnelle Komparatoren gehen schnell ins Geld. Um es nicht gleich zu übertreiben, wurden bezahlbare Typen in die engere Auswahl gezogen: LM319 (80 nsec, Dual, DIL14) und LM311 (200 nsec, DIP8).

Der Anschluss erfolgt an PA0 des ATmega16 (LSB), siehe auch Abb. 2.1.

Squarer

Abb. 3.6: Rechteckformer mit LM311 auf der Controller-Platine.

Die vielversprechenden Daten (Anstiegszeit 80 nsec) des LM319 enttäuschten. Gemessen wurden 320 nsec. Dann geht auch der LM311 im handlicheren DIP8-Gehäuse. Mit ihm wurde eine Anstiegszeit von 340 nsec gemessen. R20 ist der Lastwiderstand am Open-Collector-Ausgang des LM311. Mit P1 wird der Schalteinsatz des Komparators eingestellt. Der Ausgang Square2 geht an die umgewidmete BNC-Buchse des vormaligen High speed square-Ausgangs Square1.

Rechteckflanke

Abb. 3.7: Rechteckflanke Squarer 10 kHz, horizontal 200 nsec/Div.

Innenansicht

Abb. 3.8: Innenansicht.

Im Prototyp (Abb. 3.8) ist der Squarer als nachträglich zugefügtes Modul noch nicht auf der Controllerplatine platziert, entsprechend erweiterte Controllerplatine im Download.

3.4  Frequenzgang (Nachtrag vom 07.02.2018)

Der DDS-Generator liefert zwar klaglos 65kHz ab, aber die Frage nach der Pegelgenauigkeit war noch offen. Ein Scope kann da nur grobe Anhaltspunkte liefern, und das sah zunächst gut aus. Norbert, DG1KPN, ist mit seinem neuen AD637 True RMS-Konverter, dessen 1%-Fehlergrenze bei 200kHz nach Datenblatt liegt, der Sache auf den Grund gegangen. Den DC-Ausgang des AD637 hat Norbert mit einem hochauflösenden Millivoltmeter gemessen. Sein DDS-Generator ist ein Nachbau nach [3].

AD637 Frequency Response

Abb. 3.9: Mit einem AD637 True RMS-Konverter gemessener Frequenzgang (Messung DG1KPN)

Also - am oberen Frequenzende verschlechtern die OpAmps wie zu erwarten den Frequenzgang. Wenn wir es etwas freundlicher in dB betrachten wollen, sieht es dennoch so schlecht nicht aus (Abweichungen bezogen auf 1kHz):

20Hz: -0,07% = -0,01dB
20kHz: -0,1% = -0,02dB
34kHz: -0,5% = -0,04dB
50kHz: -1,0% = -0,09dB
65kHz: -1,7% = -0,15dB

Für Pegelmessungen an NF-Verstärkern reicht das nun wirklich.