Anzeige einer 2-stelligen Ganzzahl auf zwei 7-Segment-Anzeigen

Ich habe Probleme beim Anzeigen einer Binärzahl in einem Display. Ich bin mir nicht sicher, wie ich eine binäre Zahl in ihre einzelnen Zahlen aufteilen soll.

Wenn ich beispielsweise 25 anzeigen möchte, möchte ich dies binär in "2" und "5" aufteilen. Ich habe 8 Bits, die hereinkommen, und möchte es in zwei 4-Bit-Teile aufteilen, wobei die ersten 4 Bits die erste Ziffer in Binärform darstellen und die zweiten 4 Bits die zweite Ziffer in Binärform darstellen.

BEARBEITEN: Zur Verdeutlichung versuche ich dies mit Logikgattern zu tun.

Welche Programmiersprache verwendest du? Oder verwenden Sie kein Mikro und suchen nach einer Lösung für Logikgatter?
Ich suche nach einer Logikgatterlösung.
Möchten Sie dies mit tatsächlich diskreter Logik tun oder indem Sie es in Verilog oder VHDL entwerfen?
Ich benutze Logisim, aber eine allgemeine Darstellung wäre auch in Ordnung, denke ich.

Antworten (5)

Die Double-Dabble- Technik wandelt binär in BCD um, indem sie wiederholt verschoben wird. Jede Wiederholung halbiert die verbleibende Binärzahl und verdoppelt die BCD-Zahl, nach Verschiebung des kompletten Binärwerts erhält man das Ergebnis. Nach jeder Verschiebung wird eine Korrektur auf jede 4-Bit-BCD-Spalte angewendet (oder diejenigen, bei denen bis zu diesem Punkt mehr als 3 Bits hineingeschoben wurden). Diese Korrektur sucht nach Ziffern, die bei der nächsten Verschiebung dezimal 9 -> 10 einen BCD-Überlauf verursachen, und korrigiert das Ergebnis durch Hinzufügen von drei .

Warum drei? BCD-Ziffern im Bereich null bis vier (0,1,2,4) werden nach der Verschiebung natürlich auf 0,2,4,8 verdoppelt. Wenn Sie 5 untersuchen b 0101, ändert sich dies zu b 1010(0xA), was keine BCD-Ziffer ist. 5 wird daher zu (3+5) korrigiert, dh b 1000(0x8), was sich während der Verschiebung auf 16 Dezimalstellen (0x10) verdoppelt, was einen Übertrag von 1 auf die nächste Ziffer und die erwartete Null darstellt.

Implementierungen wiederholen diesen Prozess, entweder zeitlich synchron unter Verwendung eines Schieberegisters und 'n' Zyklen für eine n-Bit-Eingabe oder räumlich, indem die Logikschaltungen für die Korrektur platziert werden, die sich gegenseitig speisen und die Verschiebung mit Verdrahtung durchführen. Es gibt einen Übertragspfad direkt durch jede Ziffer, und die Übertragslogik ist nicht für die (binäre) FPGA-Übertragskettenlogik geeignet, sodass die Space-Implementierung im Allgemeinen inakzeptable Timing-Ergebnisse für große Eingaben liefert. Ein typischer technischer Kompromiss.

Für eine parallele (asynchrone) Konvertierung

Für enge Werte wie Ihren bietet die Website von Dr. John Loomis eine Anleitung zur logischen Struktur, die für die Implementierung in Hardware erforderlich ist. Moderne umprogrammierbare Logik kann nach aggressiver Synthese eine Breite von 8 Bit bis vielleicht 100 MHz erreichen. Das Modul add3nimmt eine 4-Bit-Eingabe und gibt sie wortwörtlich aus, oder wenn es mehr als vier sind, fügt es drei hinzu:

module add3(in,out);
input [3:0] in;
output [3:0] out;
reg [3:0] out;

