Forum: FPGA, VHDL & Co. Newbie - 7-Segment-Zähler funktioniert nicht


von Lasse S. (cowz) Benutzerseite


Lesenswert?

Hallo,

ich habe gestern angefangen, VHDL zu lernen. Programmieren tue ich auf 
einem Xilinx CPDL (9536).

Nun funktioniert mein Programm nicht und ich hoffe auf eure Hilfe, da 
ich den Fehler nicht finde.

Ziel des Programmes ist es, bei jeder positiven Flanke auf einem 
Zähleingang eine Nummer höher zu zählen und diese auf einem 
7-Segment-Display auszugeben. Den Zähleingang betreibe ich mit nem NE555 
mit etwa 1Hz.

Das Problem: Er zählt nicht 1, 2, 3, 4, ... sondern überspringt einige 
Zahlen und springt wohl auch ab und zu in das "when others".
1
entity SegCounter is
2
    Port ( clk : in  STD_LOGIC;
3
           SEG : out  STD_LOGIC_VECTOR (6 downto 0));
4
end SegCounter;
5
6
architecture Behavioral of SegCounter is
7
  signal number : integer range 0 to 10 := 0;
8
begin
9
10
  CountUp : process (clk)
11
  begin
12
    if rising_edge(clk) then
13
      number <= number + 1;
14
      if (number = 10) then
15
        number <= 0;
16
      end if;
17
      
18
      case number is
19
        when 0      => SEG <= "0000001";--"1110111";
20
        when 1      => SEG <= "0000011";--"0100100";
21
        when 2      => SEG <= "0000111";--"1101011";
22
        when 3      => SEG <= "0001111";--"1101101";
23
        when 4      => SEG <= "0011111";--"0111100";
24
        when 5      => SEG <= "0111111";--"1011101";
25
        when 6      => SEG <= "1111110";--"1011111";
26
        when 7      => SEG <= "1111100";--"1110100";
27
        when 8      => SEG <= "1111000";--"1111111";
28
        when 9      => SEG <= "1110000";--"1111101";
29
        when others => SEG <= "1111111";
30
      end case;      
31
    end if;
32
  end process;
33
34
end Behavioral;
Ich hoffe, ihr könnt mir zeigen, was an dem Code falsch ist. Gerne nehme 
ich auch Änderungsvorschläge der radikaleren Art auf ;) (Vielleicht 
sollte man das ganz anders angehen, ohne process o.ä....) Natürlich 
hoffe ich auch zu verstehen, warum mein Programm nicht ordentlich zählt.

Grüße, Lasse

von Jan M. (mueschel)


Lesenswert?

Woher stammt dein Zaehleingang? rising_edge kann man ausschliesslich 
fuer Taktsignale verwenden, nicht fuer irgendwelche Eingangsdaten.

von Lasse S. (cowz) Benutzerseite


Lesenswert?

clk liegt an GCK1 an (Pin 5 im PLCC-44 Gehäuse)

Was ich noch vergessen hatte: Die auskommentierten Segmentangaben sind 
dafür da, dass er wirklich die Zahlen anzeigt. Zum Testen nehme ich die 
anderen (damit ich micht nicht bei den Segmentangaben vertan haben 
kann).

Gruß, Lasse

von Jan M. (mueschel)


Lesenswert?

Was ist clk denn genau? Ein Taster? Ein Quarz?

von Lasse S. (cowz) Benutzerseite


Lesenswert?

Ein NE555.

Sollte hier etwas prellen, so würde er ja trotzdem nie in den "when 
others" case kommen, sondern nur zu schnell zwischen den Zahlen weiter 
schalten..

edit: Wenn ich mir den Clock-Eingang und das Zählverhalten angucke, 
scheint er bei steigenden und bei fallenden Flanken weiter zu zählen. 
Langsam blicke ich das nicht mehr ;)

edit2: Und wenn er erstmal in dem "when others" Fall ist (alle Segmente 
an), dauert es ein paar Takte (Also Flankenwechsel am Zähleingang), bis 
er da wieder rauskommt.

