Forum: FPGA, VHDL & Co. VHDL Codeergänzung um Pushbutton zu entprellen


von Tob M. (tobp)


Lesenswert?

Hallo miteinander,

ich bin frisch in das Thema VHDL eingestiegen und versuche mit einem 
Coolrunner II CPLD einen Zähler nach Drücken eines Pushbuttons mit 
7-Segment Ausgabe zu realisieren.

Das 7-Segment gibt 0-F auf einem gewünschten 7-Segment erfolgreich aus, 
aber der Pushbutton prellt. Bitte um eine simple Code Ergänzung, damit 
jeder Tastendruck nur einfach gezählt wird. Zwar habe ich viele 
Lösungsmöglichkeiten bei Suchmaschinen ermittelt, aber die Adaption an 
meinen VHDL Code gelingt mir einfach nicht.

Vielen Dank
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.STD_LOGIC_UNSIGNED.ALL;
4
5
entity eigener_count is
6
    Port ( --switches : in  STD_LOGIC_VECTOR(4 downto 0);
7
           --LEDs     : out STD_LOGIC_VECTOR(3 downto 0);
8
           clk      : in STD_LOGIC;
9
        taster     : in STD_LOGIC;
10
        --BCD_IN    : inout STD_LOGIC_VECTOR(3 downto 0);
11
        --SSEG     : out STD_LOGIC_VECTOR(6 downto 0);
12
        ausgang_7seg : out  STD_LOGIC_VECTOR (6 downto 0);
13
        ausgang_anode : out STD_LOGIC_VECTOR (3 downto 0);
14
        reset    : in STD_LOGIC
15
         );
16
end eigener_count;
17
18
architecture Behavioral of eigener_count is
19
    --signal counter : STD_LOGIC_VECTOR(29 downto 0) := (others => '0');
20
   --signal taster_deb : std_logic := '0';
21
   signal counter : STD_LOGIC_VECTOR(3 downto 0) := (others => '0');
22
   signal taster_old : std_logic := '0';
23
begin
24
    with counter select
25
  ausgang_7seg <=   "0000001" when "0000",   -- 0
26
              "1001111" when "0001",   -- 1
27
              "0010010" when "0010",   -- 2
28
              "0000110" when "0011",   -- 3
29
              "1001100" when "0100",   -- 4
30
              "0100100" when "0101",   -- 5
31
              "0100000" when "0110",   -- 6
32
              "0001111" when "0111",   -- 7
33
              "0000000" when "1000",   -- 8
34
              "0000100" when "1001",   -- 9
35
              "0001000" when "1010",   -- A
36
              "1100000" when "1011",   -- b
37
              "0110001" when "1100",   -- C
38
              "1000010" when "1101",   -- d
39
              "0110000" when "1110",   -- E
40
              "0111000" when "1111",   -- F
41
              "1111111" when others;   -- turn off all LED
42
              
43
ausgang_anode <= "1110";
44
45
46
--clk_proc: process(clk, reset)
47
clk_proc: process(clk, reset, taster)
48
  begin
49
     if reset = '0' then
50
    counter <= "0000";
51
    elsif rising_edge(clk) then
52
      if   (taster = '0') then --and (taster_old = '1') then
53
        counter <= counter+1;
54
  
55
      end if;
56
      --taster_old <= taster;
57
    end if;
58
    
59
  
60
end process;
61
62
63
64
end Behavioral;

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


Lesenswert?

Tob M. schrieb:
> Zwar habe ich viele Lösungsmöglichkeiten bei Suchmaschinen ermittelt,
> aber die Adaption an meinen VHDL Code gelingt mir einfach nicht.
Du musst zuallererst den asynchronen Taster Einsynchronisieren. Und 
danach Entprellen und eine Flankenerkennung drauf ansetzen:
http://www.lothar-miller.de/s9y/categories/35-Einsynchronisieren
http://www.lothar-miller.de/s9y/categories/18-Flankenerkennung
http://www.lothar-miller.de/s9y/categories/5-Entprellung

