Industrielle Fertigung
Industrielles Internet der Dinge | Industrielle Materialien | Gerätewartung und Reparatur | Industrielle Programmierung |
home  MfgRobots >> Industrielle Fertigung >  >> Industrial programming >> VHDL

VHDL Dual 7-Segment Display Controller für Pmod SSD – Einfache FPGA-Integration

In diesem Artikel stelle ich ein VHDL-Modul vor, das eine zweistellige Zahl auf der Pmod-SSD anzeigen kann:Seven-Segment Display von Digilent. Die duale 7-Segment-Anzeige ist mit der Pmod-Schnittstelle kompatibel, sodass Sie sie ohne Lötarbeiten verwenden können. Es passt in den Pmod-Anschluss, der auf vielen FPGA-Entwicklungsboards Standard ist.

Um die VHDL-Implementierung zu testen, verwende ich den Lattice iCEstick, ein kostengünstiges FPGA-Entwicklungsboard mit einem Pmod-Anschluss. Zusätzlich zum iCEstick benötigen Sie ein 2×6-Pin-auf-Dual-6-Pin-Pmod-Splitterkabel, um vom parallelen Pmod-Anschluss am iCEstick auf die Reihenversion des Steckers umzuwandeln, die die 7-Segment-Anzeige erwartet. Abschließend empfehle ich die Anschaffung eines USB-Typ-A-Verlängerungskabels, da es unpraktisch ist, den iCEstick direkt an den USB-Anschluss des Computers anzuschließen.

So funktionieren 7-Segment-Anzeigen

Es gibt viele verschiedene 7-Segment-Anzeigen auf dem Markt. Die Anzahl der Ziffern variiert zwischen ihnen, ebenso wie die physische Schnittstelle und die Pinbelegung. Eine generische Lösung, die alle möglichen 7-Segment-Anzeigen abdeckt, die Ihnen begegnen könnten, wäre wahrscheinlich nicht sehr benutzerfreundlich. Sie können jedoch den in diesem Artikel vorgestellten Code als Grundlage verwenden und ihn an Ihre Bedürfnisse anpassen.

Das Bild oben stammt aus dem Datenblatt für das Digilent Pmod-Modul. Es zeigt, wie die 7-Segment-Anzeige mit den Pmod-Pins verbunden wird. Diese Pins sind für das FPGA auf dem iCEstick direkt zugänglich.

Sieben der Pins steuern jeweils ein Segment auf dem Display. Durch Ansteuern eines logisch hohen Werts an einem solchen Pin leuchtet das entsprechende Segment auf dem Display auf. Auf dieser Anzeige gibt es jedoch zwei Ziffern, und wir können jeweils nur eine steuern. Der P4/C-Pin am J2-Anschluss wählt die eine oder andere Ziffer aus. Wenn die Logikspannung an diesem Pin '0' ist , die rechte Ziffer leuchtet, wenn es '1' ist , die linke Ziffer wird aktiviert.

Der Dezimalpunkt „DP“ ist nicht verbunden und kann nicht aufgerufen werden.

Die Entität

Der folgende Code zeigt die Entität unseres Seg7-VHDL-Moduls. Die Entität verfügt über einen generischen Port mit einer Konstante namens clk_cnt_bits . Es definiert die Länge eines internen Zählers, der die Aktualisierungsrate der Anzeige steuert, also die Häufigkeit des Wechsels zwischen den linken und rechten Ziffern.

Die genaue Häufigkeit ist nicht entscheidend. Wählen Sie eine Zählerlänge, die im Bereich von 50 bis einigen hundert Hertz liegt. Die Formel zur Bestimmung der Aktualisierungsrate lautet refresh_hz =2clk_cnt_bits / clk_hz .

entity seg7 is
 generic (
 -- refresh_hz = (2 ** clk_cnt_bits) / clk_hz
 clk_cnt_bits : integer
 );
 port (
 clk : in std_logic;
 rst : in std_logic;
 value : in integer range 0 to 99;
 segments : out std_logic_vector(6 downto 0);
 digit_sel : out std_logic
 );
end seg7;

Zusätzlich zur Uhr und zum Zurücksetzen verfügt die Entität über ein Eingangssignal:den Wert, der auf der 7-Segment-Anzeige angezeigt werden soll. Der value signal ist ein ganzzahliger Typ, der auf den Bereich von 0 bis 99 beschränkt ist, da dies die einzigen Zahlenwerte sind, die mit nur zwei Ziffern angezeigt werden können.

Die Ausgangssignale sind die sieben Segmente als Vektor und das Ziffernauswahlsignal zum Auswählen der linken oder rechten Ziffer zum Beleuchten.

Darstellung einer binär codierten Dezimalzahl

Um die auf dem Display angezeigten Ziffern darzustellen, verwenden wir das Format, das als binär codierte Dezimalzahl (BCD) bekannt ist. Während eine binäre Darstellung die effizienteste Art ist, die Dezimalzahl zu speichern, stoßen wir auf Probleme, wenn wir versuchen, sie in die linke und rechte Ziffer aufzuteilen, um sie auf dem Display anzuzeigen. Wir können die Dezimalziffern nicht einfach dadurch unterscheiden, dass wir den Vektor, der zum Speichern der Zahl verwendet wird, in Scheiben schneiden.

