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.
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.
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.