4x4键盘实验报告
- 格式:doc
- 大小:76.00 KB
- 文档页数:14
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 ISPORT(clk, key:IN STD_LOGIC ;clr: IN STD_LOGIC;dly_out, dif_out: OUT STD_LOGIC);END DEBOUNCING;ARCHITECTURE a OF DEBOUNCING ISSIGNAL sample,dly,diff: STD_LOGIC;BEGINfree_counter:blocksignal QQ:std_logic_vector(4 downto 0);signal d0:std_logic;beginprocess (CLR,clk)beginif clr='0' thend0<='0';QQ<=(OTHERS=>'0');ELSif clk'event and clk='1' thend0<=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个clkend block free_counter;debunce:blocksignal d0,d1,s,r:std_logic;beginprocess(clk,clr)beginif clr='0' thendly<='0';elsif rising_edge(clk) thenif sample='1' thend1<=d0;d0<=key;s<=d0 and d1;r<=not d0 and not d1;if s<='0' and r<='0' thendly<=dly;elsif s<='0' and r<='1' thendly<='0';elsif s<='1' and r<='0' thendly<='1';elsedly<='0';end if;end if;end if;end process;dly_out<=dly;end block debunce;differential:blocksignal d1,d0:std_logic;beginprocess(clk,clr)beginif clr='0' thend0<='0';d1<='0';elsif rising_edge(clk) thend1<=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 isport(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 debouncingport( 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); beginM <= "0101"; --键盘功能选择scan <= not scnlin;lednum <= scnlin & (not key_tmp);-- key_tmp <= keyin;--debounuing cktdebounuing : blockbeginU1: 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)beginif rst = '0' thencntfrq <= (others => '0');elsif rising_edge(clk_in) thenif (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" thencntfrq <= (others => '0');clk <= not clk;--去抖时钟elsecntfrq <= cntfrq + 1;end if;end if;end process;process(rst,clk) --去抖时钟,50分频,形成扫描时钟beginif rst = '0' thenclkfrq <= '0';cntfrq1 <= (others => '0');elsif rising_edge(clk) thenif cntfrq1 = "11000" thencntfrq1 <= (others => '0');clkfrq <= not clkfrq;elsecntfrq1 <= cntfrq1 + 1;end if;end if;end process;process(rst,clkfrq) -- 根据扫描时钟产生扫描线beginif rst = '0' thencntscn <= "00";elsif rising_edge(clkfrq) thenif cntscn = "11" thencntscn <= "00";elsecntscn <= cntscn+1;end if;case cntscn iswhen "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) -- 根据按键点亮相应的ledsbeginif(rst = '0' ) thenleds <= "0000";elsif clkfrq'event and clkfrq = '0' thencase lednum iswhen "10001000" =>leds <= "0001"; --1when "01001000" =>leds <= "0010"; --2when "00101000" =>leds <= "0011"; --3when "00011000" =>leds <= "1010"; --Awhen "10000100" =>leds <= "0100"; --4when "01000100" =>leds <= "0101"; --5when "00100100" =>leds <= "0110"; --6when "00010100" =>leds <= "1011"; --Bwhen "10000010" =>leds <= "0111"; --7when "01000010" =>leds <= "1000"; --8when "00100010" =>leds <= "1001"; --9when "00010010" =>leds <= "1100"; --Cwhen "10000001" =>leds <= "1110"; --*when "01000001" =>leds <= "0000"; --0when "00100001" =>leds <= "1111"; --#when "00010001" =>leds <= "1101"; --Dwhen others =>null;end case;end if;end process;process(rst,key_tmp)beginif(rst = '0' ) thenstate <= '1';elsif (key_tmp="1110" or key_tmp="1101" or key_tmp="1011" or key_tmp="0111") thenstate <= '0';elsif (key_tmp="1111") thenstate <= '1';end if;end process;end keyboard4_4_arch;三、实验工具软件的选用以及实验过程1、打开QuartusII软件。
4x4矩阵键盘设计报告1.引言1.1 概述概述:4x4矩阵键盘是一种常用的输入设备,广泛应用于各种电子产品中。
本报告旨在介绍4x4矩阵键盘的设计理念、技术实现以及使用体验,并对其设计优势进行分析。
同时,将收集用户反馈,展望未来对4x4矩阵键盘的发展趋势进行探讨。
通过本报告的阐述,读者可以更加全面地了解4x4矩阵键盘的设计与应用,为相关产品的设计与开发提供参考和借鉴。
1.2 文章结构本报告将分为引言、正文和结论三个部分。
引言部分将概述本设计报告的目的和重要性,介绍文章结构和各部分内容的主要内容。
正文部分将详细介绍设计理念、技术实现和使用体验,通过分析和阐述设计的过程和特点,展现4x4矩阵键盘设计的全面性和独特性。
结论部分将对设计的优势进行总结,考虑用户反馈和展望未来的发展方向,以期为4x4矩阵键盘的设计提供参考和启示。
文章1.3 目的:本报告的目的是介绍我们设计的4x4矩阵键盘,并分析其设计理念、技术实现和使用体验。
通过本报告,读者可以了解我们的设计思路和创新之处,以及用户在使用过程中的反馈和建议。
同时,我们还会对该键盘的设计优势进行评估,并展望未来可能的发展方向。
通过本报告的阐述,我们希望能够为相关领域的学习和研究提供有益的参考和启发。
2.正文2.1 设计理念设计理念部分的内容:在设计4x4矩阵键盘时,我们以用户体验和便捷性为设计理念的核心。
我们希望设计一款符合人体工程学的键盘,使用户在使用过程中能够感受到舒适和便捷。
同时,我们也注重键盘的美学设计,希望能够设计出外观时尚,符合当代审美的产品。
此外,我们也考虑了键盘的功能多样性,希望能够满足不同用户的需求,提供更好的用户体验。
因此,在设计理念上,我们以用户体验和功能多样性为重点,致力于设计出一款符合人体工程学、外观时尚、功能多样的4x4矩阵键盘。
2.2 技术实现在本节中,我们将讨论4x4矩阵键盘的技术实现。
我们首先考虑到了键盘的布局和排列,通过设计合理的矩阵布局,我们可以实现较小尺寸的键盘同时保证较高的按键准确性。
键盘阵列扫描输入一、实验目的1. 进一步学习并掌握Quartus II设计的方法及步骤;2. 熟悉VHDL语言电路设计方法;3. 熟悉EACF型FPGA开发板,参见6.1节;4. 学习并掌握利用VHDL描述并设计电路的方法及步骤;5. 学习并掌握键盘阵列的扫描输入的方法及实现过程。
二、实验原理键盘阵列是一个由4×4的按键开关组成的阵列,可实现16种状态的输入。
4×4按键阵列的硬件连接原理如下图所示。
4X4键盘阵列其中VCC3.3为3.3V的正电源;BUTTON为4×4共16个按键,R为电阻。
而K_H_1、K_H_2、K_H_3、K_H_4为4×4按键阵列连接到FPGA通用IO引脚的行信号;K_V_1、K_V_2、K_V_3、K_V_4为4×4按键阵列连接到FPGA通用IO引脚的列信号,如下图所示。
键盘阵列与FPGA的连接另外,连接到FPGA的行列信号圴为3.3V的LVTTL电平标准:即电压小于0.8V为低电平,高于2.0V为高电平。
通过上述4×4按键阵列的硬件连接原理图可看出,行和列信号都通过10K的电阻上拉到3.3V的电源,也就是说如果FPGA通过对应的IO引脚来读取4×4按键阵列的行和列信号,得到的全部为高电平“1”,即使按键按下时,读到的依然是高电平“1”。
那么如何在FPGA中判断4×4按键阵列中的哪个键按下呢?当然我们要实现按键输入的功能,就不能全部读取行和列的信号。
而应通过不断地输出扫描行(或列),再通过读取列(或行)的信号来判断哪个按键按下。
即:通过对4×4键盘阵列的4个行(或列)控制信号循环输出”1110、1101、1011、0111”,来驱动键盘阵列,紧接着读取相应的4个列(或行)信号。
通过读取的数据或状态来判断16个按键中哪个键被按下,并对其状态做编码输出。
此电路不停的工作,以便实时准确地获取键盘的输入状态,以供其它电路使用,从而实现了键盘阵列的扫描输入。
单片机矩阵键盘实验实验报告一、实验目的本次实验的目的是掌握原理和方法,利用单片机识别矩阵键盘并编程实现键码转换功能,控制LED点亮显示。
二、实验原理矩阵键盘是一种由多路单向控制器输入行选择信号与列选择信号连接而形成的一一对应矩阵排列结构。
它广泛应用于电子游戏机、办公自动化设备、医疗仪器、家电控制及书籍检索机器等方面。
本次实验采用的矩阵键盘是一个4 x 4矩阵,用4段数码管显示按键编码,每个按键都可以输入一个代码,矩阵键盘连接单片机,实现一个软件算法来识别键码转化。
从而将键盘中的按键的按下信号转换成程序能够识别的代码,置于相应的输出结果中,控制LED点亮,从而可以实现矩阵键盘按键的转换功能。
三、实验方法1.硬件搭建:矩阵键盘(4行4列)与单片机(Atmel AT89C51)相连,选择引脚连接,并将数码管和LED与单片机相连以实现显示和点亮的功能。
2.程序设计:先建立控制体系,利用中断服务子程序识别和码值转换,利用中断服务子程序实现从按键的按下信号转换为程序能够识别的代码,然后将该代码段编写到单片机程序中,每次按下矩阵键盘按键后单片机给出相应的按键编码输出,用数码管显示,控制LED点亮。
四、实验结果经过实验,成功实现了矩阵键盘与单片机之间的连接,编写了中断服务子程序,完成了按键编码输出与LED点亮的功能。
实验完成后,数码管显示各种按键的编码,同时LED会点亮。
本次实验介绍了矩阵键盘的原理,论述了键码转换的程序设计步骤,并实验完成矩阵键盘与单片机的连接,实现用LED点亮以及数码管显示按键的编码。
通过本次实验,受益匪浅,使我对使用单片机编写算法与程序有了更深入的认识,同时丰富了课堂学习的内容,也使我更加热爱自己所学的专业。
自主学习用实验矩阵键盘识别实验
一、实验目的
1、掌握 4×4 矩阵键盘的工作原理和键盘的扫描方式。
2、掌握键盘的去抖方法和键盘应用程序的设计。
二、实验设备
1、PC 机一台;
2、开放式模块化单片机教学实验箱一台;
3、USB 下载线一根。
三、实验内容
自行编制程序,用 51 单片机实现 4×4 矩阵键盘扫描,采用线反转法;并实现当S11按下时在数码管上显值“0”,当S12按下时在数码管上显值“1”……,即依次将 S11 至S26按下,在数码管上依次显示十六进制数“0-F”,矩阵键盘原理图如图1-1 所示。
单片机与数码管接口电路原理图如图 1-2 所示。
图 1-1 矩阵键盘接口电路
图 1-2 数码管接口电路原理图
四、思考题
1.画出所编程序的流程图;
2.若要实现2×4 矩阵键盘,软硬件作如何修改。
答:将行线P2^3, P2^4接线去掉。
程序对应部分P2=0xfd; P2=0xfe;删掉。
3.实验中有何故障、问题出现,是否得到解决?如何解决的?问题:显示值对应出错。
原来是共阳段码和共阴段码弄相反了。
矩阵键盘实验报告佘成刚学号2010302001班级08041202时间2016.01.20一、实验目的1.学习矩列式键盘工作原理;2.学习矩列式接口的程序设计。
二、实验设备普中HC6800ESV20开发板三、实验要求要现:用4*4矩阵键盘,用按键形式输入学号,在数码管上显示对应学号。
四、实验原理工作原理:矩阵式由行线和列线组成,按键位于行、列的交叉点上。
如图所示,一个4*4 的行、列结构可以构成一个由16 个按键的键盘。
很明显,在按键数量较多的场合,矩阵式键盘与独立式键盘相比,要节省很多的I/0 口。
(1)矩阵式键盘工作原理按键设置在行、列交节点上,行、列分别连接到按键开关的两端。
行线通过下拉电阻接到GND 上。
平时无按键动作时,行线处于低电平状态,而当有按键按下时,行线电平状态将由与此行线相连的列线电平决定。
列线电平如果为低,行线电平为高,列线电平如果为高,则行线电平则为低。
这一点是识别矩阵式键盘是否被按下的关键所在。
因此,各按键彼此将相互发生影响,所以必须将行、列线信号配合起来并作适当的处理,才能确定闭合键的位置。
(2)按键识别方法下面以3 号键被按下为例,来说明此键是如何被识别出来的。
前已述及,键被按下时,与此键相连的行线电平将由与此键相连的列线电平决定,而行线电平在无键按下时处于高电平状态。
如果让所有列线处于高电平那么键按下与否不会引起行线电平的状态变化,始终是高电平,所以,让所有列线处于高电平是没法识别出按键的。
现在反过来,让所有列线处于低电平,很明显,按下的键所在行电平将也被置为低电平,根据此变化,便能判定该行一定有键被按下。
但我们还不能确定是这一行的哪个键被按下。
所以,为了进一步判定到底是哪—列的键被按下,可在某一时刻只让一条列线处于低电平,而其余所有列线处于高电平。
当第1 列为低电平,其余各列为高电平时,因为是键3 被按下,所以第1 行仍处于高电平状态;当第2 列为低电平,其余各列为高电平时,同样我们会发现第1 行仍处于高电平状态,直到让第4 列为低电平,其余各列为高电平时,因为是3 号键被按下,所以第1 行的高电平转换到第4 列所处的低电平,据此,我们确信第1 行第4 列交叉点处的按键即3 号键被按下。
44键盘扫描实验实验目的1、学习HDL程序的基本设计技巧;2、掌握矩阵键盘的扫描原理和使用方法。
Verilog程序:module hex_keypad(Col,Code,show,show1,count,scan,clock,Row); output[3:0] Code,Col,count; //定义列信号Col、行列信号共同决定的输出代码Code、以及计数变量count output[7:0] show,show1; //定义七段显示变量show、show1 input[3:0] Row; //定义输入行信号Rowinput scan; //定义数码管选择信号scaninput clock; //定义时钟信号clockreg[3:0] Col,Code,count; //将输出信号定义为reg型reg[7:0] show,show1;reg[1:0] cn; //定义reg型变量cn,用于计数reg reset,count_up,count_down; //定义变量reset用于计数清零,count_up开始加计数,count_down开始减计数reg[15:0] times1,times2; //定义变量times1、times2用于决定开始计数的时间assign scan=1'b1; //将数码管选择信号赋值为1always@(posedge clock) //产生列信号if(cn==4)cn<=0; elsecn<=cn+1;always@(cn)case(cn)2'b00:Col=4'b1110;2'b01:Col=4'b1101;2'b10:Col=4'b1011;2'b11:Col=4'b0111;endcasealways@(posedge clock) //行列信号共同决定输出代码Code case({Row,Col})8'b1110_1110:Code=4'h0;8'b1110_1101:Code=4'h1;8'b1110_1011:Code=4'h2;8'b1110_0111:Code=4'h3;8'b1101_1110:Code=4'h4;8'b1101_1101:Code=4'h5;8'b1101_1011:Code=4'h6;8'b1101_0111:Code=4'h7;8'b1011_1110:Code=4'h8;8'b1011_1101:Code=4'h9;8'b1011_1011:Code=4'hA;8'b1011_0111:Code=4'hB;8'b0111_1110:Code=4'hC;8'b0111_1101:Code=4'hD;8'b0111_1011:Code=4'hE;8'b0111_0111:Code=4'hF;endcasealways@(posedge clock) //由输出Code决定数码管的显示,七段用十六进制数表示case(Code[3:0])4'h0:show=8'hFC;4'h1:show=8'h60;4'h2:show=8'hDA;4'h3:show=8'hF2;4'h4:show=8'h66;4'h5:show=8'hB6;4'h6:show=8'h3E;4'h7:show=8'hE0;4'h8:show=8'hFE;4'h9:show=8'hE6;4'hA:show=8'hEE;4'hB:show=8'hCE;4'hC:show=8'h9C;4'hD:show=8'h7A;4'hE:show=8'h9E;4'hF:show=8'h8E;endcasealways@(posedge clock) //加减计数case(Code)4'h0:begin reset=1;count_up=0;count_down=0;end //按0键时清零4'hE:begin count_up=1;count_down=0;end //按E键加计数4'hF:begin count_down=1;count_up=0;end //按F键减计数default: begin count_down=0;count_up=0;reset=0; end //按其它键不计数endcasealways@(posedge clock)if(times1==1000) times1<=101; else if (count_up) times1<=times1+1;always@(posedge clock)if(times2==1000) times2<=101; else if (count_down) times2<=times2+1; always@(posedge clock)if(reset)count<=4'h0; elseif (times1>100&&Code==4'hE) //加计数begincount<=count+4'b1;if (count==4'h9) count<=4'h0;endelseif (times2>100&&Code==4'hF) //减计数begincount<=count-4'b1;if (count==4'h0) count<=4'h9;endalways@(posedge clock) //计数显示case(count[3:0])4'h0:show1=8'hFC;4'h1:show1=8'h60;4'h2:show1=8'hDA;4'h3:show1=8'hF2;4'h4:show1=8'h66;4'h5:show1=8'hB6;4'h6:show1=8'h3E;4'h7:show1=8'hE0;4'h8:show1=8'hFE;4'h9:show1=8'hE6;endcaseendmodule仿真波形:Col、Row、Code、show、show[17..10]为十六进制显示,times1、times2、count为十进制显示当Code为F(即按F键)时,show显示8E即F,表明此时按下的是F 键。
实验报告四实验名称:4*4键盘输入1、实验内容键盘扫描,求键值,并在LED上显示该键值。
2、实验目的(1) 掌握键盘和显示器的接口方法和编程方法。
(2) 掌握键盘扫描和LED八段码显示器的工作原理。
3、实验要求在上一个实验的基础上,利用实验仪提供的键盘扫描电路和显示电路,做一个扫描键盘和数码显示实验,把按键输入的键码在六位数码管上显示出来。
实验程序可分为三个模块。
1)键输入模块:扫描键盘、读取一次键盘并将键值存入键值缓冲单元。
2)显示模块:将显示单元的内容在显示器上动态显示。
3)主程序:调用键输入模块和显示模块。
4、实验器材(1) 计算机1台5、实验电路这里只是键盘草图,列为输出,行为输入。
图中电阻为上拉电阻。
(0e103H)图6 8155键盘电路原理图表2 键值表6、实验说明本实验仪提供了一个6×4的小键盘,向列扫描码地址(0e101H)逐列输出低电平,然后从行码地址(0e103H)读回。
如果有键按下,则相应行的值应为低,如果无键按下,由于上拉的作用,行码为高。
这样就可以通过输出的列码和读取的行码来判断按下的是什么键。
在判断有键按下后,要有一定的时延,进行第二读键盘,防止键盘抖动。
7、实验流程图注:LED显示程序框图见上个实验。
图7 键盘扫描主程序流程图图8 读键输入子程序流程图8、实验程序清单;****变量定义文件,文件名:para.lib****OUTBIT equ 0e101h ; 位控制口CLK164 equ OUTBIT+1 ; 段控制口(接164时钟位)DAT164 equ OUTBIT+1 ; 段控制口(接164数据位)IN equ OUTBIT+2 ; 键盘读入口LEDBuf equ 60h ; 显示缓冲; ***变量定义文件结束***;*****************************************************;****显示部分做成单独的文件,文件名为:dis.lib,在键盘扫描部分调用**** LEDMAP: ; 八段管显示码db 3fh, 06h, 5bh, 4fh, 66h, 6dh, 7dh, 07hdb 7fh, 6fh, 77h, 7ch, 39h, 5eh, 79h, 71hdb 00H;******* 延时子程序**************Delay: ; 延时子程序mov r7, #0DelayLoop:djnz r7, DelayLoopdjnz r6, DelayLoopret;*********LED显示***************DisplayLED:mov r0, #LEDBufmov r1, #6 ; 共6个八段管mov r2, #00100000b ; 从左边开始显示Loop: mov dptr, #OUTBITmov a, #0movx @dptr, a ; 关所有八段管mov a, @r0mov B, #8 ; 送164DLP: rlc amov r3, amov acc.0, cmov dptr, #DAT164anl a,#0fdh ;PB1=0,即时钟低电平movx @dptr, amov dptr, #CLK164orl a,#02h ;PB1=1,即产生时钟高电平movx @dptr, aanl a,#0fdh ;PB1=0,时钟低电平movx @dptr, amov a, r3djnz B, DLPmov dptr, #OUTBITmov a, r2movx @dptr, a ; 显示一位八段管mov r6, #1call Delaymov a, r2 ; 显示下一位rr amov r2, ainc r0djnz r1, Loopret;******八段管显示码程序文件dis.lib结束****;***************************************************** ;******键盘扫描程序文件,文件名:key.lib***** TestKey:mov dptr, #OUTBITmov a, #0movx @dptr, a ; 输出线置为0mov dptr, #INmovx a, @dptr ; 读入键状态cpl aanl a, #0fh ; 高四位不用ret;*******键值表**************KeyTable: ; 键码定义db 00h, 01h, 04h, 07hdb 0fh, 02h, 05h, 08hdb 0eh, 03h, 06h, 09hdb 0dh, 0ch, 0bh, 0ahdb 10H,11H,12H,13Hdb 14H,15H,16H,17H;********************************GetKey:mov dptr, #OUTBITmov P2, dphmov r0, #Low(IN)mov r1, #00100000b ;列扫描初值mov r2, #6 ;扫描6列Kloop:mov a, r1 ; 找出键所在列cpl amovx @dptr, acpl arr amov r1, a ; 下一列movx a, @r0 ;读行值cpl aanl a, #0fhjnz Goon1 ; 该列有键入djnz r2,Kloopmov r2,#0ffh ; 没有键按下, 返回 0ffhsjmp ExitGoon1:mov r1,a ; R1中为行值,键序号 = (列-1)* 4 + 行mov a,r2 ;R2中为列值dec arl arl amov r2,a ; r2 = (r2-1)*4mov a,r1 ; r1中为读入的行值mov r1,#4 ;共有4行LoopC:rrc a ; 移位找出所在行jc Exitinc r2 ; r2 = r2+ 行值djnz r1,LoopCExit: mov a,r2 ; 查表取出键值码mov dptr,#KeyTablemovc a, @a+dptrmov r2,aWaitRelease:mov dptr,#OUTBIT ; 等键释放clr amovx @dptr,amov r6,#10call Delaycall TestKeyjnz WaitReleasemov a,r2ret;****键盘程序文件key.lib结束****;************************;*******以下为另一文件:主程序***********$include (para.lib)ORG 0Ljmp StartStart:mov sp, #40hmov dptr,#0e100hmov a,#03hmovx @dptr,amov LEDBuf,#0ffh ; 显示 8.8.8.8.mov LEDBuf+1,#0ffhmov LEDBuf+2,#0ffhmov LEDBuf+3,#0ffhmov LEDBuf+4,#0mov LEDBuf+5,#0Mloop:call DisplayLED ; 显示call TestKey ; 有键入?Jz Mloop ; 无键入, 继续显示call GetKey ; 读入键码mov r2,aanl a, #0fh ; 显示键码低位mov dptr, #LEDMapmovc a, @a+dptrmov LEDBuf+5,amov a,r2swap aanl a, #0fh ; 显示键码高位mov dptr, #LEDMapmovc a, @a+dptrmov LEDBuf+4, aljmp Mloop$include (dis.lib)$include (key.lib)END9、实验步骤1) 编写程序。
矩阵键盘设计实验报告
矩阵键盘是一种特殊的电子输入设备,其特殊性在于每个按键可以仅由几根线连接而成。
这可以将按键尺寸缩小,同时也减少了接線复杂度。
在本次实验中,我们设计了一个4*4的矩阵键盘。
矩阵键盘的外型是4 *4的按键,其中每个按键由一个PIN组成,连接起来分别连接在一个不同的ROW与COL上。
在使用矩阵键盘时,我们将其连接到一台电脑上,通过电脑程序监视每行每列的通断状态,当一行或者一列被按下,程序会自动捕捉,来表示一个字符或者code.
首先,我们先准备一台电脑,再连接矩阵键盘的各个PIN,用8个信号线将矩阵键盘连接到单片机,再用USB线将单片机连接到电脑上,使用PL 2303驱动链接矩阵键盘和电脑终端。
单片机负责捕获ROW和COL的信号,计算并识别矩阵键盘的按键,将计算出的字符发送至电脑终端,进行小程序的检测。
在电脑端,我们使用Apple系统的终端运行.bash,编写简单的shell脚本实现对矩阵键盘信号识别。
脚本将不断检测矩阵键盘信号状态,根据捕捉到的ROW和COL信号,将其映射出字符信息,在一定时间内输出至终端。
在实验的最后,我们检验了所设计的矩阵键盘是否符合预期效果。
通过代码发送进行按键操作,能检测到正确的字符,表明矩阵键盘的设计及实现满足要求。
本次实验可以作为以后矩阵键盘的参考,深入研究程序软件,提高实验效率。
实验报告课程名称嵌入式系统实验名称4x4键盘控制实验姓名王闯学号200907040318 专业班级软件0903实验日期年月日成绩指导教师王彩玲一、实验目的1 、通过实验掌握中断式键盘控制与设计方法;2 、掌握中断式键盘检测程序的设计思路;3 、熟练编写ARM 核处理器S3C44B0X 中断程序;二、实验设备1 、硬件:EMBEST S3CEV40 实验平台,Embest ARM 标准/ 增强型仿真器套件,PC 机;2 、软件:Embest IDE 2003 集成开发环境,Windows 98/2000/NT/XP 操作系统。
三、实验内容使用实验板上4 ×4 用户键盘,编写程序通过中断的方式读入键值,并在实验板的LE D数码管上显示读到的键值。
四、实验原理键盘接口电路如图所示,板上扩展了一个4×4行列式矩阵键盘接口。
该键盘是采用中断扫描的方式进行工作,行线选用了4个数据线,列线选用了4个地址线。
行线接上拉电阻保持高电平,并通过与门74HC08将输出信号与MCU 的中断EXINT1连接;列线接下拉电阻保持低电平。
当有键盘按下时,该行线被拉为低电平,使得EXINT1输入也为低电平,MCU 产生中断。
中断产生后通过对键盘的行和列进行扫描的方法可以计算出是哪个键按下,并跳到相应的键盘处理程序中去。
芯片74HC541是通过片选信号nGCS3来选通的,这样可以保证在键盘不使用的情况下MCU 读不到行线的输入信息。
123456784*4KEYBOARDCON7VDD33121311U13D 74HC089108714U13C74HC08456U13B 74HC08VDD33L0L1L2L3EXINT1R354.7K R364.7K R374.7K R384.7KD71N4148D81N4148D91N4148D101N4148G11A12A23A34Y217Y118G219VCC 20A45A56A67A78Y613Y514Y415Y316A89GND 10Y811Y712U10074HC541VDD33D0D1D2D3A1A2A3A4L0L1L2L3NGCS3GNDGND 1A11Y 22A32Y 45A116Y 126A13VCC 143A53Y 6GND74Y 84A95Y 10U10174HC17R20010K R20110K R20210K R20310K R20410KR20510K GND GND VDD33GNDGND五、实验操作步骤(1 )准备实验环境。
实验7 4*4 键盘扫描控制器1.实验任务说明:设计并实现4*4 键盘扫描控制电路,判断哪个按键被按下,在数码管上显示键值,并通过蜂鸣器发出按键音。
要求:●键值采用16 进制编码,即16 个按键分别对应显示16 进制数0~F,按键对应关系如下:最上面一行从左至右依次为0~3,第二行从左至右依次为4~7,第三行从左至右依次为8~B,最下面一行从左至右依次为C~F,其中b、d 显示为小写,其他字母大写;●按键按下时显示当前键值并保持,直到下一按键被按下时更新显示;●只有按键被按下时蜂鸣器发出按键音,放开后蜂鸣器不发声。
●选做:每个按键对应不同的按键音。
●2.实验设计思路将本实验分为4个部分,分别是顶层,分频器(扫描时钟的分频器和为蜂鸣器提供频率的分频器),数码管译码电路,扫描信号发生电路。
顶层利用状态机实现,状态转移为s0->s1->s2->s3->s0,分别对应扫描到col[0->3->0]。
同时把row 信号转化为一个“时钟信号”clock_change,当有按键按下就输出1,没有则输出0。
并以这个时钟设计一个时序逻辑,当clock_change的上升沿到来才更新tempSegin(传递给数码管的输入信号)和choose(传递给蜂鸣器分频器的输入信号),输出sound信号时,将蜂鸣器输出的信号与clock_change信号相与,以达到按下一次键盘蜂鸣器发声,数码管显示的目的。
3.源程序:1)分频器扫描时钟的分频器:LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL;USE IEEE.STD_LOGIC_ARITH.ALL;entity divide is--divide the frequency to 1/ngeneric( n:natural:=200);port( clk: in std_logic;clk_out: out std_logic);end divide;architecture div_arch of divide is--temporary signalsignal temp: std_logic;beginprocess( clk )--count variable count from 0 to n/2-1--means every n/2 period reverse the clk variable count: integer range 0 to n/2-1;beginif (clk'event and clk='1') thenif( count = n/2-1) thentemp <= not temp;count := 0;elsecount := count + 1;end if;end if;end process;clk_out <= temp;end div_arch;为蜂鸣器提供频率的分频器LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL;USE IEEE.STD_LOGIC_ARITH.ALL;entity divide_sound is--the origin clk is 50MHz--divide the frequency to 1/ngeneric( n0:natural:=4;n1:natural:=8;n2:natural:=12;n3:natural:=16;n4:natural:=20;n5:natural:=24;n6:natural:=28;n7:natural:=42;n8:natural:=46;n9:natural:=50;n10:natural:=54;n11:natural:=58;n12:natural:=62;n13:natural:=66;n14:natural:=70;n15:natural:=74);port( clk: in std_logic;choose: in integer range 0 to 15;sound_out: out std_logic);end divide_sound;architecture div_arch of divide_sound is --temporary signalsignal temp: std_logic;beginprocess( clk )--count variable count from 0 to n/2-1--means every n/2 period reverse the clk variable count: integer range 0 to 100;variable n:integer range 0 to 200;--count'max is over the n(max)/2 - 1begincase choose iswhen 0 =>n := n0;when 1 =>n := n1;when 2 =>n := n2;when 3 =>n := n3;when 4 =>n := n4;when 5 =>n := n5;when 6 =>n := n6;when 7 =>n := n7;when 8 =>n := n8;when 9 =>n := n9;when 10 =>n := n10;when 11 =>n := n11;when 12 =>n := n12;when 13 =>n := n13;when 14 =>n := n14;when 15 =>n := n15;when others => n:= n0;end case;if(clk'event and clk='1') thenif( count = n/2 - 1) thentemp <= not temp;count := 0;elsecount := count + 1;end if;end if;end process;sound_out <= temp;end div_arch;2)扫描信号发生电路LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_ARITH.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL;entity scan_seq is--produce the column scan signalport( clk,reset: in std_logic;col: out std_logic_vector(3 downto 0));end scan_seq;architecture arch of scan_seq isbeginprocess(clk)variable count: integer range 0 to 3;--M=4 counter,every count output the porper impulse beginif( reset ='1')thencount := 0;elsif( clk'event and clk='1' )thenif( count = 3)thencount := 0;elsecount := count +1;end if;end if;case count iswhen 0 => col<="1110";when 1 => col<="1101";when 2 => col<="1011";when 3 => col<="0111";end case;end process;end arch;3)数码管译码电路LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_ARITH.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL;ENTITY seg7_1H IS --seg7 decoding PORT(a: IN STD_LOGIC_VECTOR(3 DOWNTO 0); --inputb: OUT STD_LOGIC_VECTOR(6 DOWNTO 0); --outputcat: OUT STD_LOGIC_VECTOR(7 DOWNTO 0) --selcect);END seg7_1H;ARCHITECTURE aa OF seg7_1H ISsignal temp: std_logic_vector(3 downto 0);BEGINprocess(a)beginCASE a IS --b6-0 -> abcdefg WHEN "0000" => b <= "1111110"; --0WHEN "0001" => b <= "0110000"; --1WHEN "0010" => b <= "1101101"; --2WHEN "0011" => b <= "1111001"; --3WHEN "0100" => b <= "0110011"; --4WHEN "0101" => b <= "1011011"; --5WHEN "0110" => b <= "1011111"; --6WHEN "0111" => b <= "1110000"; --7WHEN "1000" => b <= "1111111"; --8WHEN "1001" => b <= "1111011"; --9WHEN "1010" => b <= "1110111"; --AWHEN "1011" => b <= "0011111"; --bWHEN "1100" => b <= "1001110"; --CWHEN "1101" => b <= "0111101"; --dWHEN "1110" => b <= "1001111"; --EWHEN "1111" => b <= "1000111"; --FWHEN others => b <= "0000000"; --others END CASE;end process;cat <= "11111110";END aa;4)顶层LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_ARITH.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL;entity scanKeyboard is--scan the keyboard and display, sound at the same time port(clk,reset: in std_logic;row: in std_logic_vector(3 downto 0);col: out std_logic_vector(3 downto 0);sound: out std_logic;b: out std_logic_vector(6 downto 0);cat: out std_logic_vector(7 downto 0);seeclk: out std_logic);end scanKeyboard;architecture arch of scanKeyboard iscomponent divide_sound is--the origin clk is 50MHz--divide the frequency to 1/ngeneric( n0:natural:=4;n1:natural:=8;n2:natural:=12;n3:natural:=16;n4:natural:=20;n5:natural:=24;n6:natural:=28;n7:natural:=42;n8:natural:=46;n9:natural:=50;n10:natural:=54;n11:natural:=58;n12:natural:=62;n13:natural:=66;n14:natural:=70;n15:natural:=74);port( clk: in std_logic;choose: in integer range 0 to 15;sound_out: out std_logic);end component;component scan_seq is--produce the column scan signalport( clk,reset: in std_logic;col: out std_logic_vector(3 downto 0));end component;component seg7_1H IS --seg7 decoding PORT(a: IN STD_LOGIC_VECTOR(3 DOWNTO 0); --inputb: OUT STD_LOGIC_VECTOR(6 DOWNTO 0); --outputcat: OUT STD_LOGIC_VECTOR(7 DOWNTO 0) --selcect);END component;component divide is--divide the frequency to 1/ngeneric( n:natural:=200);port( clk: in std_logic;clk_out: out std_logic);end component;--clk_scan is the scan signal for column--tempSound is the output of the sound divider--tempSegin is the input of the seg7 translate part--clock_change is disgned to record the row's impulse appear--choose is the select of the keyboardsignal clk_scan: std_logic;signal tempSound:std_logic;signal tempSegin:std_logic_vector(3 downto 0);signal clock_change:std_logic;signal choose: integer range 0 to 15;type state is (s0,s1,s2,s3);signal presentstate, nextstate : state;beginu0:divide_sound port map(clk => clk,choose=>choose,sound_out=>tempSound);u1:divide port map(clk =>clk, clk_out=>clk_scan);u2:scan_seq port map(clk=>clk_scan,reset=>reset,col=>col);u3:seg7_1H port map(a=>tempSegin,b=>b,cat=>cat); --discrible the register for clk_scanp1_reg:process(clk_scan,reset)beginif(reset ='1')thenpresentstate<= s0;elsif( clk_scan'event and clk_scan='1' )thenpresentstate<= nextstate;end if;end process;--discrible the state for clk_scanp2_stateChange:process(presentstate)begincase presentstate iswhen s0 => nextstate<= s1;when s1 => nextstate<= s2;when s2 => nextstate<= s3;when s3 => nextstate<= s0;end case;end process;--discrible the outputp3_out:process(presentstate,row,clock_change)begin--behave synchronize with the clock_changeif( clock_change'event and clock_change = '1')then case presentstate is-- column[0]when s0 => case row iswhen "1110"=>choose <= 12;tempSegin <= "1100";when "1101"=>choose <= 8;tempSegin <= "1000";when "1011"=>choose <= 4;tempSegin <= "0100";when "0111"=>choose <= 0;tempSegin <= "0000";when others=>choose <= 0;tempSegin <= tempSegin;end case;-- column[1]when s1 => case row iswhen "1110"=>choose <= 13;tempSegin <= "1101";when "1101"=>choose <= 9;tempSegin <= "1001";when "1011"=>choose <= 5;tempSegin <= "0101";when "0111"=>choose <= 1;tempSegin <= "0001";when others =>choose <= 0;tempSegin <= tempSegin;end case;-- column[2]when s2 => case row iswhen "1110"=>choose <= 14;tempSegin <= "1110";when "1101"=>choose <= 10;tempSegin <= "1010";when "1011"=>choose <= 6;tempSegin <= "0110";when "0111"=>choose <= 2;tempSegin <= "0010";when others=>choose <= 0;tempSegin <= tempSegin;end case;-- column[3]when s3 => case row iswhen "1110"=>choose <= 15;tempSegin <= "1111";when "1101"=>choose <= 11;tempSegin <= "1011";when "1011"=>choose <= 7;tempSegin <= "0111";when "0111"=>choose <= 3;tempSegin <= "0011";when others=>choose <= 0;tempSegin <= tempSegin;end case;end case;end if;end process;--discrible clkchangep3_clkchange:process(row)beginif( row = "1111")thenclock_change <='0';elseclock_change<='1';end if;end process;--output the sound signalsound <= tempSound and clock_change;--to see the clock_change in waveformseeclk <= clock_change;end arch;4.仿真波形及分析1)分频器1(扫描时钟的分频器)图1-1分频器整体图1-2 分频器计数到99翻转(高翻低)图1-3 分频器计数到99翻转(低翻高)实际应采用分频比为,50k,现仿真时为方便仿真取为200分频,由图1-1可以看到整体分频的情况,由图1-2可以看到分频器在计数到99时由高电平翻为低电平,由图1-3可以看到分频器在计数到99时由低电平翻为高电平。
4乘4键盘实验报告一、摘要本系统以89C51集成块为核心器件,制作一种4横4列的键盘。
采用16个按钮式键盘,以及一个硬件复位器。
在按下其中一个按钮时,在键盘扫描程序的作用下,通过键盘扫描识别后,在数码管上显示出来;按下硬件复位器,数码管只显示小数点,实现复位。
本次设计代码采用C语言编制,方便简单,易于调试。
关键词:89C51,键盘,按纽,数码管二、硬件设计2.1、89C51简介89C51是一种带4K字节闪烁可编程可擦除只读存储器(FPEROM—Falsh Programmable and Erasable Read Only Memory)的低电压,高性能CMOS8位微处理器,俗称单片机。
89C2051是一种带2K字节闪烁可编程可擦除只读存储器的单片机。
单片机的可擦除只读存储器可以反复擦除100次。
该器件采用ATMEL高密度非易失存储器制造技术制造,与工业标准的MCS-51指令集和输出管脚相兼容。
由于将多功能8位CPU 和闪烁存储器组合在单个芯片中,ATMEL的89C51是一种高效微控制器,89C2051是它的一种精简版本。
89C51单片机为很多嵌入式控制系统提供了一种灵活性高且价廉的方案。
主要特性:·与MCS-51 兼容·4K字节可编程闪烁存储器·寿命:1000写/擦循环·数据保留时间:10年·全静态工作:0Hz-24MHz·三级程序存储器锁定·128*8位内部RAM·32可编程I/O线·两个16位定时器/计数器·5个中断源·可编程串行通道·低功耗的闲置和掉电模式·片内振荡器和时钟电路2.2、元件分析与工作原理VCC:供电电压。
GND:接地。
P0口:P0口为一个8位漏级开路双向I/O口,每脚可吸收8TTL门电流。
当P1口的管脚第一次写1时,被定义为高阻输入。
P0能够用于外部程序数据存储器,它可以被定义为数据/地址的第八位。
黄淮学院机械与能源工程学院
单片机应用技术课程报告
实验名称4X4矩阵键盘的显示电路实验时间年月日学生姓名实验地点钉钉群线上
同组人员专业班级汽服1802B
1、实验目的
1、能够在Keil软件中查看变量,掌握程序调试的基本方法;
2、掌握按键功能设计特点;
3、当键盘中按键数量较多时,为了减少I/O端口线的占用,通常将按键排列成矩阵形式,学习按键的相关知识。
2、任务设计要求
没有按键按下时,所有输出端均为高电平,即“1”,行线输入也是高电平,即“1”;有键按下时,相应列的输出为低电平,即“0”,对应行输入线也为低电平,即“0”。
通过检测输入线的状态可知是否有键按下。
通过51单片机P1端口构成4×4矩阵式键盘,要求:当按下某一按键时,在数码管显示该按键的值。
3、总体设计方案
根据实验任务要求,通过功能分析,设计的系统总体方案如图所示。
复习软件的使用方法,软件关键字如下:
4、硬件电路设计
5、软件程序设计
如果要实现上图所示电路中转向灯的控制,需要设计控制P1.0端口输出低电平,其设计思路如图所示。
(2)程序清单
#include <reg51.h>
#define uchar unsigned char
sbit L1=P1^4; // 定义列
sbit L2=P1^5;
sbit L3=P1^6;
sbit L4=P1^7;
按下相应的键就会显示对应的字母或数字。
4x4键盘输入实验一、实验目的1.掌握4×4矩阵式键盘程序识别原理。
2.掌握4×4矩阵式键盘按键的设计方法。
二、实验原理:主要原理为扫描键盘矩阵时,每次只有一行电平拉低。
在逐次扫描拉低的这些行的同时,去读那些列的电平。
;被拉低的行上,按下的键对应的列的电平为0 ,其它为1. 用左移位的指令,在进位位CY里就可以检测出是0还是1.为1表示无按下,;为0表示该键按下。
在扫描按键时,如无按下,则取码指针R1加1后,继续扫描。
如有键按下,转按键处理子程序,按键按下标志位;F0清0(表示按下)。
此时,取码指针的值,就是按键的键名。
随后继续进入按键检测子程序重新扫描。
每个按键有它的行值和列值,行值和列值的组合就是识别这个按键的编码。
矩阵的行线和列线分别通过两并行接口和CPU通信。
每个按键的状态同样需变成数字量“0”和“1”,开关的一端(列线)通过电阻接VCC,而接地是通过程序输出数字“0”实现的。
键盘处理程序的任务是:确定有无键按下,判断哪一个键按下,键的功能是什么;还要消除按键在闭合或断开时的抖动。
两个并行口中,一个输出扫描码,使按键逐行动态接地,另一个并行口输入按键状态,由行扫描值和回馈信号共同形成键编码而识别按键,通过软件查表,查出该键的功能。
键盘连接成4×4的矩阵形式,占用单片机P1口的8根线,行信号是P1.0-1.3,列信号是P1.4-1.7。
三、实验内容及过程:1、流程图2、实验中碰到的问题编写程序时需要用到的共阳字形码,不能与共阴字形码混淆。
在仿真过程中,数码管下拉电阻起到分流作用,应该接地,但是却始终不能出结果,将下拉电阻与电源相连就可以显示正确了。
四、实验现象:按下一个键,在数码管上就会显示对应的数字或者字母。
五、程序:ORG 0000HAJMP MAINORG 0030H MAIN: MOV DPTR,#TABLCALL KEYMOVC A,@A+DPTRMOV P1,ALJMP MAIN KEY: LCALL KSJNZ K1LCALL DELAYAJMP KEYK1: LCALL DELAYLCALL KSJNZ K2AJMP KEYK2: MOV R2,#0EFHMOV R4,#0000HK3: MOV P1,R2L6: JB P2.0,L1MOV A,#0000HAJMP LKL1: JB P2.1,L2MOV A,#04HAJMP LKL2: JB P2.2,L3MOV A,#08HAJMP LKL3: JB P2.3,NEXTMOV A,#0CH LK: ADD A,R4PUSH ACCK4: LCALL DELAYLCALL K4POP ACCRETNEXT: INC R4MOV A,R2JNB ACC.7,KEYRL AMOV R2,AAJMP K3KS: MOV P2,#0FHMOV A,P2XRL A,#0FHRETDELAY:MOV R6,#0FEHLOOP1:MOV R7,#0FEHLOOP2:DJNZ R7,LOOP2DJNZ R6,LOOP1RETTAB: DB 0C0HDB 0F9HDB 0A4HDB 0B0HDB 99HDB 92HDB 82HDB 0F8HDB 80HDB 90HDB 088HDB 083HDB 0C6HDB 0A1HDB 086HDB 08EHEND六、实验心得通过本实验,懂得如何安装kell软件以及实验仿真板,懂得KEIL C51单片机仿真软件的调试,掌握了单片机矩阵键盘的基本知识。
实验八键盘扫描显示实验一、实验目的1、了解普通4×4键盘扫描的原理。
2、进一步加深七段码管显示过程的理解。
二、硬件要求1、4×4键盘阵列。
2、FPGA主芯片EP1K30TC144-3。
3、可变时钟源。
4、七段码显示区。
三、实验原理本实验主要完成的实验是完成4×4键盘扫描的,然后获取其键值,并对其进行编码,从而进行按键的识别,并将相应的按键值进行显示。
键盘扫描的实现过程如下:对于4×4键盘,通常连接为4行、4列,因此要识别按键,只需要知道是哪一行和哪一列即可,为了完成这一识别过程,我们的思想是,首先固定输出4行为高电平,然后输出4列为低电平,在读入输出的4行的值,通常高电平会被低电平拉低,如果读入的4行均为高电平,那么肯定没有按键按下,否则,如果读入的4行有一位为低电平,那么对应的该行肯定有一个按键按下,这样便可以获取到按键的行值。
同理,获取列值也是如此,先输出4列为高电平,然后在输出4行为低电平,再读入列值,如果其中有哪一位为低电平,那么肯定对应的那一列有按键按下。
获取到行值和列值以后,组合成一个8位的数据,根据实现不同的编码在对每个按键进行匹配,找到键值后在7段码管显示。
四、实验内容及步骤本实验内容是完成4×4键盘的扫描,然后将正确的键值进行显示,实验步骤如下:1、编写键盘扫描和显示的VHDL代码。
2、用MaxPlusII对其进行编译仿真。
3、在仿真确定无误后,选择芯片ACEX1K EP1K30TC144-3。
4、给芯片进行管脚绑定,在此进行编译。
5、根据自己绑定的管脚,在实验箱上对键盘接口、显示接口和FPGA之间进行正确连线。
6、给目标板下载代码,在4×4键盘输入键值,观看实验结果。
五、实验连线如果是调用的本书提供的VHDL代码,则实验连线如下:Clk:FPGA工作时钟信号,大约位5KHz至50KHz即可。
Kr[0:3]:分别接4×4键盘部分的R1、R2、R3和R4。
单片机及DSP课程设计报告专业:班级:姓名:学号:指导教师:时间:一、设计目的为了进一步巩固学习的理论知识,增强学生对所学知识的实际应用能力和运用所学的知识解决实际问题的能力,开始为期两周的课程设计。
通过设计使学生在巩固所学知识的基础之上具有初步的单片机系统设计与应用能力。
1、通过本设计,使学生综合运用《单片机技术原理与应用》、《DSP原理与应用》《C语言程序设计》以及《数字电路》、《模拟电路》等课程的内容,为以后从事电子产品设计、软件编程、系统控制等工作奠定一定的基础。
2、学会使用KEIL C和PROTEUS等软件,用C语言或汇编语言编写一个较完整的实用程序,并仿真运行,保证设计的正确性。
3、了解单片机接口应用开发的全过程:分析需求、设计原理图、选用元器件、布线、编程、调试、撰写报告等。
二、硬件电路方案设计1、4X4键盘设计4x4键盘工作原理:每个按键都有它的行值和列值,行值和列值的组合就是识别这个按键的编码。
矩阵的行线和列线分别通过两并行接口和CPU通信。
键盘的一端(列线)通过电阻接VCC,而接地是通过程序输出数字“0”实现的。
键盘处理程序的任务是:确定有无键按下,判断哪一个键按下,键的功能是什么?还要消除按键在闭合或断开时的抖动。
两个并行口中,一个输出扫描码,使按键逐行动态接地;另一个并行口输入按键状态,由行扫描值和回馈信号共同形成键编码而识别按键,通过软件查表,查出该键的功能。
2、数码管显示电路设计数码管显示原理:动态显示的特点是将所有位数码管的段选线并联在一起,由位选线控制是哪一位数码管有效。
这样一来,就没有必要每一位数码管配一个锁存器,从而大大地简化了硬件电路。
选亮数码管采用动态扫描显示。
所谓动态扫描显示即轮流向各位数码管送出字形码和相应的位选,利用发光管的余辉和人眼视觉暂留作用,使人的感觉好像各位数码管同时都在显示。
动态显示的亮度比静态显示要差一些,所以在选择限流电阻时应略小于静态显示电路中的。
3、晶振和复位电路设计4、系统总电路图三、程序设计1、程序流程图(1)键盘扫描第四行扫描第一行扫描第二行扫描第三行扫描1、在keil中运行程序,并生成hex文件保存。
2、proteus元件库中选择系统中所需的各元件,按设计的电路原理图进行连接。
3、连接好电路后鼠标双击AT89C52芯片,在“File”菜单中打开生成hex文件,下载完成后,点击运行按钮。
注意:1、在原理图的绘制过程中对数码管的选择要注意考虑所写程序,无法点亮时应考虑共阳极数码管或共阴极数码管的选择。
2、P0口接数码管时应接上拉电阻,否则无法点亮参考文献1、单片接口技术李航电子科学出版社;2、模拟电子技术基础童诗白华成英高等教育出版社;3、数字电子技术基础阎石高等教育出版社;4、51单片机设计与仿真原理程候渊北方工业出版社;五、课程设计总结心得体会:由于我没有过硬的技术,所以选择了《键盘接口和显示设计》这个相对于其他比较简单题目,望老师见谅。
做完了本次课程设计,我收获颇多,无论是学习上还是其他方面,都有所感悟。
在学习上:我对单片机有关知识有了更深刻的了解,学到了许多以前书本上没有的知识开阔了眼界和见识,“通信深似海”,只是单片机一门就让我深有体会。
,并把理论运用到实践中去,体会到了实践的重要性。
这次课程设计又为我们提供了一次自己动手操作实践的机会。
在上次的8路呼叫器的知识基础上,我这次完成的很顺利,对以往未完全掌握的知识进行了补充,对以往掌握的知识加深了了解。
这次课程设计起到着承上启下的作用,加深了过去的知识,打好了未来的实践基础每位同学对这次课程设计都付出了自己辛劳的汗水,这也使得他们的个人编程能力、电路设计能力、仿真调试能力都得到了一定程度的提高。
替他方面:做事一定要认真,在仿真时候由于一个什么什么选错了,导致仿真不能实现,检查了很多次才发现,实属不该;在编程时,也是由于一个不该犯的低级错误,导致了整个程序不能完美运行,这些都是不细心犯下的错误,以后一定要认真去做好每一件事,不让不该犯的错误导致满盘皆输。
此外,这次课程设计让我对对Keil和Proteus两款软件有了更进一步认识,了解了单片机的电路图的绘制、仿真方法,为以后的学习工,作打下了基础。
这次实习也暴露了我很多弱项,比如数电、模电学得不好,很多东西都是靠请教同学才懂。
总之这次课程设计使我对通信专业有了更深一步的认识,极大地增加了我对该专业的兴趣,相信我以后在通信这条道路上会走的更好!主程序:#include<reg52.h>#define uint unsigned int#define uchar unsigned charuchar num,temp;uchar keyscan();void delay(uint z);void display(uchar aa);uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//****************主函数*****************// void main(){while(1){keyscan();display(num);}}//***************延时函数***************// void delay(uint z){uint x,y;for(x=z;x>0;x--)for(y=100;y>0;y--);}//***************键盘扫描**************// uchar keyscan(){P1=0xfe;temp=P1;temp=temp&0xf0;while(temp!=0xf0){delay(2);temp=P1;temp=temp&0xf0;while(temp!=0xf0){temp=P1;switch(temp){case 0xee:num=11;break;case 0xde:num=12;break;case 0xbe:num=13;break;case 0x7e:num=14;break;}while(temp!=0xf0){temp=P1;temp=temp&0xf0;}}}P1=0xfd;temp=P1;temp=temp&0xf0;while(temp!=0xf0){delay(2);temp=P1;temp=temp&0xf0;while(temp!=0xf0){temp=P1;switch(temp){case 0xed:num=21;break;case 0xdd:num=22;break;case 0xbd:num=23;break;case 0x7d:num=24;break;}while(temp!=0xf0){temp=P1;temp=temp&0xf0;}}}P1=0xfb;temp=P1;temp=temp&0xf0;while(temp!=0xf0){delay(2);temp=P1;temp=temp&0xf0;while(temp!=0xf0){temp=P1;switch(temp){case 0xeb:num=31;break;case 0xdb:num=32;break;case 0xbb:num=33;break;case 0x7b:num=34;break;}while(temp!=0xf0){temp=P1;temp=temp&0xf0;}}}P1=0xf7;temp=P1;temp=temp&0xf0;while(temp!=0xf0){delay(2);temp=P1;temp=temp&0xf0;while(temp!=0xf0){temp=P1;switch(temp){case 0xe7:num=41;break;case 0xd7:num=42;break;case 0xb7:num=43;break;case 0x77:num=44;break;}while(temp!=0xf0){temp=P1;temp=temp&0xf0;}}}return num;}//**************************显示函数**********************// void display(uchar aa){ uint num1,num2;num1=aa/10;num2=aa%10;P2=0xfe;P0=table[num1];delay(5);P2=0xfd;P0=table[num2];delay(5);P0=0;}。