职场文秘网

首页 > 条据书信 > 保证书 / 正文

基于FPGA的键盘扫描程序的设计毕业设计

2020-08-26 10:10:12

X X 学 院 CHANGSHA UNIVERSITY 本科生毕业设计 设计(论文)题目:
基于FPGA的键盘扫描程序的设计 系    部:
专 业:
学 生 姓 名:
班 级:
学号 指导教师姓名:
职称 讲师 XX学院教务处 二○一一年二月制   (20 13 届)   本科生毕业设计说明书 基于FPGA的键盘扫描程序的设计 系    部:
电子与通信工程系 专 业:
学 生 姓 名:
班 级:
学号 指导教师姓名:
职称 最终评定成绩 2013 年 6 月 摘 要 在现代电子工业的控制电路中,键盘扫描和显示电路对系统的调试和设置有着重要的作用。随着EDA技术的发展,基于FPGA的扫描键盘因其结构简单,能有效防止机械键盘按键抖动带来的数据错误等优点在许多电子设备中都得到了广泛的应用。

本文主要是设计一个基于FPGA的键盘扫描程序,该设计在EDA工具Quarutus II9.0上开发完成,以Creat-SOPC2000实验箱上的4*4矩阵键盘为硬件实体,设计键盘扫描程序,将程序划分为时序产生模块、键盘扫描模块、弹跳消除模块、键值译码模块四个模块,时序产生模块为键盘扫描和弹跳消除模块产生时钟信号,键盘扫描模块采用行扫描法对4*4矩阵键盘进行扫描,键值译码模块将所按键值译码为共阳极8位7段数码管的显示码,几个模块组合起来实现键盘扫描的设计要求。最后对程序进行仿真分析和硬件验证。仿真结果表明,该系统具有集成度高、稳定性好、设计灵活和设计效率高等优点。

关键词:
FPGA,Quartus II,VHDL,键盘扫描 ABSTRACT In the modern electronics industry controlling-circuit, the keyboard scanning and display circuit plays an important role in debugging and setting the system. With the development of EDA technology, FPGA-based scanning keyboard have been widely used in many electronic devices because of its simple structure, and it also can effectively prevent mechanical keyboard jitter caused by data errors. This article primarily designed an FPGA-based keyboard scan procedures, this design is developed on the EDA tools—— Quarutus II9.0 and designed the keyboard scan program, using the Creat-SOPC2000 experimental box 4 * 4 matrix keyboard as the hardware entity .the program is divided into four modules as the timing generation module, a keyboard scanning module, bounce cancellation module and the decoding module. The timing generation module generates the clock signal for the keyboard scanning and bounce elimination module, the keyboard scanning module using the line scanning method to sweep the 4* 4 matrix keyboard, key decoder module decodes the key value for the common anode eight 7-segment display code. Several modules assembles together to meet the keyboard scanning design requirements. Finally, conducting simulation analysis by the program and verifying the hardware.Simulation results show that the system has many advantages such as high integration, good stability, high efficiency, flexible design and high design efficiency. Keywords: FPGA,Quartus II,VHDL,keyboard scanning 目 录 摘 要 I ABSTRACT II 第1章 绪 论 1 1.1 课题的研究背景 1 1.2 课题的研究意义 2 1.3 本文的主要工作 2 第2章 FPGA开发工具简介 3 2.1 FPGA概述 3 2.2 VHDL语言以及Quartus II应用 3 2.3 本章小结 4 第3章 基于FPGA的键盘扫描程序的设计 3 3.1 键盘扫描程序的总体电路设计 5 3.1.1 矩阵式键盘扫描的工作原理 6 3.1.2 数码管的显示原理 7 3.2 键盘扫描电路各主要功能模块的设计 8 3.2.1 时序产生模块 8 3.2.2 键盘扫描模块 9 3.2.3 弹跳消除模块 11 3.2.4 键盘译码电路 13 3.2.5 键盘扫描程序的顶层文件设计 15 3.3本章小结 16 第4章 键盘扫描程序的波形仿真及硬件验证 17 4.1 系统仿真 17 4.1.1 消抖电路仿真 17 4.1.2 键盘时钟信号仿真 18 4.1.3 键盘扫描信号仿真 18 4.1.4 键盘译码电路仿真 19 4.1.5 键盘扫描总体电路仿真 21 4.2引脚的锁定 22 4.3硬件验证 23 4.4本章小结 25 结  论 26 参考文献 27 附  录 28 致  谢 32 第1章 绪 论 1.1 课题的研究背景 在现代计算机与电子系统中,一般都采用通用式的标准键盘将所需的数据和指令等信息通过键盘输入到计算机和电子系统,以此来实现人机之间的接口交互。但是,在各种嵌入式系统(如微波炉、手机、电风扇等)中的键盘按键个数有限,一般为几个到十几个左右,而标准键盘则一般在一百多个左右,并且每个按键都有其各自的功能含义。所以针对每一种电子设备对其键盘进行扫描程序的设计时,必须结合工程的实际情况以及设备自身的各种资源,使所设计的键盘能够很好地融合到系统中,成为其重要的组成部分。

