Wie schon im vorigen Beitrag zu dem Frequenzzähler angedeutet, habe ich eine neue Version entwickelt, die einige Nachteile behebt. Nun ist ein USB-RS232-Konverter integriert, die CPU ist direkt auf die Leiterplatte gelötet und der Quarzoszillator ist thermisch eng mit dem Temperatursensor gekoppelt. Der Zähler wird jetzt, so wie man das von einem modernen PC-Peripheriegerät erwartet, direkt über das USB-Interface versorgt. Ein separates Netzteil ist nicht mehr nötig. Die Stromaufnahme liegt bei unter 100 mA. Die Funktionsweise ist weitgehend kompatibel zur alten Version, aber das CPLD-Pinout unterscheidet sich aus Gründen des einfacheren Routings. Mit einer Größe von 75 mm x 100 mm passt der Zähler nun in ein FISCHER Frame Gehäuse aus Aluminium.
Hier zunächst mal die 3D-Ansichten von KiCad und der Schaltplan:
Frequenzzähler V2.0, von obenFrequenzzähler V2.0, von unten
Seit der KiCad Version 6.0 sollten alle Daten in diesen Dateien enthalten sein, so daß sie sich direkt auf einem anderen PC öffnen und weiterbearbeiten lassen sollten.
Beschreibung
Auf der oberen linken Seite des Boards sieht man den USB-RS232-Konverter. Es handelt sich um ein kleines Board mit dem FT232R-Baustein von FTDI. Dieses Board ist für zwei bis drei Euro über die bekannten Online-Händler zu beziehen. Im Zehnerpack direkt aus China auch noch preiswerter.
Links unter dem FTDI-Board sieht man den Quarzoszillator und den Temperatursensor. Ein gefrästes PVC-Gehäuse sorgt für eine gewisse thermische Abschirmung, so daß die Temperatur des Quarzoszillators ziemlich genau gemessen werden kann. Dieses Gehäuse besteht aus zwei Teilen, die oben in der 3D-Ansicht semitransparent dargestellt sind. Durch einen kleinen Trick wird eine enge thermische Kopplung des Oszillators zu dem Temperatursensor sichergestellt. Der Temperatursensor im SOIC8-Gehäuse ist über einer rechteckigen Ausfräsung in der Leiterplatte montiert, in den der Quarzoszillator manuell von der anderen Seite montiert und über vier Drähte angeschlossen wird. Hier die 3D-Nahansicht von oben und unten ohne das PVC-Gehäuse:
TCXO von obenTCXO von unten
Der Frequenzzähler wird mit 3.3 V betrieben, weil das CPLD nicht mehr verträgt. Diese Versorgungsspannung wird mit einem kleinen Linearregler aus den 5 V vom USB Bus erzeugt. Der Microchip-Prozessor (ehemals Atmel) ATMEGA644 kommuniziert über seinen UART und das FTDI-Board mit dem PC und über Port-Pins per Bit-Banging mit der Logik im CPLD. Das CPLD-Interface ist selbstgestrickt und folgt keinem Standard, zum Host wird wieder das Modbus Protokoll verwendet. Die Logik im CPLD entspricht im wesentlichen dem der vorherigen Version, nur das Pinout ist geändert und hier sind keine LEDs und kein DIP-Schalter mehr angeschlossen. Die CPU hat keinen eigenen Quarz mehr, sondern sie wird mit dem auf 10 MHz heruntergeteilten Takt des 100 MHz Quarzoszillators betrieben.
Die Takteingänge clk1 und clk2 sind wie in der vorigen Version mit 50 Ω Widerständen terminiert und über einen einstufigen AC-gekoppelten Transistorverstärker in Emitterschaltung an das CPLD angeschlossen. Um auch niedrige Frequenzen bis hin zu DC zu unterstützen, wurde der clk3-Eingang vorgesehen. Er ist über einen 100 Ω Widerstand direkt an das CPLD angeschlossen, das zum Schutz noch zwei Schottky-Dioden gegen GND und VCC geschaltet hat. Die etwas seltsam anmutende Ausführung mit Doppeldioden ist der zum Designzeitpunkt einzig in der Bastelkiste verfügbaren Variante BAS70-05W geschuldet. Inzwischen ist auch die BAV99W-Variante in hinreichenden Stückzahlen eingelagert, die dann bei einem eventuellen Redesign eingesetzt würde.
Oberer und unterer Rand der Platine sind beidseitig vom Lötstopplack befreit. Die Kupferflächen sind jeweils an GND angeschlossen und stellen so einen Kontakt zum Gehäuse her. Das ist bei einem Aluminiumgehäuse naturgemäß unzuverlässig, daher sind die zwei Flachstecker TP4 und TP5 vorgesehen, über die zusätzlich ein Massekabel mit dem Gehäuse verbunden werden kann.
Hier noch ein paar Fotos des fertigen Gerätes:
TCXO von oben mit abgenommener Haube. Blick auf den Temperatursensor.TCXO von unten mit abgenommener Haube. Blick auf den Quarzoszillator.TCXO von oben mit Haube. TCXO von unten mit Haube. Gehäuseeinbau des FrequenzzählersGehäuseeinbau des FrequenzzählersGehäuseeinbau des FrequenzzählersGehäuseeinbau des FrequenzzählersRückseite des FrequenzzählersVorderseite des Frequenzzählers
Die SMA-Buchsen an der Vorder- und Rückseite werden über kurze RG174-Koax-Kabel an die Leiterplatte angeschlossen. Weil die Buchse des USB-RS232-Konverters etwa 1 mm von der Rückwand entfernt ist, die außerdem 2 mm dick ist, reichte ein kleiner Durchbruch leider nicht aus. Daher musste er leider so groß gefräst werden, daß der gesamte Stecker hineinpasst. Neben dem clk3-Eingang und der USB-Buchse ist auf der Rückseite auch noch eine Flügelschraube zur Erdung des Gerätes angebracht. Das wird normalerweise nicht nötig sein, könnte aber bei größeren HF-Leistungen in der Umgebung hilfreich sein.
Nachdem ich die letzten Wochen damit verdaddelt habe, meinen neuen Notebook soweit herzurichten, daß er wieder mit allen benötigten Programmen rund läuft, komme ich nun endlich dazu, das PC-Interface zum Frequenzzähler zu beschreiben.
Wie bereits im ersten Teil beschrieben, benutzt der Frequenzzähler wieder ein RS485-Interface zur Kommunikation mit dem PC. Das ist ein sehr störsicheres Interface, wenn man längere Strecken bis über 1 km zuverlässig überwinden muß. Daher habe ich es für die Kommunikation mit dem Antennenumschalter und dem Antennentuner verwendet, die immerhin 20 m vom Shack entfernt und höheren HF-Leistungen ausgesetzt sind. Das ist mit USB nicht mehr ohne weiteres zu machen. In diesem Fall ist RS485 aber eher suboptimal, weil der Zähler sowieso nahe am PC betrieben wird und weil immer einen USB-RS485-Umsetzer benötigt wird. Daher plane ich jetzt schon ein Redesign, das dann direkt einen FTDI USB-RS232-Umwandler beinhalten wird. Die entsprechenden Module sind ja für ein bis zwei Euro zu kaufen und auch in dem USB-RS485-Umsetzer verbaut. An der Software wird sich daher nichts ändern.
Die PC-Bedieneroberfläche
Die Bedienersoftware ist wie auch die für den Antennenumschalter und Tuner wieder für einen Windows-PC geschrieben. Der Frequenzzähler meldet sich über den USB-RS485-Umsetzer als COM-Schnittstelle an. Als Interface-Protokoll ist auch hier wieder der ModBus implementiert.
Der nachfolgende Screenshot zeigt die Benutzeroberfläche des Frequenzzählers:
Benutzeroberfläche des Frequenzzählers
Das Hauptfenster oben zeigt die gemessene Frequenz in Hz, die anderen Fenster und Steuerelemente dienen der Konfiguration, die nachfolgend kurz beschrieben werden soll. Es wird übrigens die europäische Zahlennotation angewendet, nach der ein Komma als Dezimaltrennzeichen und ein Punkt als Tausendertrennzeichen verwendet wird.
Fref
Fref ist die tatsächliche Referenzfrequenz in Hertz. Sie kann manuell in diesem Fenster eingegeben werden. Wenn der TCXO verwendet wird, wird die Referenzfrequenz aus der aktuell gemessenen Temperatur und einer hinterlegten Temperaturkurve errechnet.
Fref Precision
Hier wird die Genauigkeit der Referenzfrequenz in ppb (parts per billion = 10-9) angegeben. Daraus wird nach der Messung die Präzision des Meßergebnisses berechnet. Die Genauigkeit der üblichen Quarze und Quarzoszillatoren liegt in der Größenordnung von 10.000 ppb (= 10 ppm) und die Genauigkeit eines GPSDO ist besser als 1 ppb.
Timer Reload und Gate Time
Hier wird Anzahl der Takte zur Bestimmung der Torzeit oder direkt die Torzeit in Millisekunden eingetragen. Bei Änderung eines dieser Felder wird automatisch der andere Wert aus Fref und der Betriebsart (normal oder revers) errechnet.
Counter Temperature
Hier wird die momentane Temperatur des Frequenzzählers angezeigt. Der verwendete Sensor hat ein Genauigkeit von 0.5 K und eine Auflösung von 1⁄16 K. Er ist aber im jetzigen Modul so weit vom eingebauten Quarzoszillator entfernt, daß die Messung der Oszillatortemperatur ziemlich ungenau ist.
Resolution und Precision
In diesen Feldern wird nach der Messung die momentane Frequenzauflösung und die maximale Meßabweichung von der tatsächlichen Frequenz, also die Genauigkeit der Meßergebnisses, angezeigt. Die Frequenzauflösung hängt von den Einstellungen (z.B. der Torzeit) ab, während in die Präzision auch noch die Genauigkeit der Referenzfrequenz eingeht. Die Präzision ist eine Kombination aus dem in „Fref Precision“ eigegebenen Wert und der Frequenzauflösung. Daher ist die Präzision immer schlechter als jeder einzelne dieser Werte.
fref und fcheck Radiobuttons
Mit den fref- und fcheck-Auswahlknöpfen wird die Referenzfrequenz und die zu messende Frequenz ausgewählt. clk0 ist der Oszillator des CPU-Moduls, clk1 und clk2 sind die SMA-Buchsen mit nachfolgendem Vorverstärker und clk3 ist die Frequenz des eingebauten 100 MHz Quarzoszillators. Ein externer Referenzoszillator, z.B. ein GPSDO, wird an clk1 oder clk2 angeschlossen, an den verbleibenden Eingang kommt die zu messende Frequenz.
Prescaler
Mit dem Prescaler wird der Eingangsteiler ausgewählt, der den mit fcheck ausgewählten Takt durch 1, 2, 4 oder 8 teilt. Damit muß sichergestellt werden, daß fcheck kleiner als fref/2 ist.
TCXO
Wird hier ein Haken gesetzt, dann verwendet der Frequenzzähler den Oszillator des CPU-Moduls an clk0 oder den eingebauten Quarzoszillator an clk3 als Referenz und errechnet seine Frequenz anhand der momentanen Temperatur. Dessen Frequenzgang über der Temperatur muß vorher ausgemessen worden sein, wie in dem Beitrag zur Meßdatenanalyse mit LibreOffice beschrieben wurde.
Revers
Wird hier ein Haken gesetzt, arbeitet der Frequenzzähler im Reversbetrieb. Statt fref bestimmt dann fcheck die Torzeit und der Zähler zählt die Anzahl der fref-Takte während dieser Zeit.
Continuous
Ein Haken in diesem Feld führt dazu, daß der Zähler kontinuierlich zählt, statt nach einer Messung aufzuhören.
Open Log
Mit dieser Schaltfläche kann eine Logdatei geöffnet werden, in der im CSV-Format die Meßwerte abgelegt werden. Falls die Datei noch nicht existiert, wird sie neu angelegt, ansonsten fortgeschrieben.
Trigger Measurement
Mit dieser Schaltfläche wird die Messung gestartet und im Falle der kontinuierlichen Messung auch wieder gestoppt.
Remote Device
Hier wird ein optionales, am RS485-Bus angeschlossenes Device adressiert, dessen Betriebstemperatur hier angezeigt und gelogged wird. Zu Testzwecken kann hier auch die Device-ID des Frequenzzählers angegeben werden. Damit wird auch in diesem Feld nochmal dieselbe Temperatur angezeigt, wie unter Counter Temperature.
Beispielmessung
In der ersten Messung wird die Frequenz des eingebauten 100 MHz Quarzoszillators mit einem GPSDO als Referenz gemessen.
Frequenz des eingebauten Quarzoszillators mit GPSDO gemessen.
Der Quarzoszillator ist an clk3 angeschlossen, der GPSDO an clk1. Es wurde eine Torzeit von 1 Sekunde gewählt und der Vorteiler teilt durch 4, damit die zu messende Frequenz niedriger als die halbe Referenzfrequenz ist. Daraus ergibt sich eine Auflösung von 4.0 Hertz. Für höhere Auflösungen muß die Torzeit verlängert werden. Wegen der hohen Genauigkeit des GPSDO von besser als 1 ppm, wird die Präzision des Meßergebnisses von der Auflösung dominiert.
Die nächste Messung mißt die Frequenz des Oszillators auf dem CPU-Board (clk0), die nominal 8 MHz beträgt.
Frequenz des CPU Taktes mit GPSDO gemessen.
Da die Referenzfrequenz weitaus höher ist, als die zu messende Frequenz, kann der Vorteiler auf 1 bleiben. Auch hier ist die Auflösung wieder ein Hertz, weil die Torzeit auf eine Sekunde eingestellt wurde.
Stellt man eine Torzeit von 40 Sekunden ein, dann verbessert sich die Auflösung auf 25 mHz und die Genauigkeit auf 33 mHz, wie der nachfolgende Screenshot zeigt:
Frequenz des CPU Taktes mit GPSDO gemessen. Torzeit 40 Sekunden.
Leider muß man dabei auch 40 Sekunden auf das Ergebnis warten. Man ignoriere hier den Timer Reload Wert. Der wird leider als vorzeichenbehaftete 32-bit Zahl dargestellt.
Damit man bei niedrigen zu messenden Frequenzen auch bei kurzer Meßdauer auf ein gut aufgelöstes Ergebnis kommt, benutzt man den Reversbetrieb. Dabei wird die Dauer der Referenzperiode mit dem hohen Referenztakt ausgemessen. Bei 100 MHz Referenzfrequenz erreicht man also eine Auflösung von 10 ns.
Das hier gezeigte Meßergebnis wurde im Reversbetrieb bei einer Sekunde Meßdauer erzielt. Es erreicht eine Genauigkeit von 88 mHz.
Frequenz des CPU Taktes mit GPSDO gemessen. Reversbetrieb, Torzeit 1 Sekunde.
Durch Verlängern der Meßdauer läßt sich auch im Reversbetrieb die Genauigkeit weiter steigern. Bei 10 Sekunden Meßdauer erreicht man eine Genauigkeit von 16 mHz.
Frequenz des CPU Taktes mit GPSDO gemessen. Reversbetrieb, Torzeit 10 Sekunden.
Verwendet man statt dem hochpräzisen GPSDO den auf dem Frequenzzähler verbauten 100 MHz Oszillator als Referenz, dann ist die Genauigkeit sehr viel geringer.
Frequenz des GPSDO mit eingebautem XO gemessen.
Hier ist der GPSDO auf den Meßeingang geschaltet, der für Amateurzwecke exakt 100 MHz Ausgangsfrequenz hat. Die Messung weicht also um 676 Hz von der tatsächlichen Frequenz ab und liegt damit innerhalb der durch die 10 ppm angegebenen Fehlergrenzen, die eine Abweichung bis 1004 Hz erlauben würden.
Wie oben schon beschrieben, kann der eingebaute Oszillator per Software temperaturkompensiert werden, indem man einen Haken bei TCXO setzt. Dadurch sinkt die Meßabweichung auf etwa 1 Hz, wie der nachfolgende Screenshot zeigt.
Frequenz des GPSDO mit eingebautem TCXO gemessen.
Für schnelle Messungen kann man so also auf den GPSDO verzichten und dennoch sehr genau messen.
Anhang
Nachfolgend werden die mathematischen Formeln zum Berechnen der gemessenen Frequenz und der jeweiligen Auflösung dokumentiert. Hier nochmal als Referenz das Blockdiagramm des Frequenzzählers:
Blockdiagramm des Frequenzzählers
In den unten dokumentierten Formeln werden folgende Bezeichner verwendet:
cntr: Counter-Register, 32 bit
prsc: selprsc[1:0], 2 bit
fref: f_ref, Referenzfrequenz
rld: Timer reload value, 32 bit
gt: gate time (Torzeit) [s]
Δ(f): Frequenzauflösung [Hz]
Hier kommt nun der erste Teil der Beschreibung des Frequenzzählers. Hier soll die Hardware besprochen werden, inklusive der Logik im verwendeten CPLD und der Software des Controllers.
Eine kurze Erwähnung fand der Zähler schon vor ein paar Wochen in der Übersicht der aktuellen Projekte. Dort findet sich auch der Schaltplan und die 3D-Ansicht, beides hier nochmal zum direkten Zugriff:
Der Frequenzzähler basiert wieder auf dem ATMEGA644-CPU-Board mit RS485-Schnittstelle, das sich inzwischen in unterschiedlichen Projekten bewährt hat. Dieses CPU-Board kommuniziert über eine synchrone serielle Schnittstelle mit dem in einem EPM240T100 implementierten Frequenzzähler. Die benötigte Geschwindigkeit ist unkritisch und daher wird diese Kommunikation auf dem CPU-Board über I/O‑Pins implementiert („bit-banging“). Da der EPM240 mit 3,3 V betrieben werden muß und keine 5‑V-toleranten I/O‑Pins hat, wird auch das CPU-Board mit 3,3 V betrieben. Das schränkt die Betriebsfrequenz auf maximal 10 MHz ein. Wegen der geringen Anforderungen an die Geschwindigkeit, wurde ein 8 MHz Quarz eingebaut.
Der Schaltplan zeigt unten die Spannungsversorgung und die Kontroll-LEDs, darüber zwei gleichartige Breitband-Verstärker in klassischer Emitter-Schaltung für den Eingangstakt. Sie sind eingangsseitig mit 50 Ω abgeschlossen und heben den Pegel von etwa 6 dBm (8 mA Treiberstärke) auf den für die CPLD-Takteingänge benötigten Hub von 3.3 V an. Wegen der Schmitt-Trigger-Eingänge darf es auch etwas weniger sein. Acht LEDs und vier DIP-Schalter können optional zur Statusanzeige und zur Konfiguration verwendet werden. Außerdem ist ein 100 MHz Quarzoszillator eingebaut sowie jeweils eine JTAG-Programmierschnittstelle für das CPU-Board und das CPLD.
Funktionsweise
Zur digitalen Bestimmung einer Frequenz gibt es prinzipiell zwei Methoden: man zählt die Anzahl der Takte während eines möglichst genau bekannten Intervalls oder man misst die Zeitdauer zwischen zwei oder mehreren Takten. Die erste Methode wird nachfolgend als Normalbetrieb bezeichnet, die zweite Methode als Reversbetrieb. Beide Verfahren benötigen eine möglichst präzise Referenzfrequenz.
Prinzipiell sind beide Betriebsarten gleichwertig, sie unterscheiden sich aber in der Dauer der Messung. Die Auflösung im Normalbetrieb ist umgekehrt proportional zum Messintervall. Um eine Auflösung von 1 Hz zu erreichen, muß man eine Sekunde lang messen, bei 0,1 Hz Auflösung schon zehn Sekunden. Den 32 kHz Takt einer Uhr kann man auf diese Weise in einer Sekunde also nur auf etwa 30 ppm genau messen (2-15).
Im Reversbetrieb teilt man den Takt der Uhr beispielsweise durch 215 und bekommt so auch ein Intervall von einer Sekunde. Zählt man in der Zeit die Takte einer 100 MHz Referenz, dann erreicht man auf eine Auflösung von 10 ns, was 0,01 ppm = 10 ppb entspricht.
Kurz zusammengefasst: damit das Messintervall kurz gehalten werden kann, wählt man den Normalbetrieb am besten bei hohen Frequenzen im Vergleich zur Referenzfrequenz, den Reversbetrieb bei niedrigen Frequenzen.
Das CPLD
Ein CPLD ist für diese Art von Aufgaben prädestiniert. Es besteht aus einer Anzahl Logik-Elemente, in diesem Fall 240 Blöcke, die weitgehend frei verschaltet werden können und über schnelle Verbindungen zu den Pins verfügen. Anders als die meisten FPGAs, haben CPLDs nichtflüchtige Speicher und müssen daher nicht bei jeden Systemstart neu konfiguriert werden. Man benötigt allerdings ein preiswertes Werkzeug, in diesem (Intel/Altera-) Fall den sogenannten USB-Blaster, um das CPLD in der Schaltung zu programmieren. Das kann man auch mehrfach machen, aber die Anzahl der Programmierzyklen ist auf etwa 100 beschränkt, während der Flash-Speicher einer CPU normalerweise auch 10.000 bis 100.000-mal programmiert werden kann.
Die Logik wird in einer Programmiersprache ähnlich einer Software-Programmiersprache eingegeben. Zwei Sprachen haben sich etabliert, VHDL und Verilog. Verilog hat Elemente der Programmiersprache „C“ und ist für jemanden, der diese Sprache kennt, relativ leicht zu erlernen. Der Unterschied ist freilich, daß Software im wesentlichen sequenziell abgearbeitet wird, während in Hardware vieles gleichzeitig passiert. Wie auch bei der Softwareprogrammierung benötigt man Werkzeuge, die den erstellten Quellcode in ein Binärformat umwandeln, das man in das CPLD laden kann. Diese Werkzeuge stellt der Hersteller der Logikbausteine, gegebenenfalls in einer abgespeckten Version, kostenlos zur Verfügung. Im Falle Intels ist das die „Quartus“-Entwicklungsumgebung, die sogar eine angepasste Version des Mentor ModelSim Simulators enthält, der in der Vollversion auch in der professionellen Chip-Entwicklung verwendet wird.
Blockdiagramm des Frequenzzählers
Genau wie beim Entwurf einer diskret aufgebauten Schaltung, sollte man sich auch bei einem CPLD (oder FPGA) ein Blockdiagramm erstellen, das die Funktionsblöcke darstellt. Die können dann bei Bedarf hierarchisch weiter verfeinert werden, was aber bei dem relativ einfachen Zähler hier nicht notwendig ist.
Blockdiagramm des Frequenzzählers
Dieses Diagramm zeigt nur die Logik des Zählers, nicht das CPU-Interface. Zunächst gibt es die vier Takteingänge clk0 .. clk3, die über den Eingangsmultiplexer verteilt werden. clk1 und clk2 sind über die oben beschriebenen Vorverstärker mit den beiden SMA-Buchsen verbunden und für den Referenztakt und die zu messende Frequenz vorgesehen. clk0 ist fest mit dem CPU-Takt verbunden und clk3 wird von dem 100 MHz Quarzoszillator betrieben.
f_check ist die zu messende Frequenz, die über einen optionalen Vorteiler auf die Referenzfrequenz f_ref synchronisiert wird. Daher muß die Referenzfrequenz mindestens doppelt so hoch sein, wie die ggf. heruntergeteilte zu messende Frequenz. Der Eingangsmultiplexer bestimmt, welcher der vier Takteingänge auf f_check und f_ref geschaltet wird. Es gibt hier keine Einschränkungen, zu Testzwecken kann auch derselbe Takt auf beide Signale geschaltet werden.
Die Referenzfrequenz wird üblicherweise in der Größenordnung von 50 bis 100 MHz liegen und wenn die zu messende Frequenz mehr als halb so hoch ist, muß sie mit dem Prescaler heruntergeteilt werden.
Der eigentliche Zähler besteht aus einem 32-bit breiten Register, dessen Inhalt von der CPU eingelesen werden kann, sinnvollerweise nachdem die Messung beendet ist und der Wert sich nicht mehr ändert. Der ebenfalls 32-bit breite programmierbare Teiler wird beim Start des Meßzyklus mit dem Wert des Timer-Reload-Registers geladen und anschließend heruntergezählt. Er bestimmt damit die Torzeit, also wie lange der Zähler zählen soll. Der Meßzyklus wird beendet, sobald dieser Timer null erreicht. Ein kompletter Meßzyklus besteht aus der Konfiguration des Frequenzzählers (Wahl der Takteingänge, der Betriebsart und Einstellung des Vorteilers), Setzen des Reload-Registers und Triggern der Messung, womit gleichzeitig der Zähler auf null gesetzt wird. Ein Statusflag zeigt an, wenn der Meßzyklus beendet ist und das Ergebnis ausgelesen werden kann.
Timer, Zähler und Steuerlogik liegen in der Clock-Domäne des ausgewählten Referenzsignals, während die von der CPU geschriebenen Konfigurations- und Status-Register in der Clock-Domäne des CPU-Boards liegen (clk0). Die Simulation ergibt eine maximale Eingangsfrequenz von 120 MHz für die Takteingänge des Frequenzzählers und über 50 MHz für das CPU-Interface. Bei Betrieb mit 100 MHz ist man also auf der sicheren Seite und die 32-bit Zähler können dann über 80 Sekunden zählen, ohne überzulaufen.
Im Normalbetrieb wird die Torzeit von der Referenzfrequenz bestimmt und die Anzahl der steigenden Flanken von f_check wird in diesem Intervall gezählt. Im Reversbetrieb bestimmt f_check die Torzeit währenddessen die Anzahl von f_ref Flanken gezählt wird.
Verilog Code
Hier ist nun der Verilog-Code des Frequenzzählers und die notwendigen Projektdateien für die Quartus-Entwicklungsumgebung. Gegebenenfalls müssen Dateipfade angepasst werden.
Das eigentliche Design steckt in der Datei Datei FreqCntr.v, die hinreichend gut kommentiert sein sollte. Zu beachten ist, daß die ursprünglich geplante Parametrisierung über die Parameter COUNTERW, TIMERW und IOREGW nicht konsequent verfolgt wurde. Sie sollten auf ihren Default-Werten bleiben.
FreqCntr_EPM240.v instanziiert den Frequenzzähler für das EPM240 CPLD auf dem Frequenzzähler-Board. Die beiden weiteren Verilog Dateien FreqCntr_tb_Counter.v und FreqCntr_tb_Serial_IO.v enthalten die ModelSim-Testbenches für den Zähler und die serielle CPU-Schnittstelle. Die zugehörigen Skripte tb_Counter.do und tb_Serial_IO.do werden in ModelSim ausgeführt und starten den jeweiligen Test.
Nachtrag: Quartus Prime V21.1
Nachdem ich mir vor ein paar Wochen einen neuen Notebook geleistet habe (der alte war tatsächlich mittlerweile neun Jahre alt), habe ich die jeweils neuesten Versionen der Entwicklungsumgebungen installiert, für CPLDs und FPGAs von Intel (früher Altera) also Quartus V21.1. Dieses Paket beinhaltet nicht mehr Modelsim, sondern dessen Nachfolger Questa (beide von Mentor). Die Bedieneroberfläche ist praktisch gleich geblieben, aber es ist nun eine 64-bit Version und die Simulationsgeschwindigkeit ist beeindruckend (was teilweise auch am neuen Notebook liegen könnte). Leider benötigt diese Version eine zeitlich auf ein Jahr befristete Lizenz, die aber kostenlos ist und danach auch verlängert werden kann.
Folgendes ist zu beachten: die alten mit Modelsim erstellten Projekte sollten durch neue mit Questa erstellte Projekte ersetzt werden. Die alten Projektdateien enthalten Abhängigkeiten, die mit Questa nicht mehr funktionieren. Außerdem muß das „vsim“-Kommando einen Parameter für den Optimizer enthalten (voptargs=“+acc=prn“), damit die Namen der Ports (p), Register (r) und Netze (n) als Debuginformationen erhalten bleiben. Das vollständige vsim-Kommando lautet also beispielsweise folgendermaßen:
vsim <testbench> -voptargs="+acc=prn" -t 1ns
Das sollte dann in den Testbenches tb_*.do entsprechend geändert werden.
ATMEGA644-Code
Die Software, die auf dem ATMEGA644 ausgeführt wird, kann hier als Referenz heruntergeladen werden.
Ich verwende Atmel Studio 7.0 als Entwicklungsumgebung, habe aber keine Projektdateien dazugefügt. Vermutlich hat sowieso jeder seine eigene Philosophie bezüglich der Pfade. Das 7z-Archiv enthält auch eine PDF-Datei mit weiteren Beschreibungen.
Im kommenden zweiten Teil soll die PC-Software zur Bedienung des Frequenzzählers beschrieben werden.
Schon vor ein paar Monaten habe ich ein kleines Programm geschrieben, das eine PNG Grafik-Datei in eine Audio-Datei umwandelt.
Sample input file
Spectrum of output file
Dieses Programm ist nun soweit, daß man es weitergeben kann. Es hat sicher hier und da noch ein paar Macken, daher will ich das nicht als „Release“ bezeichnen und bleibe bei einer Versionsnummer kleiner als 1.0. Es ist eine reine Spielerei.
Die Audiodatei lässt sich mit dem VLC Media Player abspielen, der es gestattet, einen anderen Audio-Ausgang zu wählen, als den Lautsprecher am PC. Im Menü Audio -> Audiogerät kann man den Audio-Eingang eines angeschlossenen Transceivers wählen und so die Audiodatei direkt senden.
Transmitted spectrum (start)
Transmitted spectrum (middle)
Transmitted spectrum (end)
Aber bitte nicht die Mitmenschen damit ärgern. Beim ersten- und zweitenmal ist das ganz spaßig, aber dann nervt es…
In der Entwicklungsphase des noch zu beschreibenden Frequenzzählers habe ich einige Meßreihen erstellt. Eine davon war der Frequenzgang eines 8 MHz Quarzes auf dem CPU-Board, die andere der Frequenzgang eines 100 MHz Quarzoszillators auf dem Frequenzzähler selbst. Beide Frequenzgänge wurden über die Temperatur gemessen, die mit Kältespray (Butangas, nicht Rauchen, kein offenes Feuer aber offene Fenster!) bzw. einem Föhn geändert wurde.
In beiden Fällen wurde die Temperatur mit dem Temperatursensor auf dem CPU-Board gemessen, einem TMP275. Zwischen ‑40 °C und +125 °C hat er eine Toleranz von +/- 1 °C. Die tatsächliche Temperatur des Quarzes und besonders des Quarzoszillators dürften um einige °C von der gemessenen Temperatur abweichen, weil sie etwas entfernt davon montiert sind. Es soll hier aber nicht um die Präzision der Messung gehen, sondern einzig und allein um die Auswertung mit Libreoffice Calc. Der Frequenzzähler speichert die Meßdaten in einem CSV-File ab, das mit LibreOffice direkt eingelesen werden kann. Die beiden OpenOffice Calc Dateien stehen als Referenz und für eigene Experimente zum Download bereit:
In der ersten Tabelle der jeweiligen Datei stehen die original Meßdaten. Die weiteren Tabellen sind nachfolgend beschrieben.
Auswertung
Zur Auswertung empfiehlt es sich, zunächst eine Pivot-Tabelle („Daten->Pivot-Tabelle->Einfügen) zu erstellen. Als Zeilenfelder wählt man die Temperatur und als Datenfelder die gemessene Frequenz Fcheck. Für die Datenfelder interessiert uns aber nicht die Summe, sondern der Mittelwert. Das muß vor dem Erzeugen der Pivot-Tabelle eingestellt werden. Nun sucht Calc alle in der Tabelle vorkommenden Temperaturen, sortiert sie aufsteigend und ordnet jeder Temperatur den Mittelwert aller für diese Temperatur gefundenen Meßwerte zu. So erhalten wir eine Tabelle der gemittelten Meßwerte von etwa ‑30 °C bis +70 °C (Tabelle: „Pivot-Tabelle“).
Da wir einen 8 MHz bzw. einen 100 MHz Quarzoszillator gemessen haben, liegen alle Meßwerte ziemlich nahe bei 8.000.000 Hz oder 100.000.000 Hz. Ohne vernünftige Skalierung sieht man da nur eine horizontale Linie über der Temperatur. Damit die Meßwerte sinnvoll dargestellt werden können, erstellt man in diesem Fall am besten eine Spalte mit der Differenz der Meßwerte zum Nominalwert, denn alle Werte weichen nur sehr wenig davon ab. Dieses Delta läßt sich dann grafisch über der Temperatur darstellen.
Originaldaten des 8 MHz Quarzoszillators
nur langsame Phase
Originaldaten des 100 MHz Quarzoszillators
nur langsame Phase
Die linken Diagramme zeigen die unveränderten Originaldaten. Man erkennt deutlich den Temperaturgang, aber die vielen Ausreißer sind erschreckend. Die Originaldaten enthalten die sehr schnelle Abkühlphase mit Kältespray und die fast genauso schnelle Aufheizphase mit dem Föhn. Daran schließt sich jeweils eine Phase langsamen Aufheizens bzw. langsamen Abkühlens auf Zimmertemperatur an.
Die rechten Diagramme zeigen nur die langsamen Phasen und die Ausreißer sind hier komplett verschwunden (Tabellen: „Auswahl“ und „Pivot-Tabelle_1“). Die Kurvenform bleibt unverändert. Offensichtlich tun in beiden Fällen die schnellen Temperaturänderungen nicht gut, die Schwingung reißt vermutlich kurzzeitig ab.
Erzeugen einer Ausgleichskurve
Alle weiteren Auswertungen erfolgen nun mit den beiden „langsamen Kurven“, denn sie spiegeln offensichtlich die wahren Verhältnisse. Das Ziel ist nun, die jeweilige Kurve so zu glätten, daß die geglättete Kurve möglichst genau der gemessenen Kurve entspricht, ohne deren Meßabweichungen abzubilden. Die Standardmethode zum Erzeugen einer sogenannten Ausgleichskurve ist die Ausgleichsrechnung. Für ein mathematischen Lösungsverfahren muß dieser Ausgleichsrechnung ein Modell zugrunde liegen. Im allgemeinen Fall ist das ein Polynom der Form
y = a0 + a1 * x + a2 * x2 + … + an * xn
In der Praxis muß man diese Reihe natürlich frühzeitig irgendwo abbrechen, denn sonst wird der Rechenaufwand immer größer. Es sei vorab verraten, daß bei den gezeigten Kurven mindestens ein Polynom dritten Grades nötig ist, also n = 3. Das liegt an den zwei lokalen Minima bzw. Maxima (jeweils grob bei 0 °C und bei 60 °C), bei denen die erste Ableitung des Polynoms null sein muß. Um zwei Nullstellen zu haben, muß die erste Ableitung aber mindestens einen quadratischen Term haben.
Probieren wir dennoch zum Spaß und zu Übungszwecken einfach mal eine Gerade aus, brechen also nach n = 1 ab (Tabelle „Ausgleichsgerade“):
y = a0 + a1 * x
Wir tragen wenn möglich gut erratene Startwerte für die Parameter a0 und a1 in jeweils eine Zelle der Tabelle ein (hier C2 und C3). In eine Spalte (hier: Spalte E) neben den Meßwerten tragen wir dann die Formel für die Gerade ein, mit Bezug auf die Parameter ($C$2 und $C$3) und füllen diese Spalte nach unten auf (obere Zelle und alle Zellen bis zum Ende der Daten auswählen und Strg‑D drücken).
In einer weiteren Spalte berechnen wir dann das Quadrat des Fehlers, den der so errechnete Punkt zum tatsächlich gemessenen Wert hat (hier: Spalte F). Auch diese Spalte füllen wir nach unten auf und errechnen in einer weiteren Zelle (G2) die Summe all dieser Fehlerquadrate. Das Ziel ist nun, a0 und a1 (C2 und C3) so zu bestimmen, daß die Summe der Fehlerquadrate minimal wird.
Von Hand ist das ausgesprochen mühsam, aber zum Glück bietet Calc dafür eine automatische Lösung, den „Solver“. Man startet Extras->Solver und gibt die Zelle mit der Summe der Fehlerquadrate (hier G2) als Zielzelle an. Der Zielwert soll minimal werden und als veränderliche Zellen geben wir C2 und C3 in der Form $C$2:$C$3 an. Der Solver rechnet nun einige Sekunden, denn er muss die Werte in C2 und C3 solange anpassen, bis er einen Minimalwert findet.
8 MHz Quarzoszillator mit Ausgleichsgerade
100 MHz Quarzoszillator mit Ausgleichsgerade
Wie die beiden Diagramme zeigen, findet der Solver nach einigen Sekunden einen plausiblen Wert. Die orange dargestellten Geraden nähern die gemessene Kurve bestmöglich an. Bei nur zwei Variablen und den linearen Eigenschaften einer Geraden kann man auch sicher sein, ein echtes Minimum gefunden zu haben.
Ausgleichskurve mit Polynomen
Die Ausgleichsgerade aus dem vorigen Kapitel ist besser als nichts, aber sie befriedigt nicht wirklich. Für bessere rechnerische Annäherung an die Meßkurve kommt man nicht umhin, höhergradige Polynome zu verwenden. Der Rechenweg unterscheidet sich dabei nicht grundlegend von dem der Ausgleichsgeraden, nur die Formel wird etwas komplizierter. Wir nehmen einfach weitere Terme der Form anxn dazu.
Je größer n wird, je höher also die Ordnung des Polynoms wird, umso genauer können wir die Meßkurve annähern. Probieren wir es der Reihe nach durch, zunächst mit einem Polynom zweiten Grades:
8 MHz Quarzoszillator mit Polynom zweiten Grades
100 MHz Quarzoszillator mit Polynom zweiten Grades
Aus den oben schon genannten Gründen verwundert es nicht, daß das die Meßkurve noch nicht trifft. Wie erwartet gibt es nur einen lokalen Extremwert, ein Minimum bei etwa 20 °C. Versuchen wir es nun mit einem Polynom dritten Grades:
8 MHz Quarzoszillator mit Polynom dritten Grades
100 MHz Quarzoszillator mit Polynom dritten Grades
Damit kommen wir der Form der gemessenen Kurve schon sehr nahe. Gleichzeitig wird die Summe der Fehlerquadrate mit steigendem Grad des Polynoms immer kleiner.
Um es auf die Spitze zu treiben, kann man für den 100 MHz Quarzoszillator auch ein Polynom vierten und fünften Grades ausprobieren, das weitere kleine Verbesserungen bringt:
8 MHz Quarzoszillator mit Polynom vierten Grades
100 MHz Quarzoszillator mit Polynom vierten Grades
8 MHz Quarzoszillator mit Polynom fünften Grades
100 MHz Quarzoszillator mit Polynom fünften Grades
Temperaturkompensation per Software
Das sind nette Spielereien mit einem Spreadsheet-Programm, aber was bringt das ganze nun? Ganz einfach, das so gefundene Polynom gestattet uns eine softwaregesteuerte Temperaturkompensation. Wir können die mutmaßliche tatsächliche Frequenz des Oszillators bei einer bestimmten Temperatur aus seiner Nominalfrequenz annähern.
Das zeigt die Tabelle Poly_n5 für beide Quarzoszillatoren. In der Spalte H wurde die nach der Kompensation verbleibende Abweichung zur gemessenen Frequenz errechnet und in Spalte I in ppm (parts per million) umgerechnet. Die verbleibende Abweichung liegt nun außer an den Temperaturgrenzen bei weniger als 1 ppm. Die unkompensierte Abweichung ist zum Vergleich in Spalte J dargestellt und deren Maximum liegt bei knapp 40 ppm bzw. gut 16 ppm, was für einen mit +/- 25 ppm spezifizierten Quarz auch schon recht gut ist.
8 MHz Quarzoszillator unkompensiert
8 MHz Quarzoszillator temperaturkompensiert
100 MHz Quarzoszillator unkompensiert
100 MHz Quarzoszillator temperaturkompensiert
Man beachte die unterschiedliche Skalierung der y‑Achsen. Von den extremen Temperaturbereichen abgesehen, hat die Temperaturkompensation die Frequenzstabilität also mindestens um den Faktor 10 verbessert. Die deutlichen Abweichungen bei etwa 25 °C liegen an der Meßmethode, denn die Zimmertemperatur war jeweils der Endpunkt der Messungen. Hier gab es mutmaßlich Meßfehler durch den abgesetzten Temperatursensor auf dem CPU Board, der durch die Eigenerwärmung einige Grad mehr anzeigt, als beim Quarz wirklich herrschen.
Suchstrategien
Bei der hier gezeigten Meßdatenanalyse kommt der Calc-Solver schnell an seine Grenzen. Am Ende steht ein Polynom fünfter Ordnung mit sechs unbekannten Parametern a0 .. a5. Der Solver muß im Prinzip alle möglichen Parameter-Werte durchprobieren, die Quadratsumme bilden und versuchen, diese Summe zu minimieren. Ohne halbwegs passend gewählte Startwerte ist das ein Unterfangen, das auf heutigen Rechnern nicht lösbar ist. Der Suchraum ist unendlich groß und der Solver muß ihn auf irgendeine Weise einschränken. Seine Suche gilt als beendet, wenn die Quadratsumme bei jeder kleinen Änderung eines Parameters wieder größer wird. Dabei besteht aber immer die Gefahr, ein lokales Minimum zu finden, das weit weg vom tatsächlichen Minimum liegt. Es kann immer sein, daß hinter den Bergen bei den sieben Zwergen ein Minimum liegt, das tausendmal schöner als das bisher gefundene ist. Man sollte dem Solver also durch geeignete Anfangswerte helfen. Wie macht man das?
Sukzessive Erhöhung des Polynom-Grades
Die einfachste Methode, die hier auch angewendet wurde, ist die sukzessive Erhöhung des Polynom Grades. Man startet mit niedriger Ordnung und lässt den Solver dazu passende Parameter suchen. Geht man schrittweise zu höheren Ordnungen, dann sind diese Parameter zwar nicht mehr ganz richtig, aber auch nicht ganz falsch. Sie sind ein guter Startwert. Man kann auch zunächst mal nur den besten neuen Parameter suchen und erst dann eine weitere Suche über alle bisherigen Parameter starten. So verbessert sich das Ergebnis nach und nach.
Kurvendiskussion
Eine Kurvendiskussion kann beim Erraten günstiger Anfangswerte für die Parameter helfen. Zur Kurvendiskussion benötigt man die Ableitungen der Funktion. Gehen wir zunächst von einem Polynom dritten Grades aus, so ergeben sich folgende Ableitungen:
y = a0 + a1 * x + a2 * x2 + a3 * x3
y‘ = a1 + 2 * a2 * x + 3 * a3 * x2
y“ = 2 * a2 + 6 * a3 * x
Aus der ersten Gleichung erkennt man sofort, daß a0 = y(0) ist, denn wenn x = 0 ist, dann fallen alle anderen Terme weg. a0 ist beim 8 MHz Oszillator also etwa 212 und beim 100 MHz Oszillator etwa 355.
Die erste Ableitung einer Funktion ist an lokalen Extremwerten gleich null. Beim 100 MHz Oszillator finden wir ein lokales Minimum etwa bei x=3 und ein lokales Maximum bei etwa x=60. Mit der ersten Ableitung erhalten wir daraus zwei Gleichungen:
y‘ = a1 + 2 * a2 * 3 + 3 * a3 * 32 = 0
y‘ = a1 + 2 * a2 * 60 + 3 * a3 * 602 = 0
Aus zwei Gleichungen mit drei Unbekannten kann man durch Multiplikation mit einem geeigneten Faktor und anschließender Addition beider Gleichungen eine Gleichung mit zwei Unbekannten machen. Eliminieren wir zunächst a2 durch Multiplikation der ersten Gleichung mit ‑20 und anschließender Addition:
Damit haben wir eine direkte Abhängigkeit zwischen a1 und a3 bzw. a2 und a3 gefunden. Diese beiden Formeln kann man direkt in die Zellen für a1 und a2 eingeben und braucht sie dann nicht mehr in die Liste der Unbekannten für den Solver aufzunehmen. Der Suchraum ist also weiter deutlich eingeschränkt.
Können wir noch mehr tun? Ja klar, wir kennen nun Näherungswerte für a0, a1 und a2 und können die in die Gleichung des Polynoms einsetzen:
y = 355 + 540 * a3 * x – 94,5 * a3 * x2 + a3 * x3
Ohne zu vergessen, daß alles sowieso nur Näherungswerte sind, suchen wir aus der Meßreihe einen Wert x und den zugehörigen Wert y heraus. Dabei versuchen wir einen repräsentativen Wert zu finden, also Sonderfälle an den Temperaturgrenzen und auch die lokalen Extremwerte zu vermeiden. Wie wär’s, mehr oder weniger willkürlich, mit x=40 und y=773? Mit diesen Werten können wir nun einen plausiblen Startwert für a3 ausrechnen:
Aus dieser Gleichung ergibt sich a3 = ‑0,006372 und durch Einsetzen dieses Wertes in die oben schon gefundenen Gleichungen a1 = ‑3,44088 und a2 = 0,602154.
Damit haben wir dem Solver das Leben leichtgemacht. Wir haben plausible Startwerte für alle Parameter des Polynoms dritter Ordnung. Ohne den Solver auch nur zu bemühen, deckt sich diese Kurve schon erstaunlich gut mit der Meßkurve (links):
100 MHz Quarzoszillator mit Polynom dritten Grades aus der Kurvendiskussion
100 MHz Quarzoszillator mit Polynom dritten Grades
Rechts ist nochmal zum Vergleich das oben schon gezeigte Diagramm des mit dem Solver gefundenen Polynoms derselben Ordnung gezeigt. Über große Teile des Diagramms ist die Deckung des von Hand gefundenen Polynoms sogar besser. Allerdings ist die Summe der Fehlerquadrate dennoch höher, denn um den Diagrammteil bei hohen Temperaturen korrekt zu modellieren fehlen die höhergradigen Terme.
Ganz am Schluß kann man dann a0 bis a3 nochmal durch den Solver verbessern lassen. Der findet dabei tatsächlich eine bessere Lösung, als bei der Suche aufs Geratewohl im ersten Ansatz. Die geringste Summe der Fehlerquadrate ergibt sich bei a0 = 339,27, a1 = ‑3,023, a2 = 0,703 und a3 = ‑0,00858.
Mit demselben Vorgehen kann man natürlich auch den Fall des 8 MHz Oszillators nochmal durchspielen, was aber hier keine neuen Erkenntnisse mehr bringt. Das sei daher dem geneigten Leser überlassen.
Wie bereits im vorigen Beitrag über nützliche Websites in Aussicht gestellt, habe ich nun doch ein kleines Programm zum Erstellen von Timing Diagrammen im Text-Format geschrieben: DrawTimingDiagram.
Das Programm öffnet ein Eingabe- und ein Ausgabefenster. In das Eingabefenster können Kommandos geschrieben werden, die beim Klick auf den Start-Knopf in ein Timing-Diagramm im Ausgabefenster umgewandelt werden. Ein kleines Beispiel zeigt der folgende Screenshot:
Das so erzeugte Diagramm kann über das Clipboard aus dem Ausgabefenster in eine UTF8-Textdatei übernommen werden.
Eine kurze Beschreibung der unterstützten Eingabekommandos mit einem etwas komplexeren Timing Diagramm Beispiel findet sich in der Online-Hilfe.
Anlässlich meiner diversen Designs in den vergangenen Monaten, brauchte ich immer wieder mal die Möglichkeit, einfache Grafiken, Tabellen und Formeln als Text in die Quelltexte der C‑Programme und Verilog-Dateien als Kommentarblöcke einzubetten. Bisher habe ich mehr schlecht als recht mit AACircuit gearbeitet, das allerdings schon reichlich angestaubt ist und auch seine Macken hat. Eine Suche im Internet förderte ein paar sehr hilfreiche Online-Tools zu Tage.
Diagon – ASCII art diagram collection
Diagon (Diagram Online) ist ein Online-Tool, um mathematische Ausdrücke, Tabellen, Flußdiagramme und sonstiges in ASCII- oder UTF-8-Format umzuwandeln. Einfach mal die Website aufrufen und ausprobieren. Man wählt zunächst das Werkzeug aus und kann dann im Eingabefenster die Rohdaten eingeben. Sie werden dann sofort im Ausgabefenster dargestellt und können mit Copy&Paste in den eigenen Code übernommen werden. Für jedes Tool gibt es ein oder mehrere Beispiele, die zeigen, wie es geht.
ASCIIFLOW
ASCIIFLOW ist ein weiteres Online-Tool, das auf das Zeichnen einfacher geometrischer Formen spezialisiert ist. Man kann Rechtecke, Linien und Pfeile zeichnen und natürlich auch Texte eingeben. ASCIIFLOW unterstützt außer dem ASCII-Zeichensatz auch den erweiterten Zeichensatz, der schöne Linien und Ecken darstellen kann. Darüberhinaus kann man das Ergebnis direkt als Kommentare in /* und */ einbetten. Das zeigt, was der Entwickler im Sinn hatte.
Textik
Textik funktioniert ähnlich wie ASCIIFLOW. Auch hier kann man auf einer Leinwand einstellbarer Größe Rechtecke, Linien, Pfeile und Text zeichnen. Anders als ASCIIFLOW kennt Textik unterschiedliche Ebenen in z‑Richtung. Man kann also wählen, ob ein Objekt über oder unter anderen Objekten liegt. Dafür unterstützt Textik aber nur den Standard ASCII Zeichensatz.
Was noch schön wäre…
Ich hätte noch ein Tool gesucht, das einfache (extended-) ASCII-Timing Diagramme darstellen kann. Auch das ist in Quelltexten immer wieder mal nötig. Bisher zeichne ich sowas von Hand, dabei bricht man sich die Finger. Est recht, wenn man daran etwas ändern muß. Wer sowas kennt, kann mich gerne kontaktieren. Ich habe auch schon überlegt, sowas selber zu schreiben.
Leider gab es seit ein paar Monaten keine Updates mehr in diesem Blog, das werde ich nun nachholen. Im Sommer war viel an unserem Haus zu tun, wir haben das Gartenhaus fertiggestellt und auch im Haus gab und gibt es noch so einige Baustellen. Meist kleine Dinge, die nicht dringend sind, aber doch belasten, weil man sie immer vor sich herschiebt. Zwischendurch hatte ich immer wieder etwas Zeit, um eine Leiterplatte zu designen oder Software zu schreiben, ohne mir aber die Zeit zu nehmen, diese Dinge in diesem Blog zu beschreiben. Hier nun eine kurze Zusammenfassung.
ATMEGA644 V1.1
Nachdem das mit der Fertigung und Bestückung des Relaistreibers in China so gut funktioniert hat, habe ich auch das ATMEGA644 Board nochmal aufgelegt und zehn Stück davon fertigen und teilbestücken lassen. Es spart doch eine Menge Arbeit, wenn wenigstens das Vogelfutter schonmal drauf ist und man nur noch die „makroskopischen Bauteile“ von Hand bestücken muß.
Ich habe die Schaltung minimal geändert, es wurden zwei optionale Schottky-Dioden vorgesehen, damit man dem Board ein Batterie-Backup spendieren kann und es wurden zwei zusätzliche Stützkondensatoren für den Prozessor hinzugefügt. Der hat jetzt an jedem seiner drei VCC-Pins einen eigenen Stützkondensator. Kann nichts schaden, kostet kein Geld (einige milli-Cent) und bei 0402-er Bauform ist auch der Platzbedarf zu vernachlässigen. Den Trimmkondensator am Quarz habe ich weggelassen, der war sowieso nur experimentell auf einem einzigen Board aufgelötet. Außerdem habe ich eine Möglichkeit vorgesehen, den Spannungsregler etwas zu kühlen. Es sind zwei Bohrungen vorhanden, in die ein Flachstecker als Kühlfahne eingelötet werden kann. Notwendig ist diese Kühlung nicht, aber es hat sich beim Antennenumschalter und beim Tuner gezeigt, daß die Temperatur der Platine im Betrieb um ein paar Grad angehoben wird und damit die Temperaturmessung verfälscht wird. Hier nun der Vollständigkeit halber die 3D-Ansichten der neuen Platine und der Schaltplan.
ATMEGA644-Board, V11, Unterseite
ATMEGA644-Board, V11, Oberseite
Zugegeben, die Kühlfahne sieht etwas gewöhnungsbedürftig aus, aber man muß sie ja nicht bestücken. Zudem kann man sie vor dem Einlöten seitlich wegbiegen oder auch auf der Unterseite bestücken. Sie kann natürlich auch durch irgendein anderes passendes Blech ersetzt werden.
Passend zum oben beschriebenen CPU-Board habe ich einen Frequenzzähler gebaut. Hier zunächst mal die 3D-Ansichten:
Frequenzzähler, Oberseite
Frequenzzähler, Unterseite
Auf der Oberseite sieht man links das aufgesteckte CPU-Board und daneben das Intel (Altera) CPLD, in dem der Zähler und das CPU-Interface implementiert sind. Rechts sind zwei SMA-Buchsen angebracht, über die das zu messende Signal und die Referenzfrequenz eingespeist werden. Ganz links sieht man die Buchse für die Spannungsversorgung und darüber die Klemmleiste für das RS485-Interface. Um das CPLD herum sind Stiftleisten angebracht, auf die die nicht verwendeten CPLD-Pins geführt sind. Damit ist das Board auch für andere Zwecke verwendbar. Die Schalterstellungen des vierpoligen DIP-Schalters können von der CPU eingelesen werden und die acht LEDs am oberen Rand können per Software ein- und ausgeschaltet werden. Die beiden zehnpoligen Stiftleisten am oberen Rand der Platine dienen zum Programmieren der CPU und des CPLDs. Hier ist nun der Schaltplan:
Der Frequenzzähler funktioniert inzwischen sehr gut. Die Simulation ergibt eine Grenzfrequenz von 120 MHz für die Referenz- und die Meßfrequenz. Den Zähler werde ich später in voraussichtlich mehreren Beiträgen detaillierter beschreiben. Dazu gehört dann der in Verilog geschriebene CPLD-Code, die Software für das CPU-Board und die Host Software für einen Windows-PC. Außerdem lohnt es, die Auswertung einer Meßreihe mit Libreoffice genauer anzuschauen. Vielleicht fange ich sogar damit an, auch wenn es die chronologisch falsche Reihenfolge ist.
Programmier- und Debugboard
Wo ich gerade so schön am Designen war und sowieso eine Bestellung in China plante, habe ich auch noch ein kleines Programmier- und Debugboard für das ATMEGA644-CPU-Board entwickelt. Es dient dazu, Programme auf das CPU-Board zu programmieren und auch zu testen. Der ATMEGA644 hat mehrere Schnittstellen, unter anderem die SPI Schnittstelle zum Programmieren des Flash-Speichers und des EEPROMs und die JTAG-Schnittstelle, die darüberhinaus auch zum Debuggen verwendet werden kann.
Programmier- und Debugboard, Vorderseite
Programmier- und Debugboard, Rückseite
Auf dem Board sind außerdem ein paar Taster und LEDs angebracht, damit auf einfache Weise ohne Emulator ein paar Ein- und Ausgabemöglichkeiten zu haben. Auf die SMA-Buchse kann der Systemtakt ausgegeben werden, um seine Frequenz beispielsweise mit dem oben gezeigten Frequenzzähler bei unterschiedlichen Temperaturen zu messen.
Das hier beschriebene Relaistreiber-Board wurde im Antennentuner eingesetzt und funktioniert mit kleinen Einschränkungen sehr gut. Die SMD-Montage der eigentlich für Lochmontage vorgesehenen 100-mil-Sockel ist aber fehleranfällig. Beim Einsatz hat sich herausgestellt, daß das seitliche Abbiegen der Pins des Sockels zu Kontaktfehlern führt. Einreihige Sockel für die SMD-Montage scheint es nicht zu geben, zumindest habe ich keine gefunden. Außerdem wurde durch einen Designfehler das Status-Signal des BTS724G Bausteins auf PB3 gelegt, der aber auf dem ATMEGA644-Board fest mit dem Temperatursensor verbunden ist.
Das alleine sind eigentlich keine Gründe für ein Redesign, aber ich wollte schon seit längerem den in China angebotenen Service einer Teilbestückung der Leiterplatte ausprobieren. Man kann zwar SMD-Platinen selber bestücken und ich habe das auch oft gemacht, aber es gibt Grenzen. Mein persönliches Limit beim Hand-Bestücken sind 0805er Baugrößen, auch mal das ein oder andere 0603er Bauteil, aber nicht in Mengen. Außerdem habe ich für diese Bauteile immer das Footprint zum selber Löten, also mit dem Suffix „Handsoldering“ gewählt, weil es etwas größer ist, als das reguläre Footprint. Lässt man die Platine jedoch (Teil-) bestücken, dann kann man das kleinere reguläre Footprint auswählen und außerdem die kleinste verfügbare Bauform, nämlich 0402 auswählen. Das gibt einerseits einen beachtlichen Platzgewinn, andererseits sind die kleinen Bauteile für Anwendungen im Hochfrequenzbereich weitaus besser geeignet, weil ihre Selbstresonanzfrequenzen deutlich höher liegen, als bei den größeren Bauteilen. Zu beachten ist aber, daß Kondensatoren in dieser Baugröße meist nur geringe Betriebsspannungen vertragen, manche nur 6 V oder 10 V und die SMD Drosseln in der zulässigen Stromstärke begrenzt sind, weil ihr ohm’scher Widerstand höher ist, als bei größeren Bauformen.
Als Hersteller habe ich mir die Firma JLCPCB ausgesucht, einfach weil mehrfach über deren Service berichtet wurde, zuletzt in einer der jüngsten Ausgaben des „Funkamateur“. Es gibt andere Hersteller, die sicherlich genausogut sind. JLCPCB hat einen großen Lagerbestand an benutzbaren Bauteilen, laut Website über 40.000 Stück. Viele davon können ohne Aufpreis benutzt werden, weil sie ständig auf dem Bestückungsautomaten eingelegt sind. Wählt man andere Bauteile aus, die sogenannten „extended parts“, dann zahlt man einmalig pro Auftrag und pro extended part $ 3,00 oder € 2,40 als Aufwandsentschädigung für denjenigen, der dann die neue Rolle aus dem Lager holen und einlegen muß. Darüberhinaus zahlt man natürlich die Fertigung der Leiterplatte, einen geringen Grundpreis für die Bestückung und jedes Bauteil. Bei den passiven Bauteilen, Widerständen, Kondensatoren und Spulen sind die Bauteilkosten vernachlässigbar. Sie werden im Bauteilekatalog angezeigt und kosten meist weniger als 1 ct, mitunter nur 0,1 ct. Dabei ist 0402 oft die preisgünstigste Variante.
Unter diesen Randbedingungen habe ich dann ein Redesign des Relaistreibers gemacht und bei JLCPCB fertigen lassen. Die geringe Bauteilgröße gestattete viel mehr Drosseln und ein paar mehr Kondensatoren auf der Leiterplatte unterzubringen, als auf der ersten Version. Die Abmessungen der neuen Leiterplatte sind gleichgeblieben: 30,5 mm x 43,0 mm (1,2″ x 1,7″). Leider ist sie dennoch nicht kompatibel, weil ich die Buchsenleiste nicht mehr als SMD bestücken wollte, sondern als durchkontaktiertes Bauteil. Damit musste der Abstand der Leisten leider um 100 mil größer werden. Weil es ohne Aufpreis möglich war, habe ich diesmal blauen Lötstopplack gewählt. Hier die Kicad 3D-Vorschau:
Das Vogelfutter auf der Unterseite habe ich bis auf die großen SMD-Bauteile D1, F1 und L1 bestücken lassen. Zum manuellen Bestücken bleiben also die beiden Treiber auf der Oberseite und die Prüfpins, die Pin- und Sockelleisten oben und unten und die drei schon erwähnten SMD-Bauteile auf der Unterseite. An „guten Tagen“ ist sowas in 20 Minuten erledigt.
Was hat das ganze nun gekostet? Genau €28.52 für zehn Leiterplatten. Die Kosten beinhalten die Fertigung der doppelseitigen Leiterplatten, die Teil-Bestückung wie oben beschrieben, die Bauteilekosten und die Zusatzkosten für ein „extended Part“. Außerdem beinhaltet der Preis die Lieferung nach Deutschland in das Verteilzentrum von JLCPCB, die Verzollung und den Weiterversand vom Verteilzentrum zu mir nach Hause. Der Gesamtpreis teilt sich übrigens folgendermaßen auf: Merchandise Total: €17.73, Shipping Charge: €10.78. Die Lieferzeit war 12 Tage, Sonntagabend bestellt und Freitags geliefert.
Auch der Service war hervorragend. Ich hatte am Sonntagnachmittag mehrfach versucht, die Bestellung online einzugeben und es kam immer wieder eine unverständliche Fehlermeldung beim Übernehmen in den Warenkorb. Darauf konnte ich mir keinen Reim machen, also mal im Online Formular um Hilfe gebeten. Ich erhielt sofort eine automatische Email-Antwort, daß im Moment niemand verfügbar sei und man sich sobald wie möglich meldet. Ja klar, es musste in China auf Mitternacht zugehen, die Antwort wird dann wohl am Montagmorgen kommen. Zu meiner Verwunderung dauerte es keine Stunde, bis mir jemand per Email freundlich und in gutem Englisch erklärte, daß ich vermutlich eine Kombination gewählt hätte, die sie nicht anbieten. Sie kennen das Problem, der Dialog auf der Website würde nicht alle Eingabefehler abfangen. Ich hatte 1,2 mm Leiterplattenstärke bei blauem Lötstopplack gewählt, blau geht aber nur bei 1,6 mm Stärke.
Unglaublich, da kann und will kein europäischer Hersteller mithalten, ganz davon abgesehen, daß die hier noch nie an Bastlern interessiert waren. Die waren immer nur lästig. Wo führt das hin? Ganz klar zu immer weiterer Abhängigkeit von China. Unsere Fertigung macht dicht und irgendwann werden wir jeden Preis zahlen müssen, weil wir es nicht mehr können. Vielleicht wird ja Gendergaga und Klimahysterie unser neuer Exportschlager.
Nach der Beschreibung im ersten Teil wurde nun mit KiCad eine Leiterplatte für den Antennentuner entworfen. Das vorgesehene Gehäuse, ein RND 455–00150, gibt den Formfaktor der Leiterplatte vor, sie ist 210 mm breit und 100 mm hoch. Hier ist der Schaltplan (PDF) und hier die KiCad 3D-Vorschau von oben und unten:
Oberseite des Antennentuners
Unterseite des Antennentuners
Spulen und Controller sind auf der Oberseite montiert, Relais und Kondensatoren auf der Unterseite. Um die Schaltkapazitäten niedrig zu halten, ist die Platine auf einseitig beschichtetem Leiterplattenmaterial gefräst. Die oben gezeigten Leiterbahnen auf der Relaisseite, werden durch Drähte realisiert.
Der Controller wird von einem WB 375530 Weißblechgehäuse (37 mm x 55 mm x 30 mm) gegen Einstrahlungen durch benachbarte Spulen abgeschirmt.
Da sie auf der Leiterbahnseite montiert werden ist da Löten des Mittelpins der SMA Buchse und des GND-Testpads etwas erklärungsbedürftig: hier wird vor dem Bestücken eine 0,5 mm² Aderendhülse (1,4 mm Außendurchmesser) auf der Leiterbahnseite festgelötet und nach dem Bestücken des Bauteils von unten verlötet.
Der praktische Aufbau
Die Leiterplatte ist schnell gefräst, mit Stahlwolle entgratet und poliert und vor dem Bestücken mit Lötlack überzogen.
Leiterplatte für den Antennentuner und die fertig gewickelten Spulen, hier noch mit den SMA-Testbuchsen.
Zum Gewährleisten der Formstabilität sind die größeren Spulen mit passend gefrästen und angeklebten Spreizern aus Hart-PVC fixiert. Jetzt kann die Leiterplatte bestückt, getestet und in das vorgesehene Gehäuse eingebaut werden. Nachfolgend ein paar Fotos kurz vor der Montage am Mast:
Der fertige Antennentuner im wetterfesten Gehäuse
Die Anschlüsse für HF und Kommunikation
Die Anschlüsse von außen
Antennentuner auf PVC-Platte zur Mastbefestigung montiert
Auf den ersten beiden Fotos ist das Weißblechgehäuse zu sehen, das den Controller abschirmt. Es ist mit einem Abstand von etwa 1 mm über der Leiterplatte montiert. Die Leiterplatte ist an den Kanten der Abschirmung mit hitzebeständigem Kaptonband abgeklebt. Es ist nicht wirklich nötig, ich habe es vor der Inbetriebnahme wieder abgezogen. Der Deckel des Weißblechgehäuses ist nur lose aufgesteckt.
Wie beim Antennenumschalter ist auch hier beim Tuner der Kommunikations-Anschluß doppelt ausgelegt. Der RS-485 Standard sieht vor, daß alle Busteilnehmer hintereinandergeschaltet werden und der Letzte am Strang einen Abschlußwiderstand bekommt. Beide Buchsen sind gleichberechtigt. An einer der Buchsen wird das Kabel zum vorherigen Teilnehmer bzw. zum Host-PC angeschlossen, die andere Buchse erhält das Kabel zum nächsten Teilnehmer oder einen Terminierungsstecker mit einem 120 Ω Abschlußwiderstand.
Die Leiterplatte des Tuners ist übrigens auf einer 1 mm dicken Aluplatte montiert, die im Gehäuse festgeschraubt ist. Sie ist auf diesen Fotos nicht zu sehen, da sie vom Tuner verdeckt wird. Das wetterfeste Gehäuse mit dem Tuner wird auf einer passend gefrästen PVC-Platte montiert, die mit Klemmen an den Antennenmast geschraubt wird.
Erste Versuche auf dem Basteltisch verliefen erfolgreich. Statt einer Antenne wurde ein 2 kΩ Abschlußwiderstand eingelötet und die Impedanz mit einem vektoriellen Netzwerkanalysator gemessen. Es gelang für alle Amateurfunkbänder eine Anpassung auf ein SWR besser als 2 zu erreichen. Das Ziel, ein SWR besser als 3, wird damit übertroffen. Den Rest übernimmt der Antennentuner im Transceiver.
Das PC-Kommunikationsprogramm wurde so erweitert, daß der Tuner damit zunächst mal provisorisch einstellbar ist:
Man kann jeweils die Spulen- und Kondensatorkaskaden in Stufen von 0 bis 63 einstellen und diese Paare dann auch als benamte vordefinierte Werte abspeichern, so daß sie schnell abrufbar sind. Dabei hat sich gezeigt, daß es Diskontinuitäten gibt, besonders bei den Spulen, die Einstellungen verlaufen nicht ganz monoton. Das scheint aber kein Problem zu sein, es ließ sich immer eine passende Einstellung finden.
Auf dem linken Foto sieht man, wie der Antennendraht und die Erde des Antennenmasts angeschlossen sind. Sie sind jeweils über wasserdichte Kabelverschraubungen nach außen geführt. Das rechte Foto zeigt den Anschluß an den Antennendraht mit Hilfe einer Drahtseilklemme. Als Gegengewicht für die endgespeiste Antenne dient der geerdete Antennenmast.
Da diese Konstruktion ohne Balun nicht nach Lehrbuch ausgeführt ist, habe ich in der Antennenleitung zunächst provisorisch eine Mantelwellensperre aus RG58 Koaxkabel auf einem FT240-43 Ringkern eingebaut.
Erste Versuche sind sehr ermutigend. Auch hier mit der realen Antenne lässt sich für jedes Kurzwellenband, inklusive der WARC-Bänder (außer 160m), eine Einstellung finden, mit der das SWR unter 3 liegt, meist sogar unter 2. Der im Transceiver eingebaute Antennentuner bringt dann das SWR auf ideale Werte um 1.
Einige erfolgreiche FT8 QSOs auf unterschiedlichen Bändern zeigen, daß auch ein hinreichender Anteil der eingespeisten HF-Energie in Richtung Ionosphäre abgestrahlt wird und nicht (nur) die benachbarten Kirschlorbeersträucher erwärmt. Echte Dauertests stehen noch aus, aber bisher haben sich auf verschiedenen Bändern auch bei 100 Watt Ausgangsleistung nach einer Minute keine Auffälligkeiten gezeigt. Auch der Controller und die Kommunikation zum Host-PC blieben bisher von dieser Ausgangsleistung unbeeindruckt.