Jste zde

Hrátky s hradlovými poli - 4.

Minulé dva díly ukazovaly řízení sedmi segmentového displeje. Samozřejmě je však také potřeba zajistit vstup dat. K tomu slouží klávesnice. V nejjednodušším případě se jedná o maticovou klávesnici a její připojení bude dále ukázáno. Současně využiji tento díl k odpovědi těm, kteří se na mě obrátili s dotazem, co z předváděného zvládli studenti

Maticová klávesnice

     Princip maticové klávesnice je používán i u velkých klávesnic. V tomto případě se jedná o malou klávesnici 4 x 4. Jak ukazuje obrázek, je klávesnice tvořena 16 tlačítky uspořádanými do čtyř řad a čtyř sloupců.

Ke zjištění, které tlačítko bylo stisknuto, je využito tzv. skenování klávesnice. V principu jde o to, že na jeden ze sloupců nebo z řádků přivedeme opačnou logickou úroveň než na zbývající. Stisknutím konkrétního tlačítka se tento signál přenese na odpovídající řádek nebo sloupec. Výše uvedené nám dává čtyři možnosti. V dalším řešení byla použita kombinace vstup klávesnice sloupce, výstup řádky a aktivní signál log 1. Nejlépe to osvětlí příklad. Klidová úroveň na sloupcích je log 0. Postupně na jednotlivé sloupce v nekonečné smyčce přivádíme log 1. Pokud např. stiskneme klávesu „8“ na výstupu se nic neděje, dokud nepřivedeme skenovací úroveň na sloupec 2. Log 1 se nám pak přes sepnutý kontakt dostane na řádek 3. V tomto konkrétním případě máme vstup 0100 a na výstupu přečteme 0010. Právě tato kombinace je jedinečná pro klávesu „8“. Každé jiné klávese opět odpovídá jedinečná kombinace, kterou pak stačí dekódovat.

Programové řešení

     Celý program byl rozdělen na dva bloky a ty pak byly propojeny ve formě blokového schématu. Jeden blok, nazývá se Pololetka, byl předmětem zadání pololetní práce a představuje dekodér klávesnice. Vše ostatní je soustředěno do bloku MatrixKey. Obvod této složitosti studenti zvládnou v závěru druhého ročníku.

     Celý obvod zajišťuje skenování, dekódování skenkódu a zobrazení stisknuté klávesnice na sedmi segmentovém displeji.. Na vstup clk je připojen oscilátor 50 MHz. Porty radky a sloupce slouží k připojení klávesnice Na výstupy pak je připojen displej.

Pololetka

Tento blok provádí vlastní dekódování. Kromě výstupu vlastního čtyřbitového čísla poskytuje informaci, že je nějaké tlačítko stisknuto. Tato část programu je v souboru Pololetka.vhd. Autor Ladislav Hojgr, třída E2.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity Pololetka is
    Port ( radky,sloupce : in  STD_LOGIC_VECTOR (3 downto 0);
           vystup : out  STD_LOGIC_VECTOR (3 downto 0);
           platnost : out  STD_LOGIC);
end Pololetka;

architecture Behavioral of Pololetka is
signal input: STD_LOGIC_VECTOR (7 downto 0);
begin
input <= radky & sloupce;
process (input)
begin
        case input is
            when "00010001" => vystup <= "0001";  platnost <= "1";
            when "00010010" => vystup <= "0010";  platnost <= "1";
            when "00010100" => vystup <= "0011";  platnost <= "1";
            when "00011000" => vystup <= "1100";  platnost <= "1";
            when "00100001" => vystup <= "0100";  platnost <= "1";
            when "00100010" => vystup <= "0101";  platnost <= "1";
            when "00100100" => vystup <= "0110";  platnost <= "1";
            when "00101000" => vystup <= "1101";  platnost <= "1";
            when "01000001" => vystup <= "0111";  platnost <= "1";
            when "01000010" => vystup <= "1000";  platnost <= "1"; 
            when "01000100" => vystup <= "1001";  platnost <= "1";
            when "01001000" => vystup <= "1110";  platnost <= "1";
            when "10000001" => vystup <= "1010";  platnost <= "1";
            when "10000010" => vystup <= "0000";  platnost <= "1";
            when "10000100" => vystup <= "1011";  platnost <= "1";
            when "10001000" => vystup <= "1111";  platnost <= "1";
            when others => vystup <= "0000"; platnost <= "0";
        end case;  
