FPGA: Eingabe über Schalter (Permalink)

Als weiterer Schritt mit dem FPGA Board nach der 7-Segment Anzeige soll die Möglichkeit darstellen ein Byte  über Schalter einzugeben. Zusätzlich soll noch ein Taster verwendet werden, um eine Eingabe gezielt vornehmen zu können. Auch hier gilt, dass auf teureren Boards wie dem Terasic Cyclone V GX Starter Kit entsprechende Hardware bereits vorhanden ist.

Hardware

Auf dieser Webseite wird beschrieben, wie Taster und Schalter einen einen Spartan-3A FPGA angebunden werden. Eine Adaption dieser Schaltung, bei der auch der Taster active low und zusätzlich mit einem Kondensator beschaltet ist, findet man hier:

Schaltplan

Aufgebaut auf der üblichen Lochrasterplatine sieht die Platine dann so aus (hier wären die Schalter eine Nummer größer besser gewesen):

aufgebautes Modul

Die Pins auf der oberen Seite besitzen folgende Bedeutung:

PIN Nummer Bedeutung
Pin 0 (links) Switch 1 (Bit 7)
Pin 1 Switch 2 (Bit 6)
Pin 2 Switch 3 (Bit 5)
Pin 3 Switch 4 (Bit 4)
Pin 4 Switch 5 (Bit 3)
Pin 5 Switch 6 (Bit 2)
Pin 6 Switch 7 (Bit 1)
Pin 7 Switch 8 (Bit 0)
Pin 8 Taste
Pin 9 VCC
Pin 10 (rechts) GND

Ansteuerung

Leider sind real existierende Schalter und Taster aufgrund ihrer Bauform nicht frei von Prellen. In der Wikipedia wird Prellen als "mechanisch ausgelöster Störeffekt bei elektromechanischen Schaltern und Tastern bezeichnet: Statt des sofortigen elektrischen Kontakts ruft die Betätigung des Schalters kurzzeitig ein mehrfaches Schließen und Öffnen des Kontakts hervor."

Exemplarisch zeigt das folgende Bild das Prellen des verwendeten Tasters:

Unter dem Oszilloskop

Bilder, die die Situation noch besser verdeutlichen, finden sich im oben verlinkten Wikipedia-Artikel.

Das Entprellen des Tasters habe ich nicht selbst implementiert sondern eine Implementierung von eewiki.net verwendet. Die Theorie ist, dass geprüft wird, ob der zu entprellende Eingang über einen definierten Zeitraum konstant bleibt. In dieser Implementierung wird über einen 19 bit Zähler ein Zeitraum von 10.5 ms bei 50 MHz verwendet. Somit wird erst nach 10.5 ms der Wert des Eingangs weiter gegeben.

Nachdem der Taster zum Einlesen der Werte nun entprellt wurde, ist der VHDL Code nur noch wenige Zeilen lang:

library IEEE;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity byte_input is
  PORT(
    clk:      in std_logic;
    switches: in std_logic_vector(7 downto 0);
    button:   in std_logic;
    data:     out std_logic_vector(7 downto 0);
    act:      out std_logic
  );
end byte_input;

architecture sim of byte_input is
  signal s_button: std_logic;
begin
  act < = s_button;

  debouncer: entity work.debounce
    port map (
      clk => clk,
      button => not button,
      result => s_button
    );

  process(clk)
  begin
    if rising_edge(clk) and s_button = '1' then
      data < = switches;
    end if;
  end process;
end sim;

Es wird zu jedem Clock-Cycle überprüft, ob die Taste gedrückt wurde und wenn ja, der Eingang der Schalter als std_logic_vector(7 downto 0) ausgegeben.

Im GIT findest sich ein kleines Demo-Repository, welches die eingetasteten Werte auf den 2 Siebensegmentanzeigen ausgibt.