subtype digit_type is integer range 0 to 9;
type digits_type is array (1 downto 0) of digit_type;
signal digit : digit_type;
signal digits : digits_type;

Wie im obigen Code gezeigt, deklarieren wir einen Untertyp der Ganzzahl im Bereich von 0 bis 9, um den Wert zu beschreiben, der durch eine Dezimalstelle dargestellt werden kann. Dann deklarieren wir einen neuen Array-Typ, der zwei solcher BCD-Werte enthalten kann. Der digit Das Signal enthält die Nummer, die gerade auf der linken oder rechten Seite des Displays angezeigt wird. Andererseits der digits Das Signal enthält die einzelnen Dezimalzeichen für die beiden Ziffern, wie sie einer Person, die den Bildschirm betrachtet, erscheinen.

Dezimal in BCD umwandeln

Die Eingabe für dieses Modul, value ist eine Ganzzahl im Bereich von 0 bis 99, eine binäre Darstellung der Zahl. Wir müssen diese einzelne Ganzzahl in zwei Ganzzahlen im Bereich von 0 bis 9, den BCDs, umwandeln.

Der Standardalgorithmus hierfür ist Double Dabble, auch bekannt als Shift-and-Add-3 Algorithmus. Obwohl dies in Ordnung ist, werde ich mich in unserem Fall für eine kürzere Lösung entscheiden, da wir nur zwei Ziffern trennen müssen.

digits(1) <= value / 10;
digits(0) <= value - ((value / 10) * 10);

Durch die Ganzzahldivision, wie im obigen Code gezeigt, können wir die höchstwertige Dezimalstelle isolieren und sie der digits(1) zuweisen Signal. Um die niedrigstwertige Ziffer abzurufen, können wir die höchstwertige Ziffer vom value subtrahieren Signal, so dass uns nur noch die Nummer bleibt, die wir dem digits(0) zuweisen können Signal.

Taktzyklen zählen

Die Zeitverzögerung in FPGAs ist einfach eine Frage des Zählens von Taktzyklen. Die Taktperiode ist das einzige vorhersehbare Zeitintervall, auf das Sie sich in Ihrem VHDL-Code verlassen können. Der folgende Code zeigt den clk_count Signal, das wir zum Zählen von Taktzyklen verwenden. Der clk_cnt_bits generic bestimmt, wie viele Bits für dieses vorzeichenlose Signal reserviert werden sollen.

signal clk_cnt : unsigned(clk_cnt_bits - 1 downto 0);

Die genaue Bildwiederholfrequenz der Anzeige ist weniger wichtig, deshalb habe ich mich hier für einen unsignierten Typ entschieden. Dadurch können wir das Self-Wrapping-Verhalten des vorzeichenlosen Signals nutzen. Alles, was wir tun müssen, ist, den Zähler bei jeder steigenden Flanke der Uhr zu erhöhen. Der folgende Code zeigt den synchronen Prozess mit Reset, der dies erledigt.

COUNT_PROC : process(clk)
begin
 if rising_edge(clk) then
 if rst = '1' then
 clk_cnt <= (others => '0');
 
 else
 clk_cnt <= clk_cnt + 1;
 
 end if;
 end if;
end process;

Zwischen Ziffern wechseln

Nachdem der freilaufende Zähler nun funktioniert, können wir das höchstwertige Bit (MSB) des vorzeichenlosen Zählersignals verwenden, um zwischen den beiden Ziffern umzuschalten. Das MSB wechselt zwischen '0' und '1' mit einer Einschaltdauer von 50 %. Die erste Zeile des folgenden Codes legt den digit_sel fest Signal basierend auf dem Wert des MSB. Die zweite Zeile implementiert einen Multiplexer, wobei das MSB als Selektor verwendet wird. Es wird der Wert der aktiven Ziffer von digits weitergeleitet Array zum digit Signal.

digit_sel <= clk_cnt(clk_cnt'high);
digit <= digits(0) when clk_cnt(clk_cnt'high) = '0' else digits(1);

BCD zu 7-Segment-Encoder


Der letzte Schritt des Seg7-Moduls besteht darin, den im digit gespeicherten BCD zu übersetzen Signal zu einer visuellen Darstellung auf der 7-Segment-Anzeige. Der folgende Code zeigt einen Prozess, der dies durch die Verwendung einer case-Anweisung erreicht.

Die Position jedes Bitliterals im Vektor entspricht einem Segment auf der Anzeige. Index 0 entspricht Segment A, Index 1 ist B usw. bis hin zu Index 6, der Segment G steuert. Die Zuordnungen von Segmenten zu Vektorindizes werden aus dem Datenblatt für die 7-Segment-Anzeige von Digilent abgeleitet.

ENCODER_PROC : process(digit)
begin
 case digit is
 
 when 0 => segments <= "0111111";
 when 1 => segments <= "0000110";
 when 2 => segments <= "1011011";
 when 3 => segments <= "1001111";
 when 4 => segments <= "1100110";
 when 5 => segments <= "1101101";
 when 6 => segments <= "1111101";
 when 7 => segments <= "0000111";
 when 8 => segments <= "1111111";
 when 9 => segments <= "1101111";
 
 end case;
end process;

Die Ausgabe

Das Seg7-VHDL-Modul rendert auf dem Display alles, was Sie dem value zuweisen Eingangssignal. Im Testbench erhöhen wir den value Signal einmal pro Sekunde. Dann simulieren wir etwas mehr als 100 Sekunden, damit wir den Umbruchpunkt von value beobachten können Zähler.

Die obige Wellenform stammt von ModelSim. Es zeigt den ersten Teil der Simulation, in dem der Wert von 0 bis 15 gezählt wurde. Wir können sehen, dass die Zahlen im digits sind Array zählen ebenfalls. Die (0) zählen jedes Mal, wenn der value Signal ändert sich, während die Zehner (1) sind Erhöhen Sie jede zehnte Zahl.

Sie können das ModelSim-Projekt, einschließlich der Testbench, herunterladen, indem Sie das untenstehende Formular verwenden.

Wenn Sie das Seg7-Modul als oberstes Modul auf dem FPGA implementieren, wird das Display höchstwahrscheinlich eine stabile „00“ anzeigen. Das liegt an '0' ist der häufigste Standardwert, der nicht initialisierten Signalen in FPGAs zugewiesen wird. Wenn der value Wenn das Signal auf Null gesetzt wird, zeigt das Display genau das an.

Um alle möglichen Eingabezahlen zu durchlaufen, habe ich ein Wrapper-VHDL-Modul erstellt, das value erhöht Signal zehnmal pro Sekunde. Anschließend habe ich das Seg7-Modul im Wrapper instanziiert, bevor ich das Design auf dem Lattice iCEstick implementiert habe. Das sich wiederholende Gif-Video unten zeigt, wie das umgesetzte Design auf der 7-Segment-Anzeige aussieht.

Kauf der Pmod SSD:Sieben-Segment-Anzeige

Die in diesem Blogbeitrag verwendete 7-Segment-Anzeige stammt von Digilent. Sie können das Pmod-Modul im Digilent-Webshop erwerben oder bei einem der zahlreichen Wiederverkäufer beziehen. In der folgenden Auflistung habe ich auf die Produktseite für die Anzeige in einigen Online-Elektronikgeschäften verlinkt, die den Artikel führen.

Bitte beachten Sie dies, wenn Sie die Digilent 7-Segment-Anzeige mit dem Lattice iCEstick verwenden möchten , oder jedes andere FPGA-Entwicklungsboard, das über einen 6×2-Pin-Pmod-Anschluss verfügt, benötigen Sie außerdem ein Splitterkabel. Das Kabel ist bei Digilent erhältlich , Digi-Key , Mouser , und RS Electronics .

Darüber hinaus sind alle Komponenten bei verschiedenen Anbietern auf Amazon und eBay erhältlich.

VHDL-Kurs mit der Digilent 7-Segment-Anzeige

Ich habe einen neuen VHDL- und FPGA-Kurs für absolute Anfänger gestartet. Im Kurs verwende ich die 7-Segment-Anzeige von Digilent und das Lattice iCEstick FPGA-Entwicklungsboard zum Unterrichten von VHDL. Klicken Sie auf den Link unten, um mehr über den Kurs zu erfahren!

FPGA- und VHDL-Fast-Track:

Praxisnah für absolute Anfänger

Sind Sie mit der Programmierung vertraut, aber neu bei VHDL?

Benötigen Sie eine kurze Einführung in dieses unbekannte Thema?

Ist Ihr Terminkalender voll und Sie haben keine Zeit mehr zum Lernen?

Verstehen Sie an wenigen Abenden die Grundlagen der FPGA-Entwicklung mit VHDL! Dieser Kurs richtet sich an IT-Experten und Studenten, die sich schnell mit dem Thema vertraut machen möchten. Mit diesem Kurs und dem kostengünstigen Lattice iCEstick-Entwicklungsboard entwickeln Sie innerhalb weniger Stunden echte Hardware.

Klicken Sie hier, um mehr zu lesen und sich anzumelden:
FPGA und VHDL Fast-Track:Praxisnah für absolute Anfänger


VHDL

  1. Grundlegendes VHDL-Quiz – Teil 3
  2. So verwenden Sie bedingte Anweisungen in VHDL:If-Then-Elsif-Else
  3. Grundlegendes VHDL-Quiz – Teil 2
  4. Wie sich ein Signal von einer Variable in VHDL unterscheidet
  5. So verwenden Sie eine unreine Funktion in VHDL
  6. So initialisieren Sie RAM aus einer Datei mit TEXTIO
  7. So verknüpfen Sie Quartus Prime IP-Bibliotheken mit VUnit
  8. So verwenden Sie Loop und Exit in VHDL
  9. So erstellen Sie einen getakteten Prozess in VHDL
  10. Erste Schritte mit VUnit