Gruß, Lasse

von Roger S. (edge)


Lesenswert?

Lasse S. wrote:
> Sollte hier etwas prellen, so würde er ja trotzdem nie in den "when
> others" case kommen, sondern nur zu schnell zwischen den Zahlen weiter
> schalten..

nein, number ist ein signal und nimmt den neuen Zustand nach abarbeitung 
des process an. somit ist number noch 10 wenns in den case reingeht.
Du solltest deine Abfrage auf 9 aendern.

Cheers, Roger

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

Die Zuweisung "<= 0" tritt erst beim nächsten Aufruf des Prozesses in 
Kraft, du zählst also von 0 bis 10 statt von 0 bis 9 und erreichst somit 
den others-Zustand. Das "Prellen" kann passieren wenn die Flanken des 
Clock-Signals zu flach und verrauscht sind.

von Lasse S. (cowz) Benutzerseite


Lesenswert?

Danke für den Hinweis mit dem Signal. Besser wäre es dann hier eine 
Variable zu nutzen? Also einfach in der Zeile mit "signal number : " das 
hier schreiben: "variable number : "... klappt das dann?

Ich hatte gerade einen NE555 genommen, da ich hoffte, dass da kein 
Prellen auftritt. Muss ich bei dem IC auch mit Prellen rechnen? Wenn ja, 
wie kann ich das lösen? (in VHDL bin ich noch nicht fit genug, das weg 
zu programmieren... Sonst würde mir als einfache Lösung noch ein 
R-C-Glied einfallen, was allerdings nicht gerade für eine steilere 
Flanke sorgen dürfte, oder? Auf einen weiteren IC würde ich gerne 
verzichten (also lieber keinen Schmitt-Trigger...)

edit: mit variable muss das dann auch nach zwischen "CountUp process" 
und "begin" und statt "number <=" schreibe ich dann "number :=". richtig 
so?

Gruß, Lasse

von Falk B. (falk)


Lesenswert?

@ Lasse S. (cowz)

>Ziel des Programmes ist es, bei jeder positiven Flanke auf einem
>Zähleingang eine Nummer höher zu zählen und diese auf einem
>7-Segment-Display auszugeben. Den Zähleingang betreibe ich mit nem NE555
>mit etwa 1Hz.

Naja, grenzwertig. Die Flanken vom NE555 sind recht flach, 200ns 
Anstiegszeit oder so.

>Das Problem: Er zählt nicht 1, 2, 3, 4, ... sondern überspringt einige
>Zahlen und springt wohl auch ab und zu in das "when others".

Logisch, dein Zähler zählt ja auch 0,1,2,3,4,5,6,7,8,9,10,0,...

Das mit den unregelmässigen Sprüngen liegt wahrscheinlich am grausamen 
Hardwareaufbau, Steckbrett ohen 100nF Kondenatoren. Hab ich Recht? ;-)

MFG
Falk

von Roger S. (edge)


Lesenswert?

Lasse S. wrote:
> Das Problem: Er zählt nicht 1, 2, 3, 4, ... sondern überspringt einige
> Zahlen und springt wohl auch ab und zu in das "when others".
>
> Wenn ich mir den Clock-Eingang und das Zählverhalten angucke,
> scheint er bei steigenden und bei fallenden Flanken weiter zu zählen.
> Langsam blicke ich das nicht mehr ;)

Klingt nach unsauberem Takt, schalt doch mal ein 74HC14 Gatter 
dazwischen, das hat eine schnellere rise/fall time als dein NE555.
Und ueberpruefe dein pinning.

Denn sonst ist dein code ja ok.

> Sonst würde mir als einfache Lösung noch ein R-C-Glied einfallen, was allerdings 
nicht gerade für eine steilere Flanke sorgen dürfte, oder?

um Himmels Willen, NEIN!

> Auf einen weiteren IC würde ich gerne verzichten (also lieber keinen 
Schmitt-Trigger...)