在数字电路中,如果将每个按键的输出信号连接到编码器对应的输入端,通过编码逻辑在编码器的输出端得到每个按键对应的键值,利用编码器实现按键键值的直接编码,这种键盘在早期称为编码键盘。但是,这类键盘有许多缺点如按键数量较多时编码逻辑的成本就会相对变高.直接编码的方法也具有很大的局限性,编码逻辑一旦固定就难以改变。现代数字电路中,一般当按键数量较多时,我们采用扫描的方式来产生键值。用矩阵的形式连接按键,使每个按键位于行、列的相交点上,通过输入扫描信号确定所按按键的行值和列值,即位置码也称扫描码,再通过查表或译码的方式将位置码转换为按键码值,采用这类方式扫描的,我们习惯称其为“非编码键盘”。在执行键盘扫描的过程中,因大多数键盘采用的都是机械开关,所以按键在闭合时往往会出现一些难以避免的机械性抖动,输出信号随之也发生跳变,其跳变宽度一般在10 ms一20 ms之间。若不对其进行处理,则系统很有可能会将其误认为多次按键。因此在系统中须设置硬件延时电路,按键输入在经过一定时间的延迟后方可读取键值,即键盘系统中常出现的去抖电路。还有一种情况是当前面按键键值还没输出但已近有新的按键按下时,后按的键值就会覆盖前面的键值,造成数据的丢失。这时可以在系统中设置一个控制信号,确保前一按键的键值输出后才允许后一键值的产生,又或设置一组寄存器来保存按键的键值,然后系统依序对其进行处理。这类扫描键盘的优点在于不需要主机担负扫描任务,而是由软件程序完成,其次也可通过更改程序来改变按键的功能定义。

基于FPGA的键盘扫描程序,由芯片中的键盘扫描程序对键盘进行扫描,按键时,系统通过时钟模块启动扫描程序,依次对每行键值赋值来扫描每行,再通过键盘每列的输出来确定按键位置,这种扫描方法被称为逐行扫描法,当有键按下时首先获得此键的列值,然后逐行扫描就可以判断按键所在的行值,由行、列的值可以得出按键的键值。此外,还需在键盘扫描程序的中加入延时程序,以消除机械键盘按键抖动所带来的影响。如果键盘的扫描频率设置过低,则在扫描显示的过程中,会出现按键显示迟缓,甚至乱码等现象。因此在实际的设计中,需根据设计要求及系统的硬件规格选择合适的扫描平率。现代数字设备中的键盘大多采用这样的键盘扫描方法 。

1.2 课题的研究意义 从计算机时代开始以来,数字系统设计就存在两个大的分类,即系统硬件设计和系统软件设计。早期的数字系统设计人员也因此被分为两个族群:硬件设计人员和软件设计人员,他们都只从事自己的工作领域,很少涉足对方的领域,尤其是软件设计人员。但是,随着数字技术和硬件系统的发展,这两个领域开始互相有所合作。在硬件描述语言HDL(Hardware Description Language)出现后,数字系统的设计已无软硬件之分。设计人员可以用HDL语言来描述系统的硬件构成及其行为,并通过仿真确定其运用到系统硬件上时是否可行,设计出符合要求的硬件系统。不仅如此,利用HDL语言来设计系统硬件同传统的硬件设计方法相比,具有其独特的优势,它为系统的硬件设计带来了深远的影响,是硬件设计领域的一次重要的变革。

传统的键盘扫描是以硬件电路来确定键盘的变化,特定的硬件电路只能应用于特定的键盘,因此它存在这样一些缺点:不能根据实际应用的改变而变化,形式固定。本文所采用的技术方案能克服上述所讲的技术缺点,该键盘扫描程序是由软件控制完成,不需要改变硬件电路,就可以适用于多种不同类型的键盘。整个系统设计是自动化过程,减少了工作量,主要把精力放在创造性的方案和概念构思上,提高了工作效率,缩短了产品的研制周期。

1.3 本文的主要工作 本设计主要是以计算机为设计平台,综合运用EDA软件工具开发环境,使用硬件描述语言VHDL,采用自顶而下的设计方法,把系统由上至下的分成几个模块设计,最后达到系统的要求,然后在Quartus II9.0上通过编程、调试、编译、仿真,从而实现键盘扫描的设计。第二章介绍了键盘扫描的基本特点和工作原理,查找有关可编程逻辑器件、VHDL语言的相关资料,掌握一定的理论知识,熟悉Quartus II软件的使用。第三章先对键盘扫描做出总体的设计方案,然后对键盘扫描进行分模块设计,再对每个模块做出详细的分析。第四章根据第三章所做的工作,对程序编译,然后进行仿真,对仿真出的结果进行详细的分析,仿真完把程序下载到实验箱上进行测试。最后对设计做出总结。

第2章 FPGA开发工具简介 2.1 FPGA概述 FPGA现在已经取代ASIC,实现其功能。通常ASIC包含三种:全定制,半定制(包括标准单元和阵列),和可编程器件。对于前面两种,您需要支付的费用项目不能重复使用的NRE,主要用于芯片流片,在分析工程开销,成本一般是10000美元以上,数以万计的。如果不成功,返工,甚至多次返工的成本,成本将上升。高成本,高风险,但通常的需求,各种ASIC的成本,NRE费用分配给每一个产品的价格太高,用户通常是不能接受的。然而可编程逻辑器件PLD是可以解决上述问题的可编程逻辑器件,是一种新型的ASIC,它有着操作灵活,易于使用,投资风险小和开发迅速的突出优势,非常适合产品的前期开发,研究样本开发或小批量的产品。FPGA是一种新型的PLD,有着PLD所具有的优点,而且其规模比一般的PLD规模要大。

FPGA主要特点有:用户不需要投片生产,就能得到合用的芯片;
FPGA可做其它全定制或半定制ASIC电路的中试样片;
其内部有丰富的触发器和I/O引脚;
是ASIC电路中设计周期最短、开发费用最低、风险最小的器件之一;