end process;

MatrixKey

V tomto bloku je soustředěno vše ostatní, rozdělené na několik procesů. První proces vytváří skenovaní frekvenci 1 kHz. Druhý proces je dvoubitový čítač a počítá řádky. Z jeho stavu je hned následujícím procesem dekódován stav jeden ze čtyř, tedy vybrán jeden řádek. Poslední proces dekóduje platný binární údaj na sedmi segmentový kód k ovládání displeje. Na které pozici displeje se příslušný znak zobrazí je zde nastaveno pevně. Příslušný soubor MatrixKey.vhd najdete v downloadu.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity MatrixKey is
    Port ( clk, valid : in  STD_LOGIC;
           bin : in  STD_LOGIC_VECTOR (3 downto 0);
           SegOut : out  STD_LOGIC_VECTOR (7 downto 0);
           column, position : out  STD_LOGIC_VECTOR (3 downto 0));
end MatrixKey;

architecture Behavioral of MatrixKey is

signal timer: std_logic_vector(15 downto 0) := "0000000000000000";
signal TimeOut: std_logic;
signal dp: std_logic := "1";
signal count : STD_LOGIC_VECTOR (1 downto 0):="00";
signal inp: STD_LOGIC_VECTOR (4 downto 0);

begin
position <= "1110"; --výstup na nejnižší pozici displeje
inp <= valid & bin;

process (clk) begin -- časovač 1 kHz
   if clk"event and clk = "1" then
     timer <= timer + 1 ;
       if timer = "1100001101010000" then
         TimeOut <= "1" ;
         timer <= (others => "0") ;
       else
         TimeOut <= "0" ;
       end if ;
   end if ;
end process ;

process (clk)  -- čítač řádků
begin
   if clk="1" and clk"event then
      if TimeOut = "1" then
         count <= count + 1;
      end if;
   end if;
end process;

process(clk) -- výstup řádků 
begin
   if ( clk"event and clk ="1") then 
      case count is
         when "00" => column <= "0001" ;
         when "01" => column <= "0010";
         when "10" => column <= "0100";
         when "11" => column <= "1000";
         when others => column <= "0000" ;
      end case;
   end if;
end process;

process(clk) --dekodér BIN -> sedm segmentů
begin
   if ( clk"event and clk ="1") then
      case inp is
         when "10000" => SegOut <= "0000001" & dp;
         when "10001" => SegOut <= "1001111" & dp;
         when "10010" => SegOut <= "0010010" & dp;
         when "10011" => SegOut <= "0000110" & dp;
         when "10100" => SegOut <= "1001100" & dp;
         when "10101" => SegOut <= "0100100" & dp;
         when "10110" => SegOut <= "0100000" & dp;
         when "10111" => SegOut <= "1110000" & dp;
         when "11000" => SegOut <= "0000000" & dp;
         when "11001" => SegOut <= "0001100" & dp;
         when "11010" => SegOut <= "0001000" & dp;
         when "11011" => SegOut <= "1100000" & dp;
         when "11100" => SegOut <= "0110001" & dp;
         when "11101" => SegOut <= "1000010" & dp;
         when "11110" => SegOut <= "0110000" & dp;
         when "11111" => SegOut <= "0111000" & dp;
         when others => SegOut <= "1111111" & dp;
      end case;
   end if;
end process;
 
end Behavioral;

Závěr

     Simulace souboru Pololetka.vhd pomohla řadě studentů pochopit princip skenování. Pokud budete program fyzicky realizovat, je třeba připomenout, že je nutné na vstupu řádky zajistit klidovou logickou úroveň. V tomto případě to musí být log 0. Prakticky je to realizováno pomocí pulldown odporů, které jsou součástí hradlového pole. Pokud se podíváte do ucf souboru (je součástí downloadu), příslušnou volbu tam najdete.

V tomto souboru pak také najdete, na které piny konektoru jsou vyvedeny porty pro připojení klávesnice.

Jiří Král
jiri.kral@roznovskastredni.cz

Downloads&Odkazy

Hodnocení článku: