VHDL键盘扫描.doc_第1页
VHDL键盘扫描.doc_第2页
VHDL键盘扫描.doc_第3页
VHDL键盘扫描.doc_第4页
VHDL键盘扫描.doc_第5页
已阅读5页,还剩28页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

一、设计目的巩固和运用所学课程,理论联系实际,提高分析、解决计算机技术实际问题的独立工作能力,通过对FPGA几个简单的模块设计,进一步加深对计算机原理以及数字电路应用技术方面的了解与认识,进一步熟悉数字电路系统设计、制作与调试的方法和步骤。二、设计内容(1)设计一个44的键盘扫描模块,要求有防抖动功能。(2)用键盘控制1616点阵LED显示各种字符。(3)用键盘控制蜂鸣器发声,能有各种音调。三、实现方法本系统的系统组成及连接原理如图3.1所示,主系统由四个功能模块组成:分频模块(为键盘扫描模块和提供时钟)、键盘扫描模块、LED点阵模块、发声模块。LED点阵发声模块键盘扫描模块分频模块时钟输入接蜂鸣器接LED点阵接键盘图3.1整体模块划分1、分频模块分频模块的作用是把2MHZ的时钟分成1kHZ和500HZ,为键盘扫描模块和LED点阵模块提供时钟。主要方法是通过计数器实现分频。分频模块如图3.2,clk是输入时钟,clkout_kb是输入给键盘扫描模块使用,clkout_LED是输入给LED点阵模块使用。图3.2 分频模块视图其仿真结果如图3.3图 3.3分频模块仿真2、键盘扫描模块2.1行列式键盘原理行列式键盘又叫做矩阵式键盘。用带有I/O口的线组成行列结构,按键设置在行列的交点上。本次试验用到的是44的行列结构键盘,可以构成16个按键。这样,当按键数量平方增长是,I/O口只是线性增长,这样就可以节省I/O口。行列式键盘的原理如图3.4所示。CDEF89AB45670123keyin上拉电阻keydrv图 3.4 行列式键盘的原理按键设置在行列线交叉点,行、列线分别连接到按键开关的两端。列线通过上拉电阻接+5V的电压,即列线的输出被嵌位在高电平状态。判断按键中有无键按下时通过行线输入扫描信号,然后从列线读取到状态实现的。其方法是依次给行线送低电平,检查列线的输入。如果列线信号全为高电平,则代表低电平所在的行中无按键按下;如果列线有输入为低电平,则低电平信号所在的行和出现低电平的列的交点处有按键按下。设行扫描信号为keydrv3keydrv0,列线按键输入信号keyin3keyin0与按键位置的关系如表3.1所示表3.1行扫描信号、列线按键输入信号与按键位置的关系keydrv3keydrv0keyin3keyin0对应的按键111011100110111011201113110111104110151011601117101111108110191011A0111B01111110C1101D1011E0111F2.2键盘扫描系统模块划分44键盘键盘译码电路扫描电路按键去抖动电路时钟输入输入键盘值图3.5 键盘扫描系统模块划分键盘扫描电路时用于产生keydrv3-keydrv0信号,其变化顺序为1110110110110111周而复始的扫描。其停留在每个状态的时间大约有10ms。扫描电路的模型如下:图3.6 扫描电路外观接口扫描电路的仿真如图3.7所示:图3.7 扫描电路仿真键盘译码电路是从keydrv3keydrv0和keyin3keyin0译出按键值的电路,它的真值表如表1所示。键盘译码电路的模型如图3.8所示:图3.8 键盘译码电路外观其中键值keycode用5位编码,keycode为0000001111表示键值0F,keycode为11111时表示无按键按下。译码电路的仿真如图3.9所示:图3.9译码电路仿真图3.9仿真的是扫描信号在keydrv=1011时有按键按下,并且keyin=0111时的键值,由表1可知这时的键值因该是B,而由图中可以看出仿真结果是5h0B,即预测结果与仿真结果一致。2.3 按键去抖动电路实现由于机械触点的弹性作用,触点在闭合和断开瞬间的电接触情况不稳定,造成了电压信号的抖动现象,如图3.10所示。键的抖动时间一般为 510ms。这种现象会引起FPGA对于一次键操作进行多次处理,因此须设法消除键接通或断时的抖动现象。去抖动的方法有硬件和软件两种:硬件去抖动和软件去抖动。图3.10按键抖动现象去抖动模块采用多次连续检测输入键值的原理防抖。当检测到有键值输入时并不马上输出,而是当16次输入的键值都一样时才输出,其中只要有一次键值不同的话计数器都会置零,重新记数。这样就能消除按键的抖动影响。其模块外观如图3.11所示。图3.11去抖动模块外观按键去抖动仿真:图3.12按键去抖动仿真由仿真图形可以看出,输入keyvaluein开始和结束时都产生抖动,但经过去抖模块后抖动消失了。起到了去抖动的功能。3、1616 LED 点阵显示屏的设计3.1 16x16 LED点阵的工作原理及连接组成方式:16x16 LED点阵的工作原理同8x8 LED点阵的工作原理,图3.13是8x8的LED点阵单色行共阳模块的内部结构图,其单点工作电压Uf为18 V,正向电流IF为810 mA。当某一行线为高电平而某一列线为低时,其行列交叉的点就被点亮;而当其某一列线为高时,其行列交叉的点为暗;当某一行线为低电平时,无论列线如何,对应这一行的点全部为暗。图3.13:8x8的LED点阵单色行共阳模块的内部结构图本实验采用的16x16 LED点阵用四个8x8点阵显示构成,其连接方法如图3.14所示。图中,将(A)和(B)的8列、(C)和(D)的8列分别对应相连,同时将(A)和(C)的8行、 (B)和(D)的8行分别对应相连。即可形成一个16行(每一行有16个LED)、16列(每一列也有16个LED)的16x16点阵显示器,可将这256个点称为一页,这样,显示字符时。只要对一页中对应的亮灭进行控制即可。图3.14:四个8x8点阵显示构成的16x16 LED点阵3.2 16x16 LED点阵的驱动方式本实验采用动态扫描型驱动方式显示,即显示屏上的16行发光二极管共用一组列驱动寄存器,然后通过行驱动管的分时工作,来使每行LED的点亮时间占总时间的116。只要每行的刷新速率大于50 Hz,利用人眼的视觉暂留效应,人们就可以看到一幅完整的文字或画面。扫描驱动分行扫描驱动和列扫描驱动。由于16x16点阵显示器有16行,故使用行扫描信号,本电路中加入了一个4-16线译码器,其输入是一个频率为1000Hz的时钟信号,内部采用4位二进制加法器,分别为00001111,然后使每种状态只控制一路输出,解码输出为低态扫描信号,即会有16路输出。本实验的列信号由事先存于寄存器中的16进制码构成,每个矩阵表示一个字符的列扫描信号,伴随行扫描信号进行交替的扫描,其设计图见附录中16x16 LED点阵扫描设计草图。本实验所显示的字符由键盘编码所确定,其编码与显示字符对应的关系如表3.2所示:表3.2:键盘编码与对应显示字符键盘编码00000000010001000011显示字符0123键盘编码00100001010011000111显示字符4567键盘编码01000010010101001011显示字符89AB键盘编码01100011010111001111显示字符CDEF键盘编码11111显示字符音符图形3.3 16x16 LED点阵驱动电路16x16 LED点阵驱动外观电路如图3.15所示:图3.15 16x16 LED点阵驱动电路外观16x16 LED点阵驱动电路原理图如图3.16所示:图3.16:16x16 LED点阵驱动电路原理图驱动行信号仿真如图3.17所示:图3.17驱动行信号4、发声模块4.1音调的产生音调的产生是通过分频实现的。设计要求产生不同的音调,就需要不同的分频器。可以先构造一个分频器,然后通过VHDL中的参数传递语句构造出十二个不同的分频器,其分频数见表3.2(输入时钟是2MHz)。表3.3音符频率对照表键值音符频率分频数键值音符频率分频数0低53925102.04087中57842551.02041低64404545.45458中68802272.72732低74944048.5839中79882024.29153中15233824.0918A高110461912.04594中25783460.2076B高211751702.12775中36593034.9014C高313181517.45076中46982865.3295D高413971431.63924.2电路实现发声模块其内部是一个有一个输入,十二个输出的分频器,用于产生十二种音调。然后根据键值判断哪个口输出。其顶层视图如图3.18所示。图3.18发声模块外观发声模块的仿真见图3.19图3.19发声模块仿真仿真波形中l5h4是分频器的十二个输出口,当键值是C时speaker输入的是h3的值,达到了要求。5、顶层模块实现顶层电路只是把分频模块、键盘扫描模块、LED点阵模块和发声模块连接起来,其外观和内部结构如图3.20和3.21所示。图3.20顶层模块外观图3.21顶层模块内部结构6、管脚的定义管脚的定义如表3.4所示表3.4 管脚的定义I/O NameI/O DirectionLocBankclkInputP3BANK7SpeakerOutputP95BANK4keydrvOutputP120BANK3keydrvOutputP121BANK3keydrvOutputP122BANK3keydrvOutputP123BANK3keyinInputP125BANK3keyinInputP127BANK3keyinInputP129BANK3keyinInputP132BANK2LEDcolumnOutputP133BANK2LEDcolumnOutputP134BANK2LEDcolumnOutputP136BANK2LEDcolumnOutputP138BANK2LEDcolumnOutputP139BANK2LEDcolumnOutputP140BANK2LEDcolumnOutputP141BANK2LEDcolumnOutputP147BANK2LEDcolumnOutputP148BANK2LEDcolumnOutputP149BANK2LEDcolumnOutputP150BANK2LEDcolumnOutputP151BANK2LEDcolumnOutputP152BANK2LEDcolumnOutputP162BANK1LEDcolumnOutputP163BANK1LEDcolumnOutputP164BANK1LEDrowOutputP165BANK1LEDrowOutputP167BANK1LEDrowOutputP73BANK5LEDrowOutputP74BANK5LEDrowOutputP70BANK5LEDrowOutputP71BANK5LEDrowOutputP68BANK5LEDrowOutputP69BANK5LEDrowOutputP63BANK5LEDrowOutputP67BANK5LEDrowOutputP61BANK5LEDrowOutputP62BANK5LEDrowOutputP59BANK5LEDrowOutputP60BANK5LEDrowOutputP57BANK5LEDrowOutputP58BANK5附录 程序代码1、顶层模块library IEEE;use IEEE.STD_LOGIC_1164.ALL;use IEEE.STD_LOGIC_ARITH.ALL;use IEEE.STD_LOGIC_UNSIGNED.ALL;- Uncomment the following library declaration if instantiating- any Xilinx primitives in this code.-library UNISIM;-use UNISIM.VComponents.all;entity play_show is Port ( clk : in STD_LOGIC; keyin : in STD_LOGIC_VECTOR (3 downto 0); keydrv : out STD_LOGIC_VECTOR (3 downto 0);LEDrow : out STD_LOGIC_VECTOR(15 downto 0);-LED行扫描信号 LEDcolumn : out STD_LOGIC_VECTOR(15 downto 0); Displayshow: out STD_LOGIC_VECTOR (6 downto 0); Displayselect: out STD_LOGIC_VECTOR (3 downto 0); speaker : out STD_LOGIC);end play_show;architecture rtl of play_show iscomponent freq_divisionPort ( clk:in STD_LOGIC; clkout_kb:out STD_LOGIC; clkout_LED:out STD_LOGIC; clkout_display:out std_logic);end component;component keyboardPort ( clk : in STD_LOGIC;-扫描时钟,周期10ms keyin : in STD_LOGIC_VECTOR (3 downto 0); keydrv : out STD_LOGIC_VECTOR(3 downto 0); keyvalue : out STD_LOGIC_VECTOR(4 downto 0);-输出扫描信号end component;component LEDArrayPort ( clk : in STD_LOGIC;-时钟信号,经分灯鞯玫1ms脉冲 keycode : in STD_LOGIC_VECTOR(4 downto 0);-键盘给的编码 LEDrow : out STD_LOGIC_VECTOR(15 downto 0);-LED行扫描信号 LEDcolumn : out STD_LOGIC_VECTOR(15 downto 0)-LED列信号 );end component;component playport (clk:in STD_LOGIC;keyvalue:in STD_LOGIC_VECTOR(4 downto 0);speaker:out STD_LOGIC);end component;component IBUF port (I: in std_logic; O: out std_logic); end component;component Display Port ( Keyvalue : in STD_LOGIC_VECTOR (4 downto 0); clk: in STD_LOGIC; Display : out STD_LOGIC_VECTOR (6 downto 0); Diselect : out STD_LOGIC_VECTOR (3 downto 0);end component;-signal clkin:STD_LOGIC;signal clkout_kb,clkout_LED,clkout_display:STD_LOGIC;-signal keydrv1:STD_LOGIC_VECTOR (3 downto 0);signal keyvalue1:STD_LOGIC_VECTOR (4 downto 0);signal CLK_SIG: std_logic;begin-keydrv clk, O = CLK_SIG);U2freq_division:freq_divisionport map(CLK_SIG,clkout_kb,clkout_LED,clkout_display);U3keyboard:keyboardport map(clkout_kb,keyin,keydrv,keyvalue1);U4LEDArray1616:LEDArrayport map(clkout_LED,keyvalue1,LEDrow,LEDcolumn);U5Uplay:playport map(CLK_SIG,keyvalue1,speaker);U6Display:Displayport map(keyvalue1,clkout_display,Displayshow,Displayselect);end rtl;2、分频器entity fredivn isgeneric(N:integer:=2); Port ( clkin:in STD_LOGIC; clkout:out STD_LOGIC);end fredivn;architecture Behavioral of fredivn issignal clk1:std_logic:=0;signal counter:integer range 0 to n;beginprocess(clkin)begin if rising_edge(clkin)then if counter=(n-1)/2 then clk1=not clk1; counter=0; else counter=counter+1; end if; end if; end process;clkoutkb_N)port map(clk,clkout_kb);U2:fredivngeneric map(N=LED_N)port map(clk,clkout_LED);U3:fredivngeneric map(N=display_N)port map(clk,clkout_display);end RTL;4、键盘扫描驱动entity keyscan is Port ( clkin : in STD_LOGIC;-扫描时钟,周期20ms keydrv : out STD_LOGIC_VECTOR(3 downto 0);-输出扫描信号end keyscan;architecture behavioral of keyscan issignal count : std_logic_vector(1 downto 0):=00;-计数器信号beginprocess(clkin)beginif rising_edge(clkin) thenif count=11 thencount=00;elsecountkeydrvkeydrvkeydrvkeydrvkeydrv=0000;end case;end process;end behavioral;5、键盘编码entity keydecoder is Port ( clkin: in std_logic; keyin : in STD_LOGIC_VECTOR (3 downto 0); keydrv : in STD_LOGIC_VECTOR (3 downto 0); keycode : out STD_LOGIC_VECTOR (4 downto 0); end keydecoder;architecture Rtl of keydecoder issignal temp:STD_LOGIC_VECTOR (7 downto 0);signal keyvalue1:STD_LOGIC_VECTOR (4 downto 0):=11111;signal count:std_logic_vector(1 downto 0):=00;-signal keypressed:boolean:=false;-signal q1,q2,q3,q4:boolean;begintemp=keydrv&keyin;process(clkin)beginif falling_edge(clkin) thenif keyin=1111 thenif count=11 thenkeyvalue1=11111;count=00;elsecount=count+1;end if;elsecountkeyvalue1keyvalue1keyvalue1keyvalue1keyvalue1keyvalue1keyvalue1keyvalue1keyvalue1keyvalue1keyvalue1keyvalue1keyvalue1keyvalue1keyvalue1keyvalue1keyvalue1=keyvalue1;end case;end if;end if;end process;keycode=keyvalue1;end rtl;6、键盘防抖entity Antiwitter is Port ( clkin : in STD_LOGIC; keyvaluein : in STD_LOGIC_VECTOR (4 downto 0); keyvalueout : out STD_LOGIC_VECTOR (4 downto 0);end Antiwitter;architecture Behavioral of Antiwitter issignal TempNum:std_logic_vector(4 downto 0);signal Counter:std_logic_vector(4 downto 0);signal Start:std_logic;beginprocess(clkin)beginif rising_edge(clkin) then if Start=0 thenTempNum=11111;keyvalueout=11111;Start=1;elseif keyvaluein/=TempNum thenTempNum=Keyvaluein;Counter=00000;elseif Counter=11111 thenkeyvalueout=keyvaluein;Counter=00000;elseCounter=Counter+1;end if;end if;end if;end if;end process;end Behavioral;7、键盘顶层entity keyboard isPort ( clk : in STD_LOGIC;-扫描时钟,周期10ms keyin : in STD_LOGIC_VECTOR (3 downto 0); keydrv : out STD_LOGIC_VECTOR(3 downto 0); keyvalue : out STD_LOGIC_VECTOR(4 downto 0);-输出扫描信号end keyboard;architecture RTL of keyboard iscomponent keyscanPort ( clkin : in STD_LOGIC;-扫描时钟,周期10ms keydrv : out STD_LOGIC_VECTOR(3 downto 0);-输出扫描信号end component;component keydecoderPort ( clkin:in std_logic; keyin : in STD_LOGIC_VECTOR (3 downto 0); keydrv : in STD_LOGIC_VECTOR (3 downto 0); keycode : out STD_LOGIC_VECTOR (4 downto 0);end component;component Antiwitter Port ( clkin : in STD_LOGIC; keyvaluein : in STD_LOGIC_VECTOR (4 downto 0); keyvalueout : out STD_LOGIC_VECTOR (4 downto 0);end component;signal keydrv1:STD_LOGIC_VECTOR (3 downto 0);signal key:std_logic_vector(4 downto 0);beginU1:keyscanport map(clk,keydrv1);U2:keydecoderport map(clk,keyin,keydrv1,key);U3:Antiwitterport map(clk,key,keyvalue);keydrv=keydrv1;end RTL;8、LED扫描entity LEDArray is Port ( clk : in STD_LOGIC;-时钟信号,经分频器得到1ms脉冲 keycode : in STD_LOGIC_VECTOR(4 downto 0);-键盘给的编码 LEDrow : out STD_LOGIC_VECTOR(15 downto 0);-LED行扫描信号 LEDcolumn : out STD_LOGIC_VECTOR(15 downto 0)-LED列信号 );end LEDArray;architecture Scan of LEDArray issignal count : std_logic_vector(3 downto 0):=0000;-计数器信号begin-时钟信号触发的计数器计数-process(clk)beginif rising_edge(clk) thenif count=1111 thencount=000

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论