FPGA采用高速CMOS工艺,功耗低,可以与CMOS、TTL电平兼容。可以说,FPGA芯片是小批量系统提高系统集成度、可靠性的最佳选择之一。FPGA是由存放在片内RAM中的程序来设置其工作状态的,因此,工作时需要对片内的RAM进行编程。用户可以根据不同的配置模式,采用不同的编程方式。加电时,FPGA芯片将EPROM中数据读入片内编程RAM中,配置完成后,FPGA进入工作状态。掉电后,FPGA恢复成白片,内部逻辑关系消失,因此,FPGA能够反复使用。FPGA的编程无须专用的FPGA编程器,只须用通用的EPROM、PROM编程器即可。当需要修改FPGA功能时,只需换一片EPROM即可。这样,同一片FPGA,不同的编程数据,可以产生不同的电路功能。因此,FPGA的使用非常灵活 。

2.2 VHDL语言以及Quartus II应用 VHDL的英文全名是Very-High-Speed Integrated Circuit Hardware Description Language,诞生于1982 年。1987年底,VHDL被IEEE和美国国防部确认为标准硬件描述语言。

VHDL主要用于描述数字系统的结构,行为,功能和接口。除了含有许多具有硬件特征的语句外,VHDL的语言形式和描述风格与句法是十分类似于一般的计算机高级语言。VHDL的程序结构特点是将一项工程设计,或称设计实体(可以是一个元件,一个电路模块或一个系统)分成外部(或称可视部分,及端口)和内部(或称不可视部分),既涉及实体的内部功能和算法完成部分。在对一个设计实体定义了外部界面后,一旦其内部开发完成后,其他的设计就可以直接调用这个实体。这种将设计实体分成内外部分的概念是VHDL系统设计的基本点。一个完整的VHDL程序通常包括实体(Entity)、结构体(Architecture)、配置 (Configuration)、程序包集合(Package)和库(Library)5个部分。前4部分是可分别编译的源设计单元。库用来存放已经编译的实体、结构体、配置和程序包集合 。

Quartus II支持多种设计输入形式,如:原理图、VHDL、VerilogHDL以及AHDL(Altera Hardware Description Language)等,是一种综合性PLD开发软件。由于其内嵌带自有的仿真器和综合器,因而能够完成从输入设计到配置硬件的整个PLD设计流程。而且它还支持Altera的IP核和可编程系统(SOPC)在Altera的片上开发,具有LPM宏功能的模块库,用户可以使用这些成熟的功能模块,让FPGA的设计工作变得更简单。同时,Quartus II支持很多第三方的EDA工具,因而用户可以使用自己熟悉的第三方EDA工具来进行设计工作。此外,Quartus II 集合了Matlab/Simulink与DSP Builder等优秀的EDA工具,各种DSP应用系统在其平台上能够很快得以实现;
Quartus II是一个综合性的开发平台,集嵌入式软件开发、系统级设计和可编程逻辑设计于一体 。

2.3 本章小结 本章主要介绍了基于FPGA键盘扫描程序的开发工具,简单地概述了FPGA,主要讲述了FPGA的原理及FPGA的设计流程,另外还概述了VHDL语言的一些基本知识,最后简单地介绍了Quartus II软件。

第3章 基于FPGA的键盘扫描程序的设计 本次设计根据键盘扫描程序的设计思路提出了系统的整体电路框图,对硬件实体部分即本设计中4*4矩阵键盘的扫描原理和8位7段数码管的显示方式进行了简单概述,根据整体的电路构架和硬件的实现原理编写键盘扫描程序,将系统进行模块化设计,主要分为时序产生模块设计、键盘扫描模块设计、弹跳消除模块设计、键盘译码模块设计,用VHDL硬件描述语言分别编写各模块的程序,在QuartusII中为VHDL语言程序分别建立项目,在编译、仿真通过,证实逻辑功能正确后,在File菜单下选择Create/Update项中的Create Symbol Files for Current File即可为此实体生成一个后缀为.bsf的组件符号文件,以后就可以在图形编辑器中调用此组件了。用Quartus II图形编辑器将各模块联系起来,形成顶层文件即本次设计的主体。模块化的设计方法能明确设计思路,也便于调试和修改。

3.1 键盘扫描程序的总体电路设计 根据设计思路提出键盘扫描程序的总体电路设计图,如图3.1所示,主要由4*4矩阵键盘、键盘扫描电路、时序产生电路(即分频电路)、弹跳消除电路、键盘译码电路、8位7段数码管显示电路构成。整体的工作原理为,通过对系统时钟提供的频率进行分频,分别为键盘扫描电路和弹跳消除电路提供时钟信号,键盘扫描电路通过由键盘扫描时钟信号控制不断产生的键盘扫描信号对键盘进行行扫描,同时弹跳消除电路实时的对键盘的按键列信号进行采集、并将采集到的按键列信号传送到键盘译码电路进行译码,译出与之对应的键码,译出的键码将通过数码管显示电路相对应的8段7位数码管显示出来,得到最终的按键结果,完成本次设计的电路设计部分。

图3.1 键盘扫描的电路框图 3.1.1 矩阵式键盘扫描的工作原理 图3.2 4*4矩阵式键盘的面板配置 矩阵式键盘是一种常用的电子输入装置,在平常的生活中,矩阵式键盘在通信设备如手机,信息终端如计算机,家用电器如油烟机等各式电子产品上都具有很重要的作用。图3.2是一个4*4矩阵式键盘的面板配置图。

键盘上上的每个按键都是一个机械开关,当按键被按下时,则该键的电路便会输出低电平即赋值0,反之,如果没有按下按键则输出高电平即赋值1。键盘的扫描由行信号KY0—KY3控制开始进行行扫描,变化的顺序依次为1110—1101—1011—0111—1110。每一次扫描一行,依次进行循环。例如现在的行扫描信号为1011,表示目前正在扫描9、0、A、B这一行的按键,如果这行当中没有按键按下的话,则KX3—KX0输出为1111;
反之如果是9键按下,则由KX3—KX0输出为0111。

