4×4矩阵键盘控制实验
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
4×4矩阵键盘控制实验
一、实验内容摘要
设计一个4×4键盘接口控制器,在QuartusII软件上实现基设计,将其与开发板连接,实现电路功能。
当按下某一键时,4位LED上显示对应的键值,以二进制代码形式从0至F显示。
二、实验源代码
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.ALL;
ENTITY DEBOUNCING IS
PORT(
clk, key:IN STD_LOGIC ;
clr: IN STD_LOGIC;
dly_out, dif_out: OUT STD_LOGIC);
END DEBOUNCING;
ARCHITECTURE a OF DEBOUNCING IS
SIGNAL sample,dly,diff: STD_LOGIC;
BEGIN
free_counter:block
signal QQ:std_logic_vector(4 downto 0);
signal d0:std_logic;
begin
process (CLR,clk)
begin
if clr='0' then
d0<='0';
QQ<=(OTHERS=>'0');
ELSif clk'event and clk='1' then
d0<=QQ(4); --QQ的最高位同时作为d0信号,即d0的周期为2的5次方个clk.
QQ<=QQ+1;
end if;
end process;
sample<=not(QQ(4) and (not d0));--当d0为0,QQ(4)为1时,sample产生采样脉冲,低电平时间为1个clk
end block free_counter;
debunce:block
signal d0,d1,s,r:std_logic;
begin
process(clk,clr)
begin
if clr='0' then
dly<='0';
elsif rising_edge(clk) then
if sample='1' then
d1<=d0;
d0<=key;
s<=d0 and d1;
r<=not d0 and not d1;
if s<='0' and r<='0' then
dly<=dly;
elsif s<='0' and r<='1' then
dly<='0';
elsif s<='1' and r<='0' then
dly<='1';
else
dly<='0';
end if;
end if;
end if;
end process;
dly_out<=dly;
end block debunce;
differential:block
signal d1,d0:std_logic;
begin
process(clk,clr)
begin
if clr='0' then
d0<='0';
d1<='0';
elsif rising_edge(clk) then
d1<=d0;
d0<=dly;
end if;
diff<=d0 and not d1;
end process;
dif_out<=diff;
end block differential;
END a;
--****************************************************************** --* 4x4标准键盘板读取并点亮实验箱底板上的L1-L4
--* Filename: keyboard4_4
--* 扫描键盘,译码并点亮实验箱底板上的L1-L4
--* 已加入去抖程序
--****************************************************************** library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity keyboard4_4 is
port(
rst : in std_logic;
clk_in : in std_logic;
keyin : in std_logic_vector(3 downto 0);
scan : out std_logic_vector(3 downto 0);
leds : out std_logic_vector(3 downto 0);
state : out std_logic;
M : out std_logic_vector(3 downto 0)
);
end keyboard4_4;
architecture keyboard4_4_arch of keyboard4_4 is
--
--********************************************* component debouncing
port( key : IN STD_LOGIC ;
clk,clr : IN STD_LOGIC ;
dly_out : OUT STD_LOGIC ) ;
end component ;
--*********************************************
--
signal clkfrq : std_logic;
signal cntscn : std_logic_vector(1 downto 0);
signal scnlin : std_logic_vector(3 downto 0);
signal cntfrq : std_logic_vector(14 downto 0);
signal lednum : std_logic_vector(7 downto 0);
signal key_tmp : std_logic_vector(3 downto 0);
signal clk : std_logic;
signal cntfrq1 : std_logic_vector(5 downto 0); begin
M <= "0101"; --键盘功能选择
scan <= not scnlin;
lednum <= scnlin & (not key_tmp);
-- key_tmp <= keyin;
--debounuing ckt
debounuing : block
begin
U1: debouncing PORT MAP (
KEY => keyin(0) ,
DLY_OUT => key_tmp(0) ,
clr=>rst,
clk => CLK
);
U2: debouncing PORT MAP (
KEY => keyin(1) ,
dly_out => key_tmp(1) ,
clr=>rst,
clk => CLK
);
U3: debouncing PORT MAP (
key => keyin(2) ,
dly_out => key_tmp(2) ,
clr=>rst,
clk => CLK
);
U4: debouncing PORT MAP (
key => keyin(3) ,
dly_out => key_tmp(3) ,
clr=>rst,
clk => CLK
);
END block debounuing ;
--******************************************************
--
process(rst,clk_in) -- 晶振为40MHz,进行40000分频产生去抖时钟(1000Hz)
begin
if rst = '0' then
cntfrq <= (others => '0');
elsif rising_edge(clk_in) then
if (cntfrq = "100111000011111" or not (key_tmp="1110" or key_tmp="1101" or key_tmp="1011" or key_tmp="0111") ) then
--if (cntfrq = "100111000011111" or key_tmp="1111" ) then
--if cntfrq = "1111" then
cntfrq <= (others => '0');
clk <= not clk;--去抖时钟
else
cntfrq <= cntfrq + 1;
end if;
end if;
end process;
process(rst,clk) --去抖时钟,50分频,形成扫描时钟
begin
if rst = '0' then
clkfrq <= '0';
cntfrq1 <= (others => '0');
elsif rising_edge(clk) then
if cntfrq1 = "11000" then
cntfrq1 <= (others => '0');
clkfrq <= not clkfrq;
else
cntfrq1 <= cntfrq1 + 1;
end if;
end if;
end process;
process(rst,clkfrq) -- 根据扫描时钟产生扫描线
begin
if rst = '0' then
cntscn <= "00";
elsif rising_edge(clkfrq) then
if cntscn = "11" then
cntscn <= "00";
else
cntscn <= cntscn+1;
end if;
case cntscn is
when "00" => scnlin <= "0001";
when "01" => scnlin <= "0010";
when "10" => scnlin <= "0100";
when "11" => scnlin <= "1000";
when others => null;
end case;
end if;
end process;
process(rst, clkfrq) -- 根据按键点亮相应的leds
begin
if(rst = '0' ) then
leds <= "0000";
elsif clkfrq'event and clkfrq = '0' then
case lednum is
when "10001000" =>
leds <= "0001"; --1
when "01001000" =>
leds <= "0010"; --2
when "00101000" =>
leds <= "0011"; --3
when "00011000" =>
leds <= "1010"; --A
when "10000100" =>
leds <= "0100"; --4
when "01000100" =>
leds <= "0101"; --5
when "00100100" =>
leds <= "0110"; --6
when "00010100" =>
leds <= "1011"; --B
when "10000010" =>
leds <= "0111"; --7
when "01000010" =>
leds <= "1000"; --8
when "00100010" =>
leds <= "1001"; --9
when "00010010" =>
leds <= "1100"; --C
when "10000001" =>
leds <= "1110"; --*
when "01000001" =>
leds <= "0000"; --0
when "00100001" =>
leds <= "1111"; --#
when "00010001" =>
leds <= "1101"; --D
when others =>
null;
end case;
end if;
end process;
process(rst,key_tmp)
begin
if(rst = '0' ) then
state <= '1';
elsif (key_tmp="1110" or key_tmp="1101" or key_tmp="1011" or key_tmp="0111") then
state <= '0';
elsif (key_tmp="1111") then
state <= '1';
end if;
end process;
end keyboard4_4_arch;
三、实验工具软件的选用以及实验过程
1、打开QuartusII软件。
2、选择File/New,选择Design File/VHDL File。
3、输入4×4矩阵键盘控制的代码。
4、选择File/Save,保存文件名为DEBOUNCING.vhd。
在弹出的窗口Do you want to creat
a new project with this file?选择“是”。
5、在弹出的New Projec Wizard:中,选择Next>;Directory,Name,Top-Level Entity 选择Next>;Add Files选择Next>;○4Family&Device Setting中,Family选择Cyclone IV,Packge选择FBGA,Pin Count选择256,Speed grade选择8,Available device选择
EP3C25F256C8,在点击Next>;○5EDA Tool Settings选择Next>;○6最后在Summary中选择Finish。
6、点击Assignments,选择Remove Assignments,全选后取消All和Device Assigments。
7、预编译,选择Process/Start/Start Analysis&Synthesis,进行综合。
8、选择File/New,选择Design File/VHDL File。
9、输入4×4矩阵键盘控制的消抖代码。
10、点击Project,选择Set as Top-Level Entity,设置成顶层模块。
11、点击Assignments,选择Remove Assignments,全选后取消All和Device Assigments。
12、进行引脚锁定
13、预编译,选择Process/Start/Start Analysis&Synthesis,进行综合。
14、选择Programmer,选择Hardware Setup,选择USB接口,选择好后关闭返回上级点击开始。
四、实验结果
当按下键盘上1时,状态指示灯灭,四位LED灯以二进制代码形式1点亮,当按下键盘上2时,状态指示灯灭,四位LED灯以二进制代码形式2点亮,依次按下键盘上按键,分别从0到F显示。
当按下0时,四位LED灯全灭,只有状态指示灯亮。
当按下其他数字时四位LED灯会以相应的二进制代码形式点亮。
如下例的一些图:
五、实验分析及总结。