Wie erstelle ich einen Zähler zur Anzeige von 6 Ziffern mit Anoden?

Ich versuche, eine Digitaluhr auf VHDL für ein FPGA zu schreiben, das auf 100 MHz läuft. Ich kann es auf 4 Anoden schreiben, indem ich einen Zähler wie unten gezeigt erstelle (count1 = 249999), die Ziffern scheinen ziemlich klar zu sein. Wenn ich jedoch die Zeit im Format HH:MM:SS anzeigen möchte (wenn ich 6 Anoden anstelle von 4 verwenden möchte), konnte ich die Ziffern nicht klar anzeigen. Wenn ich den Wert von count1 stark erhöhe, beginnen die LEDs zu blinken, wenn ich den Wert von count1 verringere, sehen die Ziffern schwer zu identifizieren aus.

Gibt es eine theoretische Möglichkeit, diesen Zählerwert (Zähler1) zu bestimmen? Ist es möglich, 6 Ziffern so klar anzuzeigen, wie ich es versuche?

Danke ab sofort.

der Code, der für die Anzeige von 4 Anoden verantwortlich ist:

anode_clock : process(count1, clk_in, A_counter) -- counter to display all digits using anodes
begin 
    if(rising_edge(clk_in)) then
        count1 <= count1 + 1;
        if(count1 = 249999) then  -- ATTENTION HERE
            A_counter <= A_counter + 1;
            count1 <= 0;
        end if;
    end if;
end process;

anode_display : process (A_counter, tmp_AN, min0, min1, hour0) begin -- matching anodes to display
    AN <= tmp_AN;
    case A_counter is
        when 0 =>
            tmp_AN <= "1110";
            if (min0 = 0) then
                DISP <= "1000000";
            elsif min0 = 1 then
                DISP <= "1111001";
            elsif min0 = 2 then
                DISP <= "0100100";
            elsif min0 = 3 then
                DISP <= "0110000";
            elsif min0 = 4 then
                DISP <= "0011001";
            elsif min0 = 5 then
                DISP <= "0010010";
            elsif min0 = 6 then
                DISP <= "0000010";
            elsif min0 = 7 then
                DISP <= "1111000";
            elsif min0 = 8 then
                DISP <= "0000000";
            elsif min0 = 9 then
                DISP <= "0010000";
            end if;
        when 1 =>
            tmp_AN <= "1101";
            if (min1 = 0) then
                DISP <= "1000000";
            elsif min1 = 1 then
                DISP <= "1111001";
            elsif min1 = 2 then
                DISP <= "0100100";
            elsif min1 = 3 then
                DISP <= "0110000";
            elsif min1 = 4 then
                DISP <= "0011001";
            elsif min1 = 5 then
                DISP <= "0010010";
            elsif min1 = 6 then
                DISP <= "1000000";
            end if;
        when 2 =>
            tmp_AN <= "1011";
            if (hour0 = 0) then
                DISP <= "1000000";
            elsif hour0 = 1 then
                DISP <= "1111001";
            elsif hour0 = 2 then
                DISP <= "0100100";
            elsif hour0 = 3 then
                DISP <= "0110000";
            elsif hour0 = 4 then
                DISP <= "0011001";
            elsif hour0 = 5 then
                DISP <= "0010010";
            elsif hour0 = 6 then
                DISP <= "0000010";
            elsif hour0 = 7 then
                DISP <= "1111000";
            elsif hour0 = 8 then
                DISP <= "0000000";
            elsif hour0 = 9 then
                DISP <= "0010000";
            elsif hour0 = 10 then
                DISP <= "1000000";
            elsif hour0 = 11 then
                DISP <= "1111001";
            elsif hour0 = 12 then
                DISP <= "0100100";
            elsif hour0 = 13 then
                DISP <= "1000000";
            end if;
        when 3 =>
            tmp_AN <= "0111";
            if (hour0 = 10) then
                DISP <= "1111001";
            elsif hour0 = 11 then
                DISP <= "1111001";
            elsif hour0 = 12 then
                DISP <= "1111001";
            else 
                DISP <= "1000000";
            end if;
    end case;