根据上面所述原理,我们可得到各按键的位置与码值的关系如表3.1和3.2所示。

表3.1 按键位置与数码的关系 KY3-KY0 1110 1110 1110 1110 1101 1101 1101 1101 KX3-KX0 0111 1011 1101 1110 0111 1011 1101 1110 按键号 1 2 3 4 5 6 7 8 表3.2 按键位置与数码的关系 KY3-KY0 1011 1011 1011 1011 0111 0111 0111 0111 KX3-KX0 0111 1011 1101 1110 0111 1011 1101 1110 按键号 9 0 A B C D E F 若从KX3—KX0读出的值皆为1时,代表该列没有按键按下,则不进行按键译码的动作,反之,如果有按键按下时,则应将KX3—KX0读出的值送至译码电路进行译码。

3.1.2 数码管的显示原理 数码管的显示数据的方式有静态显示和动态显示之分。所谓静态显示,就是将被显示的数据的BCD码通过各自的4—7/8显示译码器译码后,分别接到显示译码器的显示驱动端a—g(p),而公共端COM则根据数码管的类型(共阴/共阳)分别接GND/VCC。所谓动态显示,就是将被显示的数据的BCD码按照一定的变化频率,在不同的时刻周期性地分别送到一个数据总线上,再通过一个公共的4—7/8显示译码器译码后,接到多个显示译码的公共显示驱动端口a—g(p)上,同时,在不同的时刻周期性的选通对应的数码管的公共端口COM。

本设计采用的是共阳极数码管,采用的显示方式是静态显示,其电路中只用到一个数码管,当有键按下时,数码管将显示出对应的键码值。其主要的VHDL程序如下:
---------数码管显示程序---------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity smgxs is port(ym_in: in std_logic_vector(4 downto 0); com0: out std_logic; qout8: out std_logic_vector(7 downto 0)); end entity smgxs; architecture art of smgxs is signal qout8_s: std_logic_vector(7 downto 0); begin process(ym_in)is begin case ym_in is when “00000“=>qout8_s<=“11000000“;----0 when “00001“=>qout8_s<=“11111001“;----1 when “00010“=>qout8_s<=“10100100“;----2 when “00011“=>qout8_s<=“10110000“;----3 when “00100“=>qout8_s<=“10011001“;----4 when “00101“=>qout8_s<=“10010010“;----5 when “00110“=>qout8_s<=“10000010“;----6 when “00111“=>qout8_s<=“11111000“;----7 when “01000“=>qout8_s<=“10000000“;----8 when “01001“=>qout8_s<=“10010000“;----9 when “01010“=>qout8_s<=“10001000“;----A when “01011“=>qout8_s<=“10000000“;----B when “01100“=>qout8_s<=“11000110“;----C when “01101“=>qout8_s<=“11000000“;----D when “01110“=>qout8_s<=“10000110“;----E when “01111“=>qout8_s<=“10001110“;----F when others=>qout8_s<=“11111111“; end case; end process; qout8<=qout8_s; com0<='1'; end architecture art; 3.2 键盘扫描电路各主要功能模块的设计 3.2.1 时序产生模块 本时序产生模块中使用了二种不同频率的工作脉冲波形,通过对系统时钟脉冲进行分频得到键盘扫描模块和键盘去抖模块的时钟信号。

当系统需要使用多种操作频率的时钟脉冲时,较为直接和简便的方法就是用一个自由计数器自由累加得到所需的各种频率。也就是建立一个N位计数器,N的大小根据电路的需求决定,N的值越大,电路可以分频的次数就越多,这样就可以获得更多的频率变化,以便提供多种不同频率的时钟信号。若输入时钟为CLK,N位计数器的输出为Q[N-1.0],则Q(0)为CLK的2分频脉冲信号,Q(1)为CLK的4分频脉冲信号,Q(2)为CLK的8分频脉冲信号……Q(N-1)为CLK的2N 分频脉冲信号。我们利用以上规律即可得到我们所需要频率的信号或信号序列。时序产生模块模块电路图如图3.4所示。xd_clk输出信号和ym_clk输出信号分别为系统时钟clk的8分频和2分频,其中xd_clk信号用作弹跳消除取样电路的时钟信号,ym_out信号用作键盘扫描电路的时钟信号。时序产生模块原理图如图3.3所示。