: Bearbeitet durch Moderator
von Tob M. (tobp)


Lesenswert?

Danke Herr Miller. Ihre Beispiele hatte ich mir bereits mehrfach 
angeschaut. Sie sind schön aufgelistet und darstellt, aber mir gelingt 
der Transfer auf meinen VHDL-Code nicht.

Wie würde ich zum Beispiel Ihre Tasterentprellung anwenden? In meinem 
Grundverständnis müsste doch "keyin" in Verbindung mit "keyout" als 
Ersatz für "taster" auftreten, oder?
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.numeric_std.ALL;
4
5
entity Debounce is
6
    Port ( clk    : in  STD_LOGIC;
7
           keyin  : in  STD_LOGIC;
8
           keyout : out  STD_LOGIC);
9
end Debounce;
10
11
architecture Behavioral of Debounce is
12
signal keydeb : std_logic := '0';
13
signal debcnt : integer range 0 to 63 := 0;
14
begin
15
   process begin
16
      wait until rising_edge(clk);
17
      -- XOR
18
      if (keyin=keydeb) then debcnt <= 0;
19
      else                   debcnt <= debcnt+1;
20
      end if;
21
      -- Latch
22
      if (debcnt=63) then keydeb <= keyin; 
23
      end if;
24
   end process;
25
   keyout <= keydeb;
26
27
end Behavioral;

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


Lesenswert?

Tob M. schrieb:
> Wie würde ich zum Beispiel Ihre Tasterentprellung anwenden?
Du könntest sie als Komponente in dein Projekt einbinden. Das wäre der 
übliche Weg.

Du könntest sie einfach reinkopieren. Das wäre der wilde Hack:
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.numeric_std.ALL;
4
5
entity eigener_count is
6
    Port ( clk      : in STD_LOGIC;
7
        taster     : in STD_LOGIC;
8
        ausgang_7seg : out  STD_LOGIC_VECTOR (6 downto 0);
9
        ausgang_anode : out STD_LOGIC_VECTOR (3 downto 0);
10
        reset    : in STD_LOGIC
11
         );
12
end eigener_count;
13
14
architecture Behavioral of eigener_count is
15
   signal taster_old : std_logic := '0';
16
   signal taster_deb : std_logic := '0';
17
   signal debcnt : integer range 0 to 63 := 0;
18
19
   signal counter : integer range 0 to 15 := 0;
20
begin
21
    with counter select
22
  ausgang_7seg <=
23
              "0000001" when 0,   -- 0
24
              "1001111" when 1,   -- 1
25
              "0010010" when 2,   -- 2
26
              :
27
              "1000010" when 13,   -- d
28
              "0110000" when 14,   -- E
29
              "0111000" when 15;   -- F
30
              
31
ausgang_anode <= "1110";
32
33
34
  clk_proc: process(clk, reset, taster)
35
  begin
36
     if reset = '0' then
37
       counter <= "0000";
38
     elsif rising_edge(clk) then
39
       if taster_deb='1' and taster_old='0' then -- Flankenerkennung
40
         counter <= counter+1;
41
       end if;
42
       taster_old <= taster_deb;
43
     end if;
44
  end process;
45
46
   process begin
47
      wait until rising_edge(clk);
48
      -- XOR
49
      if (taster=taster_deb) then debcnt <= 0;
50
      else                        debcnt <= debcnt+1;
51
      end if;
52
      -- Latch
53
      if (debcnt=63) then taster_deb <= taster; 
54
      end if;
55
   end process;
56
57
end Behavioral;

von Klakx (Gast)


Lesenswert?

noch eine Ergänzung zum Thema Verstänis, falls das nicht jetzt schon 
später dir deutlich geworden ist.

Auch wenn dein Taster nicht prellen würde, würde der Druck der Taste 
mehrere Takte in Anspruch nehmen und dadurch dein Counter pro Druck 
mehrmals zählen.

Deshalb wie bereits angesprochen: Flanke erkennen und danach für ein 
paar Millisekunden den Taster "stumm" setzen.

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.