⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 keyborad.vhd

📁 一个8X8的矩阵键盘的VHDL文件,并且有长安键和短按键之分,即一共能做到128个键值,扫描用的时钟用1ms的就行了
💻 VHD
字号:
library ieee;
use ieee.std_logic_1164.all;

entity keyboard is
   port(
        scan_out:buffer std_logic_vector(7 downto 0);--8位扫描输出线
        scan_in :in  std_logic_vector(7 downto 0);--8位扫描输入线
        key_data:out std_logic_vector(7 downto 0);--8位键盘值输出数据线
        cs      :in  std_logic;--读数时的选择线
        clk     :in  std_logic;--扫描时钟输入线
        key_init:buffer std_logic --有键值时的中断信号线
       );

end keyboard;

--****************************************

architecture keyboard of keyboard is
   signal clk_cnt :integer range 0 to 7; --记录8位时钟周期,以便扫描时输出信号
   signal scl_cnt :integer range 0 to 2500; --记录有键按的周期数,10ms的时钟,5秒的个数
   signal key_buff:std_logic_vector(7 downto 0); --键值

   signal out_db,out_dt,in_dt:std_logic_vector(3 downto 0);
   signal lock_dt,scan_do :boolean;

   signal code:integer range 0 to 2;--0 no key;1 shout key;2 long key 
begin
    
   --**************************************************
   process(clk)    --键盘扫描信号送出部份

   begin
      
      if clk'event and clk='1' then
        if scan_do=true then
      -- then the up'event and along scan ,can scan
           case clk_cnt is 
           when 0 =>
               clk_cnt<=clk_cnt+1;
               scan_out<="11111110";       
           when 1 =>
               clk_cnt<=clk_cnt+1;
               scan_out<="11111101";
           when 2 =>
               clk_cnt<=clk_cnt+1;
               scan_out<="11111011";
           when 3 =>
               clk_cnt<=clk_cnt+1;
               scan_out<="11110111";
           when 4 =>
               clk_cnt<=clk_cnt+1;
               scan_out<="11101111";
           when 5 =>
               clk_cnt<=clk_cnt+1;
               scan_out<="11011111";
           when 6 =>
               clk_cnt<=clk_cnt+1;
               scan_out<="10111111";
           when 7 =>
               clk_cnt<=0;
               scan_out<="01111111";
           when others =>
               clk_cnt<=0;
           end case; 
        end if;
     ------------------------------------------------- 
      end if; 
   end process;
--**************************************************
  process(scan_in,clk)--对扫描输入信号进行编码
  begin
    if   clk'event and clk='0' then --use down'event
     if scan_in/="11111111"then 
        scan_do<=false;
        if lock_dt=true then  --允许锁存数据    

           out_dt<=out_db;           
           case scan_in is  --对输入线编码
           when "11111110" =>
                in_dt<="0000";
           when "11111101" =>
                in_dt<="0001";
           when "11111011" =>
                in_dt<="0010";
           when "11110111" =>
                in_dt<="0011";
           when "11101111" =>
                in_dt<="0100";
           when "11011111" =>
                in_dt<="0101";
           when "10111111" =>
                in_dt<="0110";
           when "01111111" =>
                in_dt<="0111";
           when others =>
                null; 
           end case;                    
           lock_dt<=false;

        end if;
------------------------------------------------------------
        if scl_cnt<2500 then
           scl_cnt<=scl_cnt+1; 
           if scl_cnt=40 then
              lock_dt<=true;
           end if;
        end if;

        if scl_cnt=2500 then --长按键时间到,发中断信号
           if key_init='1' then -- then the "init" not outpu
              code<=2;  
              key_init<='0'; --给中断信号
           end if;
        end if;

------------------------------------------------------------
     else -- no any key by down ,all line is high       
-------------------------------------------------------------
        if scl_cnt>=40 and scl_cnt<2500 then        
           key_init<='0';  --还有8颗键没法设,80---88                   
           scl_cnt<=0;
           code<=1;            

        elsif scl_cnt=2500 then           
           scl_cnt<=0;
           key_init<='1'; 
           code<=0;

        elsif scl_cnt<40 and scl_cnt>0 then
           scl_cnt<=0;

        else
           key_init<='1';

        end if;
        scan_do<=true;
------------------------------------------------------------
     end if;
    end if;  
   end process;
--****************************************************
   process(scan_out)
   begin
      case scan_out is  -- 对输出线编码
       
      when "11111110" =>
           out_db<="0001";
      when "11111101" =>
           out_db<="0010";
      when "11111011" =>
           out_db<="0011";
      when "11110111" =>
           out_db<="0100";
      when "11101111" =>
           out_db<="0101";
      when "11011111" =>
           out_db<="0110";
      when "10111111" =>
           out_db<="0111";
      when "01111111" =>
           out_db<="1000";
      when others =>
           null;
      end case;

   end process;

--**********************************************
   process(code)--对键值进行编码并输出到缓冲器里
   begin
     if code/=0 then
   
         key_buff(3 downto 0)<=out_dt;
         key_buff(7 downto 4)<=in_dt;
         
         if code=2 then
            key_buff(7)<='1';             
         end if;

     end if;
   end process;

--***********************************************
   process(cs)
   begin
        if cs='1' then
           key_data<= NOT key_buff;
        else
           key_data<="00000000";
        end if;
   end process; 
--*************************************************

end keyboard;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -