📄 keyborad.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 + -