end process;

die Ausgabe (wie ich wollte):Geben Sie hier die Bildbeschreibung ein

der Code, der für die Anzeige von 6 Anoden verantwortlich ist (Ziffern sind nicht klar lesbar):

anode_clock : process(count1, clk_in, A_counter) -- counter to display all digits using anodes
begin 
    if(rising_edge(clk_in)) then
        count1 <= count1 + 1;
        if(count1 = 125000) then -- experimental value: 249999
            A_counter <= A_counter + 1;
            count1 <= 0;
        end if;
    end if;
end process;

anode_display : process (A_counter, tmp_AN, sec0,sec1, min0, min1, hour0) begin -- matching anodes to display
    AN <= tmp_AN;
    case A_counter is
        when 0 =>
            tmp_AN <= "111110";
            if (sec0 = 0) then
                DISP <= "1000000";
            elsif sec0 = 1 then
                DISP <= "1111001";
            elsif sec0 = 2 then
                DISP <= "0100100";
            elsif sec0 = 3 then
                DISP <= "0110000";
            elsif sec0 = 4 then
                DISP <= "0011001";
            elsif sec0 = 5 then
                DISP <= "0010010";
            elsif sec0 = 6 then
                DISP <= "0000010";
            elsif sec0 = 7 then
                DISP <= "1111000";
            elsif sec0 = 8 then
                DISP <= "0000000";
            elsif sec0 = 9 then
                DISP <= "0010000";
            end if;
        when 1 =>
            tmp_AN <= "111101";
            if (sec1 = 0) then
                DISP <= "1000000";
            elsif sec1 = 1 then
                DISP <= "1111001";
            elsif sec1 = 2 then
                DISP <= "0100100";
            elsif sec1 = 3 then
                DISP <= "0110000";
            elsif sec1 = 4 then
                DISP <= "0011001";
            elsif sec1 = 5 then
                DISP <= "0010010";
            elsif sec1 = 6 then
                DISP <= "1000000";
            end if;
        when 2 =>
            tmp_AN <= "111011";
            if (min0 = 0) then
                DISP <= "1000000";
            elsif min0 = 1 then
                DISP <= "1111001";
            elsif min0 = 2 then
                DISP <= "0100100";
            elsif min0 = 3 then
                DISP <= "0110000";
            elsif min0 = 4 then
                DISP <= "0011001";
            elsif min0 = 5 then
                DISP <= "0010010";
            elsif min0 = 6 then
                DISP <= "0000010";
            elsif min0 = 7 then
                DISP <= "1111000";
            elsif min0 = 8 then
                DISP <= "0000000";
            elsif min0 = 9 then
                DISP <= "0010000";
            end if;
        when 3 =>
            tmp_AN <= "110111";
            if (min1 = 0) then
                DISP <= "1000000";
            elsif min1 = 1 then
                DISP <= "1111001";
            elsif min1 = 2 then
                DISP <= "0100100";
            elsif min1 = 3 then
                DISP <= "0110000";
            elsif min1 = 4 then
                DISP <= "0011001";
            elsif min1 = 5 then
                DISP <= "0010010";
            elsif min1 = 6 then
                DISP <= "1000000";
            end if;
        when 4 =>
            tmp_AN <= "101111";
            if (hour0 = 0) then
                DISP <= "1000000";
            elsif hour0 = 1 then
                DISP <= "1111001";
            elsif hour0 = 2 then
                DISP <= "0100100";
            elsif hour0 = 3 then
                DISP <= "0110000";
            elsif hour0 = 4 then
                DISP <= "0011001";
            elsif hour0 = 5 then
                DISP <= "0010010";
            elsif hour0 = 6 then
                DISP <= "0000010";
            elsif hour0 = 7 then
                DISP <= "1111000";
            elsif hour0 = 8 then
                DISP <= "0000000";
            elsif hour0 = 9 then
                DISP <= "0010000";
            elsif hour0 = 10 then
                DISP <= "1000000";
            elsif hour0 = 11 then
                DISP <= "1111001";
            elsif hour0 = 12 then
                DISP <= "0100100";
            elsif hour0 = 13 then
                DISP <= "1000000";
            end if;
        when 5 =>
            tmp_AN <= "011111";
            if (hour0 = 10) then
                DISP <= "1111001";
            elsif hour0 = 11 then
                DISP <= "1111001";
            elsif hour0 = 12 then
                DISP <= "1111001";
            else 
                DISP <= "1000000";
            end if;
    end case;
