Forum: FPGA, VHDL & Co. Anfänger: Wieder mal 7-Segment


von vhtl (Gast)


Lesenswert?

Ich bin VHDL-Anfänger und schaffe es einfach nicht, eine vierstellige 
7-Segment-Anzeige anzusteuern (Beispiel reduziert):
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.STD_LOGIC_ARITH.ALL;
4
use IEEE.STD_LOGIC_UNSIGNED.ALL;
5
6
entity Hello is
7
  port ( SEG7 : out STD_LOGIC_VECTOR (1 to 8) := (others => '1');
8
         ANODE : out STD_LOGIC_VECTOR (0 to 3) := (others => '0');
9
         CLK : in STD_LOGIC);
10
end Hello;
11
12
architecture V1 of Hello is
13
  signal counter : STD_LOGIC_VECTOR (15 downto 0) := "1010010110010110";
14
  signal seg7id : STD_LOGIC_VECTOR(1 downto 0) := (others => '0');
15
begin 
16
  display: process(CLK)
17
    variable digit : STD_LOGIC_VECTOR(3 downto 0);
18
  begin
19
    if rising_edge(CLK) then
20
21
      case seg7id is
22
        when "00" => ANODE <= "1110";
23
                     digit := counter(3 downto 0);
24
                     seg7id <= "01";
25
        when "01" => ANODE <= "1101";
26
                     digit := counter(7 downto 4);
27
                     seg7id <= "10";
28
        when "10" => ANODE <= "1011";
29
                     digit := counter(11 downto 8);
30
                     seg7id <= "11";
31
        when "11" => ANODE <= "0111";
32
                     seg7id <= "00";
33
                     digit := counter(15 downto 12);
34
        when others => ANODE <= "1111";
35
                       seg7id <= "00";
36
      end case;
37
      
38
      case digit is
39
        when "0000" => SEG7 <= "00000011";
40
        when "0001" => SEG7 <= "10011111";
41
        when "0010" => SEG7 <= "00100101";
42
        when "0011" => SEG7 <= "00001101";
43
        when "0100" => SEG7 <= "10011001";
44
        when "0101" => SEG7 <= "01001001";
45
        when "0110" => SEG7 <= "01000001";
46
        when "0111" => SEG7 <= "00011111";
47
        when "1000" => SEG7 <= "00000001";
48
        when "1001" => SEG7 <= "00001001";
49
        when "1010" => SEG7 <= "00010011";
50
        when "1011" => SEG7 <= "11100001";
51
        when "1100" => SEG7 <= "11100101";
52
        when "1101" => SEG7 <= "10000101";
53
        when "1110" => SEG7 <= "11000001";
54
        when "1111" => SEG7 <= "11100001";
55
        when others => SEG7 <= "11111101";
56
      end case;
57
               
58
    end if;   
59
  end process;
60
   
61
end V1;

Leider sehe ich auf der Anzeige nur 8888, wobei die richtigen Segmente 
etwas kräftiger erscheinen.

Ich hatte auch versucht, den display-Prozeß zu teilen und digit zum 
Signal zu machen, aber der Fehler blieb.

Kann mir jemand zeigen, was ich falsch mache? Oder ist der Takt zu hoch?

von Sigi (Gast)


Lesenswert?

Dein Hauptproblem ist, dass Du zum einen
den Anodenvektor zu schnell umschaltest und
zum 2. den Anodenvektor daziwschen nicht
eine Zeitlang auf "1111" setzt. Mach es
wie folgt:
"1111"  x us
"1110"  y us
"1111"  x us
"1101"  y us
etc.
x und y musst Du experimentell ermitteln:
- zu kleines x bewirkt Nachleuchten
- zu kleines y hat schwaches Leuchten zur Folge.
IdR brauchst Du also 2 Zählvariablen und eine
FSM.

von vhtl (Gast)


Lesenswert?

Herzlichen Dank, das war's!
1
signal sid : STD_LOGIC_VECTOR(7 downto 0) := (others => '0');
2
    -- ...
3
    if rising_edge(CLK) then
4
      case sid(7 downto 5) is
5
        when "000" => ANODE <= "1110";
6
                      digit := counter(3 downto 0);
7
        when "010" => ANODE <= "1101";
8
                      digit := counter(7 downto 4);
9
        when "100" => ANODE <= "1011";
10
                      digit := counter(11 downto 8);
11
        when "110" => ANODE <= "0111";
12
                      digit := counter(15 downto 12);
13
        when others => ANODE <= "1111";
14
      end case;
15
      sid <= sid + 1;
16
      -- ...

Hardware ist echt schnell! :-)

von Sigi (Gast)


Lesenswert?

Du setzt den ANODE-Vektor zwischenzeitlich
nicht auf "1111". Siehst Du bei Dir ein
"seltsames" Nachleuchten?

von vhtl (Gast)


Lesenswert?

Doch, über
1
when others => ANODE <= "1111";

bei "--1-----".

von Mike (Gast)


Lesenswert?

Ich schätze mal dein ursprünglicher Code schaltet zu früh/zu spät auf 
die nächste Stelle um. Man müsste ihn mal simulieren.

Dann solltest du dir nicht angewöhnen mit std_logic_unsigned zu rechnen 
(ist veraltet). Besser wäre es wenn du numeric_std verwendest.

Siehe hier:

http://www.mikrocontroller.net/articles/Rechnen_in_VHDL#Schlecht:_Direktes_Rechnen_mit_std_logic_vector

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Mike schrieb:
> Besser wäre es wenn du numeric_std verwendest.
> Siehe hier:...
Und hier die relevanten Umformungen:
http://www.lothar-miller.de/s9y/categories/16-Numeric_Std

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.