图3.3 时序产生模块 时序产生模块VHDL描述如下:
--------------扫描时钟产生程序------------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; use ieee.std_logic_arith.all; entity smsz is port(clk: in std_logic; ym_clk: out std_logic; xd_clk: out std_logic); end entity smsz; architecture art of smsz is signal clk_s: std_logic_vector(3 downto 0); begin process(clk)is begin if(clk'event and clk='1')then -----------上升沿 if(clk_s=“1111“)then clk_s<=“0000“; else clk_s<=clk_s+1; -----------计数器分频 end if; end if; end process; ym_clk<=clk_s(0); xd_clk<=clk_s(2); end architecture art; 3.2.2 键盘扫描模块 键盘扫描模块的主要功能是为键盘提供扫描信号(表3.1中的行扫描信号KY0—KY3),行扫描信号由时钟控制按照顺序依次被赋值1110—1101—1011—0111。扫描时从KY0-KY3分别扫描四行按键,将行扫描信号赋值0111时即可对KY0这一行按键进行扫描;
将扫描信号赋值1011时则扫描KY1这一行按键;
将扫描信号赋值1101时扫描KY2这一行按键;
将扫描信号赋值1110时,检测KY3这一行的按键情况。通过行扫描信号的循环依次检查每一行是否有键按下,如果这行有按键按下则立刻进行对按键编码进行译码,且将译码的结果传送到数码管。键盘扫描模块模块图如图3.4所示。

图3.4 键盘扫描模块 键盘扫描模块VHDL描述如下:
------------扫描信号产生程序---------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; entity smxh is port(clk: in std_logic; q_out: out std_logic_vector(1 downto 0); sm_out: out std_logic_vector(3 downto 0)); end entity smxh; architecture art of smxh is signal sm_s: std_logic_vector(3 downto 0); signal q_s: std_logic_vector(1 downto 0); begin process(clk)is begin if(clk'event and clk='1')then if(q_s=“11“)then q_s<=“00“; else q_s<=q_s+1; end if; end if; end process; process(q_s)is begin case q_s is when “00“=>sm_s<=“1110“; ---------输出扫描信号为1110 when “01“=>sm_s<=“1101“; ---------输出扫描信号为1101 when “10“=>sm_s<=“1011“; ---------输出扫描信号为1011 when “11“=>sm_s<=“0111“; ----------输出扫描信号为0111 when others=>sm_s<=“1111“; end case; end process; sm_out<=sm_s; q_out<=q_s; end architecture art; 3.2.3 弹跳消除模块 由于本设计中的4*4矩阵键盘用的是机械开关,因此在按键按下的时刻会在触片上出现信号来回弹跳的现象,因为这种弹跳现象很可能会造成乱码现象,从而影响到按键结果的正确显示。

图3.5为弹跳现象造成的错误的抽样结果,从中可以看出虽然是只按键一次然后就马上松开,然而实际的按键信号却已跃变多次,通过取样信号的检查,就很有可能输出错误的编码。

图3.5 弹跳现象产生错误的抽样结果 如果调整抽样频率(如图3.6所示),可以发现弹跳现象获得了改善。

图3.6 调整抽样频率后得到的抽样结果 因此为系统加上此模块,能有效避免乱码现象的发生。另外,系统中弹跳消除模块的脉冲信号频率必须高于其他模块中的脉冲信号频率;
一般情况下,扫描模块的工作频率为24Hz左右,而弹跳消除模块的工作频率则必须为128Hz左右,后者的工作频率要高于前者。

图3.7 弹跳消除电路的内部实现原理图 弹跳消除电路的实现原理如图3.7所示,按下按键时键盘的输入信号为D_IN,CLK为此模块的时钟信号,也就是抽样信号,将D_IN通过两个D触发器延时后再用RS触发器处理。

RS触发器的前端连接和非门原理:
(1)通常人的按键速度维持在10次/秒左右,也就是说每次按键的时间在100ms左右,所以按下的时间可估算为50ms,以取样信号CLK的周期为8ms计,则可以取样到6次。

(2)对于不稳定的噪声,在4ms以下则至多抽样一次。

(3)在触发器之前,接上AND-NOT之后,SR的组态如表3.3所示。

表3.3 RS触发器真值表 S R D_OUT 0 0 不变 1 0 1 0 1 0 (1)D0为1,且D1也为1时,结果S=1,R=0,D_OUT才会输出1。这代表被取样的D_IN信号能被连续取样到两次1,此时认定它已经稳定地按下按钮。

(2)D0为0,且D1也为0时,结果S=0,R=1,D_OUT才会输出0。这代表被取样的D_IN信号能被连续取样到两次0,此时认定它已经稳定地放掉按钮。

(3)D0为1,且D1也为0时,结果S=0,R=0,D_OUT将维持先前的输出信号不变。D0=0,D1=1也是如此。

总之,必须取样到两次1才会输出1,两次0才会输出0.最后,由于D_OUT的信号输出时间宽度过长,所以输出必须再接一级微分电路后,才接到译码电路。

弹跳消除模块的VHDL描述如下:
--------D触发器程序--------- library ieee; use ieee.std_logic_1164.all; entity dcfq is port(clk,d: in std_logic; q: out std_logic); end entity dcfq; architecture art of dcfq is begin process(clk) begin if clk'event and clk='1' then ---------上升沿 q<=d; end if; end process; end architecture art; ----------SR触发器-------- library ieee; use ieee.std_logic_1164.all; entity srcfq is port(r,s: in std_logic; q,qb: out std_logic); end entity srcfq; architecture art of srcfq is signal q_s,qb_s: std_logic; begin process(r,s)is begin if(r='0' and s='1')then ----------RS触发器输出置‘1’ q_s<='1'; qb_s<='0'; elsif(r='1' and s='0')then -----------RS触发器输出置‘0’ q_s<='0'; qb_s<='1'; elsif(r='0' and s='0')then ------------RS触发器输出保存不变 q_s<=q_s; qb_s<=qb_s; end if; q<=q_s; qb<=qb_s; end process; end architecture art; 3.2.4 键盘译码电路 键盘译码电路的主要工作原理是:首先根据输入的键盘信号判断是否有键盘按下再,如果有键盘按下,将根据输入的键盘信号和扫描信号进行查表,根据查表可直接得出相应的键盘的译码值。

矩阵式键盘中每个按键的键值参照下表(表3.4键盘参数表)。

表3.4 键盘参数表 扫描位置 KY3-KY0 键盘输出 KX3-KX0 相对应的 键盘按键 键盘译码 电路输出 1110 0111 1 0001 1011 2 0010 1101 3 0011 1110 4 0100 1101 0111 5 0101 1011 6 0110 1101 7 0111 1110 8 1000 1011 0111 9 1001 1011 0 0000 1101 A 1010 1110 B 1011 0111 0111 C 1100 1011 D 1101 1101 E 1110 1110 F 1111 键盘译码模块模块原理图如图3.8所示。

图3.8 键盘译码模块 键盘译码模块VHDL描述如下:
---------译码电路程序---------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; use ieee.std_logic_arith.all; entity ymdl is port(clk: in std_logic; sm_in: in std_logic_vector(1 downto 0); jm_in: in std_logic_vector(3 downto 0); ym_out: out std_logic_vector(3 downto 0)); end entity ymdl; architecture art of ymdl is signal jm_s: std_logic_vector(5 downto 0); signal ym_s: std_logic_vector(3 downto 0); begin process(clk)is begin jm_s<=sm_in & jm_in; if(clk'event and clk='1')then case jm_s is when “000111“=>ym_s<=“0001“; ------译码值1 when “001011“=>ym_s<=“0010“; ------译码值2 when “001101“=>ym_s<=“0011“; ------译码值3 when “001110“=>ym_s<=“0100“; ------译码值4 when “010111“=>ym_s<=“0101“; ------译码值5 when “011011“=>ym_s<=“0110“; ------译码值6 when “011101“=>ym_s<=“0111“; ------译码值7 when “011110“=>ym_s<=“1000“; ------译码值8 when “100111“=>ym_s<=“1001“; ------译码值9 when “101011“=>ym_s<=“0000“; ------译码值0 when “101101“=>ym_s<=“1010“; ------译码值A when “101110“=>ym_s<=“1011“; ------译码值B when “110111“=>ym_s<=“1100“; ------译码值C when “111011“=>ym_s<=“1101“; ------译码值D when “111101“=>ym_s<=“1110“; ------译码值E when “111110“=>ym_s<=“1111“; -------译码值F when others=>ym_s<=“XXXX“; end case; end if; end process; ym_out<=ym_s; end architecture art; 3.2.5 键盘扫描程序的顶层文件设计 设计好各个模块后,要使其相互联系起来要通过QUARTUS II的图形编辑器将各个模块按照一定的关系建立顶层文件jpsm.bdf,通过连线将各模块整合后,整体电路用VHDL实现的总体的模块电路图如图3.9所示:
图3.9 键盘扫描程序的顶层文件图 3.3本章小结 本章首先是根据课题任务书和所查找的资料,给出本次设计的整体电路设计方案。然后对硬件部分如4*4矩阵键盘和8段7位数码管的原理进行阐述,再对键盘扫描程序的主要模块(时序产生模块、键盘扫描模块、弹跳消除模块、键盘译码模块)分别进行设计,将这几个模块进行编程和生成电路元件,并对其进行详细地分析。最后根据自己的设计思路,将各模块的电路元件进行整合生成键盘扫描程序的顶层文件。

第4章 键盘扫描程序的波形仿真及硬件验证 系统采用ALTERA公司的软件Quartus II9.0软件进行编译及仿真,硬件部分利用Creat-SOPC2000实验箱上的时钟频率源、4*4矩阵键盘、8位7段数码管、EP1C20F324C8芯片模块搭建电路进行硬件验证。Quartus II支持多种设计输入形式,如:原理图、VHDL、VerilogHDL以及AHDL(Altera Hardware Description Language)等,是一种综合性PLD开发软件。由于其内嵌带自有的仿真器和综合器,因而能够完成从输入设计到配置硬件的整个PLD设计流程。而且它还支持Altera的IP核和可编程系统(SOPC)在Altera的片上开发,具有LPM宏功能的模块库,用户可以使用这些成熟的功能模块,让FPGA的设计工作变得更简单。同时,Quartus II支持很多第三方的EDA工具,因而用户可以使用自己熟悉的第三方EDA工具来进行设计工作。此外,Quartus II 集合了Matlab/Simulink与DSP Builder等优秀的EDA工具,各种DSP应用系统在其平台上能够很快得以实现;
Quartus II是一个综合性的开发平台,集嵌入式软件开发、系统级设计和可编程逻辑设计于一体。

4.1 系统仿真 在软件Quartus II9.0上对程序进行编译,编译后进行波形仿真。为了方便观察显示结果,这里调节仿真时间为1s ,脉冲频率clk的周期为10ms,保存之后,对各模块的VWF文件执行Quartus软件中的processing--> start simulation选项,就可以生产各个模块的波形仿真图像,观察并分析其结果是否与设计方案中的设计思路一致。

4.1.1 消抖电路仿真 键盘的按键闭合与释放瞬间,输入信号会有按键抖动问题出现。如果不进行消抖处理,系统会将这些按键抖动误以为是用户的另一次输入,导致系统的误操作,出现乱码。

图4.1为键盘输入去抖电路的仿真结果图,图中的输出信号为Q_OUT、QB_OUT,由图上可以看出,输出信号Q_OUT的信号跃变比输入信号D_IN拖后两个时钟周期,即必须连续两次采样检测到信号变化系统才会对其做出反应,否则电路将其视为噪声,不予理会,原来的弹跳现象经过键盘输入去抖电路处理后已经得到解决。

图4.1 键盘输入去抖电路的仿真图 4.1.2 键盘时钟信号仿真 键盘的时钟信号由系统时钟提供的频率进行分频得到,图4.1为键盘各电路提供时钟信号的仿真结果图,图中的输出信号为clk_out[3..0],由图上可以看出,clk_out(0)为clk时钟信号的2分频信号,clk_out(1)为clk时钟信号的4分频信号,clk_out(2)为clk时钟信号的8分频信号,clk_out(3)为clk时钟信号的16分频信号。其中clk_out(0)分别为译码电路、扫描信号产生电路提供时钟,其中clk_out(2)为去抖电路提供时钟。

图4.2 键盘各时钟信号的仿真图 4.1.3 键盘扫描信号仿真 图4.3为键盘扫描信号产生电路的仿真结果,图中的输入为clk,输出为sm_out[3..0]、q_out[1..0],由图上可以看出q_out的值和sm_out的值与图3.2上扫描信号的所标示的完全一致,其中sm_out为键盘的扫描信号,q_out为译码电路提供相应的扫描值,观察仿真结果可知q_out的值和sm_out的值与图3.2上所标示的键盘行信号和对应的译码值完全一致。

图4.3 键盘扫描信号的仿真图 4.1.4 键盘译码电路仿真 图4.4、图4.5、图4.6、图4.7为键盘译码电路的仿真结果,图中的输入信号为clk、jm_in[3..0]、sm_in[1..0]、输出为ym_out[3..0],由图上可以看出当扫描信号分别为0111、1011、1101、1110时,输出的译码值ym_out,与输入的sm_in的值与表3.4中完全符合。

图4.4 扫描信号为0111时键盘译码电路的仿真图 图4.5 扫描信号为1011时键盘译码电路的仿真图 图4.6 扫描信号为1101时键盘译码电路的仿真图 图4.7 扫描信号为1110时键盘译码电路的仿真图 4.1.5 键盘扫描总体电路仿真 图4.8、图4.9、图4.10、图4.11为键盘扫描总体电路的仿真结果,图中的输入信号为clk、jm0、jm1、jm2、jm3,输出信号为smxh[3..0]、ymxh[3..0],由各图可以看出当键盘输出的键码分别为1110、1101、1011、0111时。扫描信号smxh,译码结果ymxh与表3.4完全符合。

图4.8 当键盘输出为1110时键盘扫描总体电路的仿真图 图4.9 当键盘输出为1101时键盘扫描总体电路的仿真图 图4.10 当键盘输出为1011时键盘扫描总体电路的仿真图 图4.11 当键盘输出为0111时键盘扫描总体电路的仿真图 4.2引脚的锁定 本次设计在Creat-SOPC2000 实验箱上实现,由Cyclone系列EP1C20F324C8芯片完成,对照实验箱的电路原理图上的元件符号及实验室芯片的引进列表可查出系统设计中各信号的对应引脚。仿真后,选择Assignments -> Assignments Editor,在Assignments Editor窗口中选择 Pin 标签页,对照芯片EP1C20F324C8的引脚列表及原理图中的元件符号进行引脚锁定,最终的引脚锁定如图4.12所示:
图4.12 引脚锁定列表 4.3硬件验证 用VHDL语言编写的源程序在QuartusⅡ软件上完成编译测试,波形仿真以及对所用芯片EP1C20F324C8进行引脚锁定后,需进行下载验证。将重新编译完成后形成可配置到FPGA的 jpsm.sof 文件下载到Create-SOPC2000实验系统及SOPC 开发板上,本次设计用到实验箱上的时钟产生模块,芯片模块,数码管显示模块及4*4矩阵键盘。用跳线将时钟模块连接到芯片模块上,下载完成后即可按键进行测试,观察是否解决按键抖动问题及数码管能否正常显示按键键值。

按键观察实验箱上数码管的显示结果,得到数码管显示图(图4.13、图4.14、图4.15),从图中可以看出,数码管能正常显示4*4键盘16个按键(0-9,A-F)的结果,并且在采用了合适的扫描频率后,按键结果的显示迅速且无延迟。在采用了按键消抖模块后,不会出现乱码问题,符合设计要求,完成了本次毕业设计任务。

本设计采用一个8位7段数码管对键盘上的A-F字母键进行数字显示,将程序下载到试验箱上并按下键盘A键,F键及5键后,实验箱显示结果如图4.13、图4.14、图4.15所示 图4.13 A键显示结果图 图4.14 F键显示结果图 图4.15 5键显示结果图 4.4本章小结 本章主要是对系统的组成部分如去抖电路,键盘时钟信号,键盘扫描电路,键盘译码电路进行波形仿真,通过对波形仿真图的分析,来检测本次设计各模块的逻辑功能是否都已实现。最后进行引脚锁定,将源程序下载到实验箱,进行硬件验证。

结 论 本设计主要是以计算机为工作平台,综合运用EDA软件工具开发环境,使用硬件描述语言VHDL,采用自顶向下的设计方法,把系统由上到下的分成几个模块设计,最后达到系统预期要求,然后在Quartus II9.0上通过编程、调试、编译、仿真,从而实现键盘扫描程序的设计。

本论文对键盘扫描程序的原理、系统结构、设计方法进行了研究,取得了如下成果:
(1) 概述了课题的研究背景、课题研究的意义及本文的主要工作。

(2) 概述了FPGA及其设计流程,对VHDL语言和Quartus II软件的应用进行了简单的介绍。

(3) 根据本次设计的课题任务书以及所查找的资料,给出了键盘扫描程序的总体设计方案,并设计出了四个主要模块(时序产生模块、键盘扫描模块、弹跳消除模块键盘译码模块)。

(4) 使用Quartus软件对编译后的程序进行仿真,然后使用Create-SOPC2000实验系统及SOPC 开发板,对键盘扫描系统进行硬件测试和验证。

该系统具有集成度高、稳定性好、设计灵活和设计效率高等优点。虽然本次设计实现了了键盘扫描及显示功能,但是由于时间和水平的有限,有些地方还有待改进,例如多位数据的扫描显示,键盘扫描LED点阵显示等。

参考文献 [1] 李君,胡胜.一种新型的键盘扫描方式[J].控制工程, 2004(S1):125-148. [2] 杜道山,白荣华.伺服控制系统键盘扫描程序的处理[J].机床与液压, 2005(01). [3] 吴淑芸.定时中断扫描键盘与显示器的程序设计[J].自动化仪表, 1994(01). [4] 李小亮,蒋华勤,董雪峰.基于FPGA的可键盘控制计数电路的设计与实现[J].电子设计工程,2011(8):154-156. [5] 王美丽.用FPGA设计和制造键盘扫描[J].仪表技术,2008(10):47-49. [6] 张玲.基于FPGA4*4键盘扫描电路设计[J],计算机软件与光盘应用,2012(13):181-182. [7] 袁文波.FPGA应用开发从实践到提高[M].中国电力出版社,2007:78. [8] 褚振勇.FPGA设计及应用[M].西安电子科技大学出版社,2002:61-68. [9] 周润景.基于QuartusII的FPGA/CPLD数字系统设计实例[M].电子工业出版社,2007:98-104. [10] 胡振华.VHDL与FPGA设计[M].中国铁道出版社,2003:51-53. [11] 樊国梁,张晓燕.基于VHDL的键盘扫描及显示电路设计[J].电子世界,2005(02). [12] 包明.EDA技术与可编程逻辑器件应用[M].北京邮电大学出版社,2006. [13] 尹唱唱,卫阿盈.基于QuartusⅡ的数字电路设计研究[J].中国科技信息,2009(21):75. [14] 王艳玲.QuartusⅡ应用于数字电路教学的研究[J].中国科技信息,2009(02):41-47. [15] 程继航,黄飞,石静苑.QuartusⅡ在EDA技术中的应用[J].电脑编程技巧及维护,2009(S1). 附 录 程序:
--------D触发器程序--------- library ieee; use ieee.std_logic_1164.all; entity dcfq is port(clk,d: in std_logic; q: out std_logic); end entity dcfq; architecture art of dcfq is begin process(clk) begin if clk'event and clk='1' then ---------上升沿 q<=d; end if; end process; end architecture art; ----------SR触发器-------- library ieee; use ieee.std_logic_1164.all; entity srcfq is port(r,s: in std_logic; q,qb: out std_logic); end entity srcfq; architecture art of srcfq is signal q_s,qb_s: std_logic; begin process(r,s)is begin if(r='0' and s='1')then ----------RS触发器输出置‘1’ q_s<='1'; qb_s<='0'; elsif(r='1' and s='0')then -----------RS触发器输出置‘0’ q_s<='0'; qb_s<='1'; elsif(r='0' and s='0')then ------------RS触发器输出保存不变 q_s<=q_s; qb_s<=qb_s; end if; q<=q_s; qb<=qb_s; end process; end architecture art; ---------译码电路程序---------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; use ieee.std_logic_arith.all; entity ymdl is port(clk: in std_logic; sm_in: in std_logic_vector(1 downto 0); jm_in: in std_logic_vector(3 downto 0); ym_out: out std_logic_vector(3 downto 0)); end entity ymdl; architecture art of ymdl is signal jm_s: std_logic_vector(5 downto 0); signal ym_s: std_logic_vector(3 downto 0); begin process(clk)is begin jm_s<=sm_in & jm_in; if(clk'event and clk='1')then case jm_s is when “000111“=>ym_s<=“0001“; ------译码值1 when “001011“=>ym_s<=“0010“; ------译码值2 when “001101“=>ym_s<=“0011“; ------译码值3 when “001110“=>ym_s<=“0100“; ------译码值4 when “010111“=>ym_s<=“0101“; ------译码值5 when “011011“=>ym_s<=“0110“; ------译码值6 when “011101“=>ym_s<=“0111“; ------译码值7 when “011110“=>ym_s<=“1000“; ------译码值8 when “100111“=>ym_s<=“1001“; ------译码值9 when “101011“=>ym_s<=“0000“; ------译码值0 when “101101“=>ym_s<=“1010“; ------译码值A when “101110“=>ym_s<=“1011“; ------译码值B when “110111“=>ym_s<=“1100“; ------译码值C when “111011“=>ym_s<=“1101“; ------译码值D when “111101“=>ym_s<=“1110“; ------译码值E when “111110“=>ym_s<=“1111“; -------译码值F when others=>ym_s<=“XXXX“; end case; end if; end process; ym_out<=ym_s; end architecture art; ------------扫描信号产生程序---------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; entity smxh is port(clk: in std_logic; q_out: out std_logic_vector(1 downto 0); sm_out: out std_logic_vector(3 downto 0)); end entity smxh; architecture art of smxh is signal sm_s: std_logic_vector(3 downto 0); signal q_s: std_logic_vector(1 downto 0); begin process(clk)is begin if(clk'event and clk='1')then if(q_s=“11“)then q_s<=“00“; else q_s<=q_s+1; end if; end if; end process; process(q_s)is begin case q_s is when “00“=>sm_s<=“1110“; ---------输出扫描信号为1110 when “01“=>sm_s<=“1101“; ---------输出扫描信号为1101 when “10“=>sm_s<=“1011“; ---------输出扫描信号为1011 when “11“=>sm_s<=“0111“; ----------输出扫描信号为0111 when others=>sm_s<=“1111“; end case; end process; sm_out<=sm_s; q_out<=q_s; end architecture art; --------------扫描时钟产生程序------------- library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; use ieee.std_logic_arith.all; entity smsz is port(clk: in std_logic; clk_out: out std_logic_vector(3 downto 0)); end entity smsz; architecture art of smsz is signal clk_s: std_logic_vector(3 downto 0); begin process(clk)is begin if(clk'event and clk='1')then if(clk_s=“1111“)then clk_s<=“0000“; else clk_s<=clk_s+1; ---------计数器分频 end if; end if; end process; clk_out<=clk_s; end architecture art; 致 谢 学生签名:
日 期:

Tags:

搜索
网站分类
标签列表