end process;

die Ausgabe (Ziffern sind nicht wie ich wollte, etwas sieht mit dem Anzeigezähler nicht richtig aus):Geben Sie hier die Bildbeschreibung ein

Sind Sie sicher, dass Anoden das Wort ist, das Sie wollen? Eine Anode ist nur ein Anschluss eines Geräts mit zwei Anschlüssen.
yhmm, Sie haben eine ziemlich schnelle Uhr (100 MHz), aber Sie müssen ihr beibringen, 6 BCD-Nibbles (4 Bit) und nicht 4 Binärbytes (8) zu verwenden. Setzen Sie dann einen dunkelroten durchsichtigen Kunststofffilter ein, um den Kontrast zu verbessern. Ich sehe 88061817. Ist es eine BCD-Ziffer oder HEX?
@ThePhoton Ich kenne die physikalische Bedeutung. Bei Siebensegmentanzeigen ist eine Anode meines Wissens nur eine Ziffer. Zum Beispiel gibt es auf meinem FPGA 8 Anoden für meine sieben Segmente. Ich könnte mich irren und geschätzt werden, wenn Sie mir sagen, wenn ich falsch liege.
@TonyStewart.EEseit '75 Nun, mein FPGA- und VHDL-Wissen ist ziemlich begrenzt. Ich kann Codes wie oben schreiben, weiß aber nicht, wie ich Ihren Vorschlag umsetzen soll. Kannst du mir eine Quelle nennen, wie man das macht?
Wenn LED-Werte nur Speicheradressen sind, dann googeln Sie den Mathcode für einen BCD-Taktausgang mit einem Präzisionstakteingang `zum internen Zähler idc-online.com/technical_references/pdfs/electronic_engineering und en.wikipedia.org/wiki/Binary-coded_decimal/…
Soll ich raten, ob LED-Werte nur Speicheradressen oder fest verdrahtete binär codierte Ziffern auf einem Binärzähler sind oder was? Die Bilder zählen bei mir nicht.
Der vollständige Code von @TonyStewart.EEsince'75 kann von hier aus erreicht werden: repl.it/IAEN können Sie den Grund aus diesem vollständigen Code ermitteln?
@ErenL, wenn Sie "4 Anoden einer 7-Segment-Anzeige mit gemeinsamer Kathode" geschrieben oder auch nur 7-Segment-Anzeigen erwähnt hätten, bevor Sie das Wort Anode verwendet hätten , wäre es klarer gewesen.

Antworten (3)

Dies ist eine inhärente Einschränkung des Multiplexing: Da Sie jeweils nur eine einzelne Ziffer ansteuern, wird Ihre Anzeige schwächer, wenn Sie die Anzahl der Ziffern erhöhen. Sie sollten jedoch in der Lage sein, 8-stellig zu fahren.

Ich würde versuchen, Ihren Zähler explizit zu umschließen, um sicherzustellen, dass Sie zu jedem Zeitpunkt eine bestimmte Ziffer fahren:

    if(count1 = 249999) then  -- ATTENTION HERE
        A_counter <= A_counter + 1;
        if(A_counter < 6) then -- 6 or 4, depending on how many digits you drive
            A_counter <= A_counter + 1;
        else
            counter <= 0;
        end if;
        count1 <= 0;
    end if;

Es sieht so aus, als ob Sie im 6-stelligen Code A_COUNTER kontinuierlich durchlaufen, was bedeutet, dass es mindestens 2 Zustände gibt, Zustand 6 und Zustand 7, die nicht explizit decodiert werden. Versuchen Sie, alle Segmente für die Zustände 6 und 7 explizit auszuschalten. Wenn A_COUNTER mehr als 3 Bits beträgt, müssen Sie herausfinden, was mit der Anzeige passiert, wenn A_COUNTER nicht 0 bis 5 ist.

Da die Anzeigeaktivierungen aktiv niedrig sind (0 = ein), ist es wahrscheinlich, dass alle Segmente standardmäßig eingeschaltet sind, wenn Sie ihnen nicht sagen, dass sie sich ausschalten sollen, wie dies in den Zuständen 6 und 7 passieren kann.

Als diagnostischen Ansatz können Sie COUNT1 vielleicht so weit erhöhen, dass sich die Ziffern extrem langsam ändern, sodass Sie die Beleuchtungsschritte in Zeitlupe beobachten können.

Ich bin mir nicht sicher, ob es die zusätzlichen Fälle 6 und 7 gibt. Aber da die 2 unbenutzten Ziffern (ganz links) mit allen leuchtenden Segmenten eingeschaltet sind, scheinen einige Ziffern/Segmente standardmäßig beleuchtet zu sein, wenn Sie sie nicht ausschalten. Wenn es nur 6 Fälle gibt und jeweils 1 Ziffer aktiviert ist, sollten die Ziffern 6 und 7 keine Zeit haben, eingeschaltet zu sein, aber sie sind eingeschaltet. Ich glaube, dass sowohl die Zeile als auch das Segment (00000000,00000000) standardmäßig für ein kurzes Intervall empfangen und alle Ziffern und alle Segmente einschalten.

Testen Sie dies, indem Sie Ziffernaktivierungswerte mit 8 Binärziffern (11xxxxxx) anstelle von 6 (xxxxxx) ausgeben, sodass die oberen 2 unbenutzten Ziffern ausgeschaltet sind. Die 2 Ziffern ganz links sind dunkler, aber immer noch teilweise beleuchtet.

Wenn es nicht decodierte Fälle gibt, gibt Xilinx einen Fehler aus. Sind Sie sicher, dass es Zustand 6 und Zustand 7 gibt? Weil Zähler1 als ganzzahliger Bereich von 0 bis 5 definiert ist.
Aktualisierte Antwort.

Es gibt einige Probleme mit Ihrem Code, die Sie beheben sollten, um das Debuggen zu vereinfachen. Erstens haben Sie die Kathoden [Segment] -Decodierung mehrmals dupliziert - dies muss nur einmal durchgeführt werden - ich würde einen Prozess vorschlagen, der die aktuelle Dezimalstelle als Signal auf der Empfindlichkeitsliste hat und die Segmente setzt. Der durch den Haupttakt gesteuerte Prozess wäre dann ohne die duplizierte Decodierung viel einfacher. In der Praxis werden die Synthesewerkzeuge eine solche Dekodierung wahrscheinlich effizient einer RAM-Loop-Up-Tabelle auf dem FPGA zuordnen - sie sind möglicherweise nicht in der Lage, dies für Ihren Code zu tun, z

Das vom Haupttakt gesteuerte Routing dreht sich dann zyklisch und setzt das geeignete Dezimalsignal und das Anodensignal. Mein Ansatz wäre, den Anodenausgang auf "111110" zu initialisieren und diesen bei jedem Taktzyklus im getakteten Prozess zyklisch nach links zu verschieben und in eine Logik einzufügen, um das entsprechende Ziffernsignal zur Anzeige einzustellen.

Was nicht klar ist, ist, welche Uhr Sie verwenden, um diesen Prozess zu steuern. Es sollte wahrscheinlich nicht bei etwa 100 MHz Systemtakt liegen, wenn LEDs angesteuert werden - ich würde vorschlagen, es bei etwa 1 kHz oder so zu betreiben.