Hallo Kollegen!
ich sitze gerade vor dem Problem einen VHDL Code zu schreiben der einen
1 Byte Eingang umrechnen soll und die PIN's der LED's einzeln direkt
ansteuern soll. Z.b die Dual Zahl 0000 0000 soll die LED's a,b,c,d,e,f
ansteuern. Wenn ich das alles einzeln ausführen würde, dann hätte ich 99
IF Anweisungen. Kann mir da jemand weiterhelfen?
Viele Grüße
Zepter96
zepter96 schrieb:> dann hätte ich 99 IF Anweisungen. Kann mir da jemand weiterhelfen?
Aufgabe 1: stelle 0..9 auf 1 Anzeige dar.
Aufgabe 2: teile den 1 Wert in 2 Stellen mit 0..9 auf
Aufgabe 3: verbinde Lösung 2 mit 2x Lösung 1
Sieh dir an, ob dir das weiterhilft:
http://www.lothar-miller.de/s9y/categories/44-BCD-Umwandlung
für eine 7-Segment-Anzeige reichen dir 4 Bit, also ein halbes Byte. Du
brauchst also für 10 Ziffern nur 10 IFs. Kannst du den Eingang verunden?
Ich kenne kein VHDL, aber das sollte doch da auch gehen.
IF (Eingang & 0x01) -> Bitmuster am Ausgang für 1
IF (Eingang & 0x02) -> Bitmuster am Ausgang für 2
....
Hi
Früher hat man sich angeschaut, welche Segmente bei weöchen Eingängen
leuchten sollen und hat Diese logisch zusammen gefasst.
Ist wohl heute nicht mehr so :/
Bei BCD ist's ja Mal gar kein Problem ... ich sehe schon die
Google-Treffer, wo ich Google noch gar nicht offen habe, so viele kommen
Da ...
MfG
Wenn ich den TO richtig verstanden habe, dann will er
nicht nur 0 bis 9 darstellen, sondern 0 bis F. Das geht
problemlos auf einer 7-Segment-Anzeige: A,b,C,d,E,F.
Bit-7 von Tabelle und von Wert wird nicht gebraucht und wegoptimiert.
Je nach Ansteuer-Elektronik der Segmente kann es sein, dass man Wert
invertieren muss, also einfach not wert ausgeben.
Der Code stammt aus den Dateien kde0.vhd und knxs.vhd meines Projekts.
8bit-Computer: bo8h
Josef G. schrieb:> Wenn ich den TO richtig verstanden habe, dann will er> nicht nur 0 bis 9 darstellen, sondern 0 bis F
Ich sehe es so: er will 00 bis 99 darstellen und die Segmente seiner
beiden Anzeigen sind im Uhrzeigersinn mit abcdef und g benannt. Wie
allgemein üblich leuchten für die 0 alle äußeren Segmente, also abcde
und f.
Ok, er schreibt
zepter96 schrieb:> dann hätte ich 99 IF Anweisungen.
Andererseits bräuchte er für ein Byte dann 3 Digits,
im Widerspruch zum Titel. Darum dachte ich, er braucht
Hex-Stellen. Aber vielleicht meint er ja mit Byte einen
Wert im Packed-BCD-Format. Dafür ginge dann auch mein Code.
Dass er einen Binärwert im Bereich 0..99(dez) vorliegen
hat, wäre nach meiner Kenntnis eher ungewöhnlich.
Josef G. schrieb:> Das geht problemlos auf einer 7-Segment-Anzeige: A,b,C,d,E,F.
Sollte heissen: Für b und d muss man Kleinbuchstaben verwenden.
Mit A,b,C,d,E,F war nicht die Nummerierung der Segmente gemeint.
Josef G. schrieb:> Dass er einen Binärwert im Bereich 0..99(dez) vorliegen> hat, wäre nach meiner Kenntnis eher ungewöhnlich.
und es wären nur 7 Bit, er schreibt aber:
zepter96 schrieb:> die Dual Zahl 0000 0000 soll
Vielen vielen Dank erstmal für die schnellen Antworten! Also ich habe
hier eine dual 7 Segment Anzeige vorliegen. Das heißt die Anzeige ist
bis 99 begrenzt. Was reinkommt ist ein 8 bit Wert. Ja! Es können Zahlen
höher 99 vorkommen, jedoch möchte ich bzw. muss ich die Zahl auf 99
begrenzen. Ich stehe einfach auf dem Schlauch, was die Ansteuerung des
dual 7 Seg. Anzeiges angeht. Ich hatte vor erst den 8 bit Wert in
Integer umzuwandeln. Anschließend durch 10 Teilen und dies ist mein
erster Wert für den Dig1. Modulo 10 ist meine zweite Anzeige. Schön und
gut, jetzt sind meine Zahlen für beide Anzeigen da, jedoch weiß ich
nicht wie ich mit nur mit der Ansteuerung umgehen soll. Sagen wir ich
habe jetzt in der variable Seg1= 1 und in Seg2 = 2. Wie soll ich nun das
ganze ansteuern? Für die Zahl 0 habe ich die Kombination : 0111111
(g,f,e,d,c,b,a) (Das sind die einzelnen LED's. Wenn ich jetzt überall
diese kombinationen reinknallen muss, dann wird das ganze mal schnell
unübersichtlich. Habt ihr vielleicht eine Lösung für mich ?
Beste Grüße!
zepter96 schrieb:> Für die Zahl 0 habe ich die Kombination : 0111111
Das ist genau der Wert x"3f" aus meiner Tabelle Version-1.
Schau dir meine Lösung nochmal an. Das ist was du suchst.
Wenn du nur 0 bis 9 brauchst, kannst du die
Werte für 10 bis 15 durch dont care ersetzen.
Für die Konvertierung des Binärwerts in zwei
BCD-Stellen siehe den Beitrag von Lothar Miller.
Oder du machst Konvertierung und Dekodierung auf einmal nach
meinem Muster. Dann wären wert und tabelle 16-Bit breit, wobei
Bit-15 und Bit-7 nicht gebraucht werden, und der Index von
tabelle liefe von 0 bis 127, wobei die Werte oberhalb von 99
dont care sein dürfen.
Das Ausrechnen der Tabelle würde ich auf
dem PC mit einem C-Programm erledigen.
zepter96 schrieb:> Ich stehe einfach auf dem Schlauch, was die Ansteuerung des dual 7> Seg. Anzeiges angeht.
Wie eine einzelne 7-Segmentanzeige angesteuert wird, dafür gibt es doch
sicher zig zehntausend Beispiele im Netz (das zigzehntausendunderste
dann hier im Thread).
> Ich hatte vor erst den 8 bit Wert in Integer umzuwandeln.
Ich habe den Verdacht, dir fehlt grundsätzlich das Verständnis der
binären Zahlendarstellung. Das solltest du ändern...
In der Hardwarewelt sind diese selbstgesteckten 8-Bit Grenzen aus der
Prozessorwelt absolut irrelevant. Hier wird jede Zahl prinzipiell nur so
"breit" umgesetzt, wie es unbedingt nötig ist. Wenn du z.B. einen Zähler
von 0..29 hast, dann braucht der 5 Bit. Und er wird in der Hardware auch
nur 5 Flipflops einnehmen, auch wenn du sagst, der Zähler solle ein
Integer sein.
> Ich hatte vor erst den 8 bit Wert in Integer umzuwandeln. Anschließend> durch 10 Teilen und dies ist mein erster Wert für den Dig1. Modulo 10> ist meine zweite Anzeige. Schön und gut, jetzt sind meine Zahlen für> beide Anzeigen da, jedoch weiß ich nicht wie ich mit nur mit der> Ansteuerung umgehen soll. Sagen wir ich habe jetzt in der variable Seg1=> 1 und in Seg2 = 2. Wie soll ich nun das ganze ansteuern?
Vergiss diese ganze Modulo-Rechnerei und Mikrocontroller-Programiererei.
Du musst in Hardware denken, sonst wird das nichts.
Hast du mal auf den geposteten Link geklickt? Hast du da dann nicht
gefunden, was dir helfen könnte? Kannst du dir nicht vorstellen, dass
dir diese BCD-Darstellung weiterhelfen würde? Oder ist dir nicht klar,
wie es dir helfen könnte?
Josef G. schrieb:> zepter96 schrieb:>> Für die Zahl 0 habe ich die Kombination : 0111111> Das ist genau der Wert x"3f" aus meiner Tabelle Version-1.> Schau dir meine Lösung nochmal an. Das ist was du suchst.
Josef, deine Lösung ist viel zu "ausgefuchst". Natürlich ist sie
naheliegend, wenn man in ROM-Blöcken und Speichern denkt. Aber davon
sind wir hier noch weit, weit entfernt...
Ich gehe mal einen Schritt zurück und zitiere mich selbst:
Lothar M. schrieb:> zepter96 schrieb:>> dann hätte ich 99 IF Anweisungen. Kann mir da jemand weiterhelfen?> Aufgabe 1: stelle 0..9 auf 1 Anzeige dar.
Probiers mal so:
https://www.google.de/search?q=7+segment+vhdl
Und dort dann den ersten Treffer:
http://vhdlguru.blogspot.de/2010/03/vhdl-code-for-bcd-to-7-segment-display.html
Und jetzt versuche zu verstehen, was da gemacht wird: die LEDs sind
dort so angeschlossen, dass ein LOW-Pegel das Segment einschaltet.
Also wird dort aus deinem 0111111 ein 1000000. Und zudem hat der, der
das geschreiben hat, seine Segmente andersrum angeschlossen, ergibt also
0000001. Findest du dieses Bitmuster dort im Code? Sind dir dann mit
einigem Nachdenken auch die anderen Bitmuster klar? Und ist dir dann
klar, wie man 1 einzige 7-Segment-Anzeige mit einem 4 Bit breiten Vektor
(=ein halbes Byte) ansteuert?
Gut, dann
> Aufgabe 2: teile den 1 Wert in 2 Stellen mit 0..9 auf
Du hast eine 8-Bit Zahl, von 0..99 die musst du jetzt in 2 4 Bit breite
Zahlen umrechnen, die dann jeweils die Zehner und die Einerstelle
beinhalten. Dazu habe ich das Stichwort BCD genannt. Der Rest ist
Knobeln und Nachdenken.
Nach ein paar bemalten Blättern Papier dann zur
> Aufgabe 3: verbinde Lösung 2 mit 2x Lösung 1
Jetzt hast du zwei Schaltungsteile:
1. die Ansteuerung einer (in Zahlen 1) 7-Segment-Anzeige und
2. die Umwandlung einer Binärzahl in einzelne Dezimalstellen
Jetzt machst du ein VHDL "Top-Modul", in das du die Komponente
"7-Segment-Anzeige" und die Komponente "BCD-Umwandler" einbindest, dann
2 der "7-Segment-Anzeige" Module instantiierst und auf vorteilhafte
Weise mit dem "BCD-Umwandler" verbindest.
Und wie gesagt nochmal die Zusammenfassung in Kürze:
Vergiss diese Programmierdenkweise.
Mit VHDLbeschreibst du Hardware!
Du musst "in Hardware denken", sonst wird das nix...
Josef G. schrieb:> Das Ausrechnen der Tabelle würde ich auf> dem PC mit einem C-Programm erledigen.
Korrektur: Man muss gar nichts rechnen, man braucht nur jeweils
zwei Werte aus obiger Tabelle Version-1 nebeneinander schreiben.
In jeder Zeile 10 Werte je 16-Bit:
1
x"3f3f",x"3f06",..,x"3f7f",x"3f6f",
2
x"063f",x"0606",..,x"067f",x"066f",
3
x"5b3f",x"5b06",..,x"5b7f",x"5b6f",
4
..
Lothar M. schrieb:> Und zudem hat der, der das geschreiben hat,> seine Segmente andersrum angeschlossen,
Nein, er hat geschrieben:
zepter96 schrieb:> Für die Zahl 0 habe ich die Kombination :> 0111111 (g,f,e,d,c,b,a)
Und das ist mein Wert x"3f", wie ich geschrieben habe.
Die Invertierung der Pegel, falls erforderlich, kann man,
wie ich geschrieben habe, ganz am Schluss bei der Ausgabe
berücksichtigen. Ich glaube nicht, dass das zu unnötigen
Negationsgliedern führt, sondern dass die Synthese das
durch Umdefinition der Signale realisiert.
zepter96 schrieb:> Also ich habe> hier eine dual 7 Segment Anzeige vorliegen. Das heißt die Anzeige ist> bis 99 begrenzt.
Das ist schon mal falsch oder zumindest irreführend. Eine duale
Anzeige würde eine LED pro Bit haben. Mit etwas Übung kann auch
ein Mensch eine solche Anzeige ablesen und interpretieren. Was
Du hast, ist vermutlich eine doppelte BCD (binär codierte Dezi-
male) Anzeige.
> Ich stehe einfach auf dem Schlauch, was die Ansteuerung des> dual 7 Seg. Anzeiges angeht.
Nun, so etwas ist eher trivial, weil man solche Anzeigen inzwischen
in fast jedem elektronischen Gerät hat. Es gibt verschiedene Metho-
den, wie man Dualzahlen in BCD-Zahlen umwandelt. Ich glaube, es
sind inzwischen alle gängigen in diesem Thread erklärt. Meistens
nimmt man aber einfach den praktisch immer vorhandenen Befehl im
jeweils verwendeten Mikrocomputer dafür. Für die Umwandlung von
BCD in Siebensegment gibt es spezielle ICs. ES gibt aber auch
passende, fertige Unterprogramme für µCs dafür.
Harald W. schrieb:> zepter96 schrieb:>>> Also ich habe>> hier eine dual 7 Segment Anzeige vorliegen. Das heißt die Anzeige ist>> bis 99 begrenzt.>> Das ist schon mal falsch oder zumindest irreführend...
...
>> Nun, so etwas ist eher trivial,...
Ich muß es einfach loswerden, sorry.
Das ist wahrlich mit eine der faszinierendsten Antworten, die ich auf
mikrocontroller.net je gelesen habe.
Erst die Frage nicht verstanden, dann mit der falsch verstandenen Frage
den TO der Ahnungslosigkeit bezichtigt und anschließend mit vielen
Worten die Trivialität der Lösung beschrieben ohne auch nur ansatzweise
überhaupt irgendwas dazu beizutragen.
Wirtschaftsingeneur? Berater? Politiker?
Falls nicht: da hättest Du sicher eine große Zukunft vor dir.
Lothar M. schrieb:> Und zudem hat der, der das geschreiben hat,> seine Segmente andersrum angeschlossen,
Sorry für's nochmal aufwärmen, es ist eigentlich
alles gesagt. Aber das will ich noch loswerden:
Ich habe zu spät gemerkt, dass die Aussage
sich auf die verlinkte Seite bezieht.
Die dort angegebenen Werte entsprechen meiner
Tabelle Version-2, mit invertierten Pegeln.
Josef G. schrieb:> Oder du machst Konvertierung und Dekodierung auf einmal nach> meinem Muster. Dann wären wert und tabelle 16-Bit breit, wobei> Bit-15 und Bit-7 nicht gebraucht werden, und der Index von> tabelle liefe von 0 bis 127, wobei die Werte oberhalb von 99> dont care sein dürfen.
Hab's nicht getestet, aber es sollte funktionieren:
Josef G. schrieb:> x"663f",x"6606",x"665b",x"664f",x"6666",x"666d",x"667d",x"6607",x"667f",
x"666f",
> x"6d3f",x"6d06",x"6d5b",x"6d4f",x"6d66",x"6d6d",x"6d7d",x"6d07",x"6d7f",
x"6d6f",
> x"7d3f",x"7d06",x"7d5b",x"7d4f",x"7d66",x"7d6d",x"7d7d",x"7d07",x"7d7f",
x"7d6f",
Das Josef fließend hex spricht ist bekannt. Da sich der Rest der
Menschheit damit offenbar schwer tut, hier eine Fragment, wie ich das
Problem angehen würde:
1
...
2
withdigit_outselect
3
-- abcdefg
4
seg_bits<="1111110"whenx"0",
5
"0110000"whenx"1",
6
"1101101"whenx"2",
7
"1111001"whenx"3",
8
"0110011"whenx"4",
9
"1011011"whenx"5",
10
"1011111"whenx"6",
11
"1110000"whenx"7",
12
"1111111"whenx"8",
13
"1111011"whenx"9",
14
"0000000"whenothers;
15
...
Wer es noch weiter treiben will, definiert sich für die Segmente
passende Konstanten:
>Das Josef fließend hex spricht ist bekannt.
Der Ansatz ist aber interessant: Einfach eine Tabelle mit 100 Einträgen,
in der alle Segmente der zwei Anzeigen zu finden sind.
Es wird für die Umsetzung also ein Speicher von 200Byte gebraucht.
Ist es ökonomischer als die Schaltung als Logik zu implementieren? ..
vielleicht ..
chris schrieb:> Es wird für die Umsetzung also ein Speicher von 200Byte gebraucht. Ist> es ökonomischer als die Schaltung als Logik zu implementieren?
Wenn man RAMBlöcke übrig hat sowieso...
Das Aufsplitten braucht auf einem Spartan6 lt. Synthese 11 LUT6. Bei
einem MachXO2 werden 17 LUT4 benötigt (Quartus hab ich hier nicht). Dazu
käme noch die Konvertierung von dezimal zu 7-Segment.
Aber ja, mit einer Tabelle kann man zur Not alle Probleme erschlagen :-)
(siehe Tafelwerk, für die jüngeren Semester...)
Duke
Divisionen gehen schon, in der Simulation problemlos. Bei der Synthese
sollte man bei Platzproblemen nur mit fixen Zweierpotenzen dividieren
:-)
Alles andere führt zu einem Logikhaufen. Für die paar Bits im Beispiel
geht das schon.
Schwierig wird die Division, wenn der Divisor variabel ist. Ich verwende
dafür einen IP-Core der pro Bit einen Takt braucht.
Duke
chris schrieb:> Ich dachte, Divisionen sind in VHDL zu vermeiden
Divisionen durch Zweierpotenzen gingen schon immer (ist ja einfach: Bits
abschneiden = anders verdrahten, wobei dieses simple Verfahren nur für
positive Zahlen korrekt ist, negative werden in die falsche Richtung
abgeschnitten). Inzwischen können Synthesizer auch beliebige Konstanten,
und optimiert sind dabei natürlich so simple, alltägliche, eben
"menschliche" Divisionen durch Zehnerpotenzen.