Bleibt dir nichts anderes uebrig.

Cheers, Roger

von Falk B. (falk)


Lesenswert?

@  Lasse S. (cowz)

>Danke für den Hinweis mit dem Signal. Besser wäre es dann hier eine
>Variable zu nutzen?

NEIN! Du musst auch number=9 prüfen. Siehe VHDL.

>Prellen auftritt. Muss ich bei dem IC auch mit Prellen rechnen?

Prellen nicht, aber schnarchlangsame Flanken.

>Wenn ja, wie kann ich das lösen?

Nimm einen 74HC14 als Oszillator.

>R-C-Glied einfallen,

AHHHH!!! NEIN!

>verzichten (also lieber keinen Schmitt-Trigger...)

DOCH!

MFG
Falk

von Lasse S. (cowz) Benutzerseite


Lesenswert?

Falk Brunner wrote:

> Logisch, dein Zähler zählt ja auch 0,1,2,3,4,5,6,7,8,9,10,0,...

Ja, das Problem wurde ja schon angesprochen. Habe das jetzt mit der 
Variable gelöst (wenn es denn

> Das mit den unregelmässigen Sprüngen liegt wahrscheinlich am grausamen
> Hardwareaufbau, Steckbrett ohen 100nF Kondenatoren. Hab ich Recht? ;-)

Steckbrett ja, 100nF hab ich eigentlich recht viele. Nur der NE555 hatte 
bisher noch keinen. Kommt jetzt aber.


Roger Steiner wrote:
> Klingt nach unsauberem Takt, schalt doch mal ein 74HC14 Gatter
> dazwischen, das hat eine schnellere rise/fall time als dein NE555.
> Und ueberpruefe dein pinning.
Das Pinning sollte stimmen, es funktioniert ja auch ansich. Nur eben der 
komische Zählfehler.

> Denn sonst ist dein code ja ok.
Das ist sehr beruhigend :) Darauf kommt es nämlich im Moment an, beim 
Lernen von VHDL.

Falk Brunner wrote:
> NEIN!
Wieso? Wenn ich eine Variable benutze, wird die doch sofort gesetzt und 
kann "daher in einem Prozess gleich weiterverwendet werden", oder doch 
nicht?

> AHHHH!!! NEIN! [...] DOCH!
ok ;) Einen 7414 habe ich gerade nicht da, funktioniert auch ein 7404?

Gruß, Lasse

von Falk B. (falk)


Lesenswert?

@ Lasse S. (cowz)

>Ja, das Problem wurde ja schon angesprochen. Habe das jetzt mit der
>Variable gelöst (wenn es denn

Das solltest du lassen, Lasse ;-)
Warum?

http://www.mikrocontroller.net/articles/VHDL#Grundregeln_f.C3.BCr_synthetisierbaren_VHDL-Code

>> NEIN!
>Wieso? Wenn ich eine Variable benutze, wird die doch sofort gesetzt und
>kann "daher in einem Prozess gleich weiterverwendet werden", oder doch
>nicht?

Jain.

Siehe oben. Du musst erstmal die Grundlagen verstehen. Variablen kommen 
später.

>ok ;) Einen 7414 habe ich gerade nicht da, funktioniert auch ein 7404?

Mit der richtigen Schaltung ja. Die braucht drei gateer und einen 
Kondensator. Hab jetzt aber keinen Link papat.

MFG
Falk

von Lasse S. (cowz) Benutzerseite


Lesenswert?

Hi,

juhu! jetzt funktioniert es!

Ich habe statt dem NE555 einen Quarzoszillator angeschlossen. Es schien 
also wirklich an dem Taktgeber zu liegen.

Vielen Dank!

Jetzt muss ich mir nur noch angucken, wie ich den Takt teilen kann, und 
zwar geschickter als mit zwei "Hochzähl"-Schleifen. Aber da finde ich 
bestimmt was im Wiki.

Vielen Dank für eure Hilfe :)

Gruß, Lasse

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.