always @ (in)
    case (in)
    4'b0000: out <= 4'b0000;  // 0 -> 0
    4'b0001: out <= 4'b0001;
    4'b0010: out <= 4'b0010;
    4'b0011: out <= 4'b0011; 
    4'b0100: out <= 4'b0100;  // 4 -> 4
    4'b0101: out <= 4'b1000;  // 5 -> 8
    4'b0110: out <= 4'b1001;  
    4'b0111: out <= 4'b1010;
    4'b1000: out <= 4'b1011;
    4'b1001: out <= 4'b1100;  // 9 -> 12
    default: out <= 4'b0000;
    endcase
endmodule

Die Kombination dieser Module ergibt die Ausgabe.Module zusammen

Für eine sequentielle (Multi-Cycle, Pipelined) Variante

Für breite Signale läuft eine in Xlinx App Note „XAPP 029“ beschriebene serielle Technik mit 1 Bit pro Zyklus, wahrscheinlich bei 300 MHz+.

Wenn jemand eine gute Hybridtechnik kennt, würde mich das interessieren. Ich habe beide in Verilog mit Testbenches in meiner verilog-utils- Sammlung modelliert.

Ich mag den Xilinx-Ansatz; Es ist einfach und ermöglicht kompakten (wenn auch nicht unbedingt schnellen) Code auf Mikroprozessoren, der Anweisungen für BCD-Arithmetik enthält. Wenn man wirklich keine Geschwindigkeit braucht, kann der Xilinx-Ansatz angepasst werden, um lange Dezimalausgaben mit einer einzigen 4-Bit-BCD-Einheit zusammen mit einer Reihe von Schieberegistern zu erzeugen. Bei einer zweistelligen Zahl ist das natürlich nicht unbedingt nötig.

Was Sie tun möchten, ist als Konvertierung in binär codierte Dezimalzahlen bekannt . Einige Computer haben spezielle Anweisungen, die bei der Umwandlung in und aus BCD sowie bei der Addition und Subtraktion helfen. Das ist für Sie jedoch nicht relevant.

Der einfachste Weg, den ich kenne, um Ihre 8-Bit-Zahl in zwei 4-Bit-Zahlen umzuwandeln, besteht darin, sie in Zehnerpotenzen zu behandeln.

unsigned char eight_bit_to_two_four_bit(unsigned char value)
{
    unsigned char result = 0;

    while (value >= 10)        // First, count how many 10s fit into value
    {
        value -= 10;
        result += 0x10;        // and count them in the top 4-bits of result
    }

    result += value;           // The remainder is the number of 1s in value
                               // These end up stored in the bottom 4-bits of result

    return result;
}

Die While-Schleife dort implementiert im Grunde eine Divisionsoperation. Eine andere Möglichkeit, diese Funktion zu implementieren, ist:

unsigned char eight_bit_to_two_four_bit(unsigned char value)
{
    unsigned char result = 0;

    result  = (value / 10) << 4;
    result += (value % 10);

    return result;
}

Dies verwendet tatsächlich zwei Divisionsoperationen. Teuer! Stattdessen können wir eine der Divisionen durch eine Multiplikation und Subtraktion ersetzen.

unsigned char eight_bit_to_two_four_bit(unsigned char value)
{
    unsigned char result = 0;

    result  = (value / 10) << 4;
    result += (value - result*10);

    return result;
}

Die Tatsache, dass diese Funktion mit Divisionen implementiert wird, macht es wahrscheinlich schwierig, sie mit kombinatorischer Logik zu implementieren. Um dies in reiner Logik zu tun, besteht der beste Ansatz wahrscheinlich darin, zu versuchen, die erste Funktion zu implementieren.

Das würde ich auch machen. Schade, dass er nach einer Logikgatterlösung sucht ...
Entschuldigung, ich verstehe, wie man das logisch macht, bin mir aber nicht sicher, wie man es mit Logikgattern macht.
@YamatoC - Es ist derselbe Algorithmus, wenn Sie Logikgatter verwenden möchten. Sie müssen Divisions- und Modulo-Operationen in Ihrer Logik implementieren. Dies sind etwas komplexe Berechnungen, aber wenn Sie nach Divisionsalgorithmen suchen, sollten Sie in der Lage sein, etwas Implementierbares zu finden.

Suchen Sie einen Binär-zu-BCD-Konverter wie den 74185 ?

Wenn nicht, gibt es auf Wikipedia eine Liste mit Logikchips der Serie 7400, die Sie durchsehen und finden können, was Sie brauchen.

Eine Logikgatterlösung ist mit einer Wahrheitstabelle und Karnaugh-Karten einfach. Die Wahrheitstabelle hat den Binärwert als Eingabe und den gewünschten BCD-Wert für die Ausgabe.

Ihre Wahrheitstabelle sollte so aussehen:

a0 a1 a2 a3 | b6 b5 b4 b3 b2 b1 b0 <br>
0  0  0  0  | 0  0  0  0  0  0  0
0  0  0  1  | 7-seg output for 1
0  0  1  0  | 7-seg output for 2
and so on

Wandle dann die Wahrheitstabelle in Karnaugh-Karten (K-Karten) um und löse nach b6, b5 ... b0 auf. Nehmen Sie die resultierenden Gleichungen und implementieren Sie sie mit Logikgattern.

Informationen zu K-Maps: http://en.wikipedia.org/wiki/Karnaugh_map

Und hier ist eine Lösung, die eine ähnliche Übung mit Nand-Gattern durchläuft: http://circuitscan.homestead.com/files/digelec/bcdto7seg.htm

Bearbeiten: Aus den Kommentaren: Wenn Ihre 4-Bit-Zahl kein BCD darstellt, dh über 9 hinausgeht, würde ich die Gleichung direkt aus der Wahrheitstabelle ableiten. Also zum Beispiel für diesen Eintrag in der Wahrheitstabelle:

a0 a1 a2 a3   | output
0   1  0  1   | 0 1 1 0 1 1 0

Ihre Gleichung für das erste Bit (0) ist a0 + a1 (Balken) + a2 + a3 (Balken), das zweite Bit (1) ist a0 (Balken) + a1 + a2 (Balken) + a3 und so weiter. Die Implementierung dieser Gleichung in Logikgatter ist einfach.

Edit2: Viele dieser Gleichungen werden sich überschneiden und Sie können nach der Generierung weiter vereinfachen.

Für eine 2 (dezimal!) stellige Zahl ist das eine ziemlich große Wahrheitstabelle.
Die Wahrheitstabelle muss nur einmal für eine 4-Bit-Eingabe berechnet werden. Dieselben Gleichungen gelten für die zweite 4-Bit-Zahl.
Die Eingabe ist tatsächlich 7 Bit, nicht 4 Bit. Der Eingabebereich ist [0..99], was 7 Bit Speicherplatz erfordert.
@xyzio Nein, die Wahrheitstabelle hängt von 4 Bits + BCD-Übertrag von der vorherigen Ziffer ab
Ah, ich habe die Frage wörtlich gelesen, wobei 4 Bits = 1 BCD-Ziffer sind, was impliziert, dass die 4 Bits nur Werte bis 9 enthalten. Wenn dies der Fall ist, würde ich schummeln und direkte Gleichungen aus der Wahrheitstabelle ableiten. 7-stellige k-Karte wird unhandlich sein.

Wenn Sie die Schaltung so einfach wie möglich machen möchten, würde ich empfehlen, dass Sie anstelle der Anzeige in Dezimalzahlen Hexadezimalzahlen verwenden. In diesem Fall zeigt jede 7-Segment-Anzeige einen Wert von 0 bis 15, wobei die Zahlen 10, 11, 12, 13, 14 und 15 als A, B, C, D, E und F angezeigt werden. Dann benötigen Sie nur zwei MC14495-ICs um jeden 4-Bit-Wert in seine 7-Segment-Anzeigeausgaben umzuwandeln.