基于FPGA的键盘扫描程序的设计
扫描矩阵键盘简介以及其FPGA设计思路
扫描键盘的设计思想和代码技巧非常值得学习。
首先扫描键盘可以节省FPGA 的引脚资源,例如一个4x4的扫描键盘有16个按键,如果不用扫描方式而是直接把16跟控制线接入FPGA ,就要16个引脚,而用扫描方式只需要4+4=8个引脚。
尤其是随着键盘的增大,比如8x9=72的键盘,用扫描方式只需要17个引脚。
要想了解扫描键盘的原理,首先要知道矩阵键盘的电路结构。
如上图所示,矩阵键盘的某一个按钮按下会使对应的一条行线和列线导通,为了便于分析扫描过程做如下简化:3.3v Row0Row1 Row2Row3 Col 0 Col 1 Col 2 Col 3Row0Row1Row2Row3Col 0 Col 1 Col 2 Col 33 5 A E D C 2 B 9 8 F4 6 0 1 7 接高电平 由FPGA 输出给键盘高低电平的组合,即是扫描码键盘行线高低电平的变化输入给FPGA扫描键盘的工作状态分为两种:第一种状态是判断是否有键按下,该状态下四根列线对应的电平状态是{col 0,col 1,col 2,col 3}=0000 。
四根行线左端都接高电平,没有键被按下时,四根行线右端的状态是{row0,row1,row2,row3}=1111 。
假如上图中按键3被按下了,也就是说row0和col 0接通了。
那么四根行线右端的状态将会是{row0,row1,row2,row3}=0111 。
也就是说,在第一种状态下,只要键盘行线输入FPGA的状态不是1111,就说明有键被按下了。
马上进入第二状态。
第二种状态是判断具体哪个键被按下了。
该状态下四根行线左端接高电平不变,四根列线对应的电平状态不断变化,由FPGA的输出的扫描码控制四根列线的电平状态。
由第一状态的行线输入已经可以确定按键所处的行了。
接下来只要再确定按键所处的列就可以确定到底哪个键被按下了。
如何根据行线的输入确定按键所处的列,奥妙就在于扫描码了。
让列线以1000、0100、0010、0001的电平状态不断循环。
键盘扫描及计算器VHDL仿真
简易计算器设计——EDA实验报告一、实验内容实验要求:完成个位数的加减乘运算,输入用矩阵键盘,输出用数码管显示,每输入一次数据要显示在数码管上。
矩阵键盘共16个按键,用其中10个做个位数的输入,用3个分别做加减乘运算,用其中1个做等于操作,各位数的运算结果最多两位,用动态扫描数码管显示运算结果。
二、小组成员三、实现方法系统组成及连接原理如图所示,主要由由七个功能模块组成:分频模块(为键盘扫描模块和防抖模块提供时钟)、键盘扫描驱动模块(依次置零)、键盘按键值编码模块、键盘编码值防抖模块、运算模块,数码管显示驱动模块、动态扫描驱动模块。
1.分频模块由于FPGA实验板的原始时钟频率高达33.8688MHz,所以不能直接接入设计模块中使用,就需要用到分频模块。
将33.8688MHz分频到4KHz和10Hz来使用,一个用于行驱动扫描时钟,一个用于防抖模块。
所以,采用写一个可变分频元件来调用。
元件视图:主要代码如下(完整代码见附录,下同):architecture RTL of freq_division iscomponent fredivn isgeneric(n:positive);Port ( clkin:in STD_LOGIC;clkout:out STD_LOGIC);end component;beginU1:fredivngeneric map(n=>3)port map(clkin=>clk,clkout=>clkout_kb);end RTL;仿真结果如下图:达到预期的目的2.行驱动模块(依次对行置零):键盘扫描的原理就是检测行列信号然后判断出具体是按下了哪一个按键。
所以,对行依次置零,当置零频率较快时,按下某一个按键后,一定能得到某一列的信号输出为零,如下图:当行信号为1110时,若按下了0键,就会得到1110的列信号,立马就快可以译码出按键值,若按下4键、8键、C键则都不会有输出。
非编码键盘的扫描程序设计
计算机控制技术课程设计是在教学及实验基础上,对课程所学理论知识的深化和提高。
本次课程设的内容是利用8031微控制器,通过8155扩展I/O口行列式键盘。
要求通过8155扩展I/O口组成4×8行列式键盘,设计非编码键盘的扫描系统,并且能够对键盘的按键正确识别,去抖动。
关键词:8155 非编码去抖1 课程设计目的 (1)2 非编码键盘 (2)3 芯片介绍 (3)3.1 8031芯片介绍 (3)3.2 8155芯片介绍 (5)4 电路设计 (7)5 程序设计 (8)6 电路仿真 (12)7 心得体会 (17)附录程序清单 (18)参考文献 (21)非编码键盘的扫描程序设计1 课程设计目的(1)了解并掌握非编码键盘的工作原理;(2)熟悉和掌握8155与8031的结构及工作原理;(3)通过课程设计,掌握电路设计的基本方法和技术;(4)掌握单片机的接口技术及相关外围芯片的外特性,控制方法,从而加深对计算机控制技术知识的理解;(5)通过实际程序设计和调试,逐步掌握模块化程序设计方法和调试技术。
2 非编码键盘键盘可以分为编码式和非编码式两种。
编码式键盘是通过数字电路直接产生对应于按键的ASCⅡ码,这种方式目前很少使用。
非编码式键盘将案件排列成矩阵的形势,由硬件或软件随时对矩阵扫描,一旦某一键被按下,该键的行列信息即被转换为位置码并送入主机,再由键盘驱动程序查表,从而得到按键的ASCⅡ码,最后送入内存中的键盘缓冲区供主机分析执行。
非编码式键盘由于结构简单,按键重定义方便而成为目前最常采用的键盘类型。
由此,多姿多彩的多媒体键盘便应运而生,这些键盘通常出现在品牌机上,如联想、同方等,品牌机上的“单键上网”也是基于此原理。
非编码键盘又分为:独立键盘和行列式(又称为矩阵式)键盘。
本次课程设计要求设计的是4×8行列式键盘。
3 芯片介绍3.1 8031芯片介绍8031和8051一样是最常见的MCS51系列单片机,是inter公司早期的成熟的单片机产品,应用范围涉及到各行各业。
使用可编程逻辑器件实现矩阵键盘扫描模块的设计
使用可编程逻辑器件实现矩阵键盘扫描模块的设计给出了CPLD 部分模块的VHDL 语言实现和仿真波形。
在矩阵键盘的扫描、编码、输出完全不需CPU 控制的前提下,实现标准键盘和矩阵键盘双键盘同时使用。
在基于PC104 的便携式野外测试设备的设计中,键盘是常用的输入设备。
对于便携式设备野外工作时,一般使用小型(4×4)矩阵键盘就能满足设备的信息输入需要;室内调试时,使用标准PS2 键盘更方便、灵活。
一般的做法是保留PC104 的键盘接口用于接标准键盘,利用扩展I/O接口完成小矩阵键盘的扫描和输入。
这样做虽然可以实现设备双键盘同时工作的功能,却需耗费大量的CPU 处理时间扫描矩阵键盘,造成CPU 处理其他信息的能力下降。
而本文设计的基于CPLD 的矩阵键盘扫描模块能够很好地解决上述问题。
1 矩阵键盘扫描原理图1 给出了4×4 矩阵键盘的电路图,在图1 中KX[3..0]为扫描码输入,KY[3..0]为扫描码输出。
键盘扫描开始时,首先置KX[3..0]=“0000”;键盘扫描码寄存器和键盘扫描码缓存器Kreg[15..0]和Kscan[15..0]置成“1111111111111111”(全1为没有键按下,有键按下时至少有一位为0),一旦有键按下,KY[3..0]输出不全为“0”的扫描码触发键盘扫描功能开始键盘扫描,扫描开始后,依次将KX3、KX2、KX1、KX0 置“0”,分别将对应的4 组KY[3..0]输入值保存于Kscan[15..12]、Kscan[11..8] 、Kscan[7..4] 、Kscan[3..0]中,而后比较Kscan 和Kreg 的大小,如果Kscan 小于Kreg,将Kscan 保存于Kreg 中,重复上述扫描过程直到Kscan[15..0]各位输出全为“1”时,说明按下的键全部抬起,Kreg[15..0]中的每一个为“0”的位对应一个按下的键,保留扫描过程中的Kreg 最小值就可以处理组合键。
04陈阳 基于VHDL的键盘扫描及显示电路.
课程设计(论文)题目名称基于VHDL的键盘扫描及显示电路课程名称专业课程设计III学生姓名陈阳学号1041301004系、专业信息工程系、电子信息工程指导教师王少杰2013年11月05日运VHDL硬件描述语言和图形设计综合方法,实现了4×4键盘扫描电路的程序设计,通过运用QuartusⅡ软件平台生成电路符号,建立波形文件,设置输入端口,实现模拟仿真,得到仿真波形图。
FPGA/ CPLD 在数字系统设计中的广泛应用,影响到了生产生活的各个方面。
在FPGA/ CPLD 的设计开发中,VHDL 语言作为一种主流的硬件描述语言,具有设计效率高, 可靠性好, 易读易懂等诸多优点。
作为一种功能强大的FPGA/ CPLD 数字系统开发环境,Altera 公司推出的Quart us Ⅱ,为设计者提供了一种与结构无关的设计环境,使设计者能方便地进行设计输入、快速处理和器件编程,为使用V HDL 语言进行FPGA/ CPLD 设计提供了极大的便利。
矩阵键盘作为一种常用的数据输入设备,在各种电子设备上有着广泛的应用,通过7 段数码管将按键数值进行显示也是一种常用的数据显示方式。
在设计机械式矩阵键盘控制电路时,按键防抖和按键数据的译码显示是两个重要方面。
关键字:VHDL QuartusⅡ;数码管;FPGA/ CPLD;译码器摘要 (I)第2章方案设计 (1)1.1 题目分析 (1)2.2 矩阵键盘及显示电路设计路 (1)2.3 EDA技术的基本特征 (1)第3章电路设计 (2)2.1矩阵键盘及显示电路的实现 (2)2.2矩阵键盘及显示电路的电路符号 (2)2.3数码管显示译码模块设计 (2)第4章程序设计 (4)3.1键盘扫描模块程序、原理图及仿真波形 (4)3.2整体电路程序 (9)第5章仿真及结果 (11)第6章结束语 (12)参考文献......................................... . (13)第1章前言1.1EDA技术的介绍EDA是Electronic Design Automation的缩写,中文译为电子设计自动化,是现代电子设计技术的有力工具。
单片机实验--键盘扫描
实验4 键盘实验一、实验目的:1.掌握8255A编程原理。
2.了解键盘电路的工作原理。
3.掌握键盘接口电路的编程方法。
二、实验设备:CPU挂箱、8031CPU模块三、实验原理:1.识别键的闭合,通常采用行扫描法和行反转法。
行扫描法是使键盘上某一行线为低电平,而其余行接高电平,然后读取列值,如所读列值中某位为低电平,表明有键按下,否则扫描下一行,直到扫完所有行。
本实验例程采用的是行反转法。
行反转法识别键闭合时,要将行线接一并行口,先让它工作于输出方式,将列线也接到一个并行口,先让它工作于输入方式,程序使CPU通过输出端口往各行线上全部送低电平,然后读入列线值,如此时有某键被按下,则必定会使某一列线值为0。
然后,程序对两个并行端口进行方式设置,使行线工作于输入方式,列线工作于输出方式,并将刚才读得的列线值从列线所接的并行端口输出,再读取行线上的输入值,那么,在闭合键所在的行线上的值必定为0。
这样,当一个键被按下时,必定可以读得一对唯一的行线值和列线值。
2.程序设计时,要学会灵活地对8255A的各端口进行方式设置。
3.程序设计时,可将各键对应的键值(行线值、列线值)放在一个表中,将要显示的0~F字符放在另一个表中,通过查表来确定按下的是哪一个键并正确显示出来。
实验题目利用实验箱上的8255A可编程并行接口芯片和矩阵键盘,编写程序,做到在键盘上每按一个数字键(0~F),用发光二极管将该代码显示出来。
四、实验步骤:将键盘RL10~RL17接8255A的PB0~PB7;KA10~KA12接8255A的PA0~PA2;PC0~PC7接发光二极管的L1~L8;8255A芯片的片选信号8255CS接CS0。
五、实验电路:六、程序框图7.程序清单八、附:8251/8255扩展模块该模块由8251可编程串行口电路和8255可编程并行口电路两部分组成,其电源、数据总线、地址总线和片选信号均由接口挂箱上的接口插座提供。
一、8251可编程串行口电路(1)8251可编程串行接口芯片引脚及功能8251A是通用同步/异步收发器USART,适合作异步起止式数据格式和同步面向字符数据格式的接口,其功能很强。
基于FPGA的键盘扫描模块的设计与实现
●主题论文1概述1.1通用键盘和专用键盘[1]在现代个人计算机系统中,一般都采用通用的标准键盘(如:标准101/102键盘或Microsoft自然PS/2键盘)来实现人与计算机之间的接口交互,所需要的各种数据和指令等信息都通过键盘来输入计算机。
但是,在各种嵌入式系统(如手机、微波炉、电风扇等)中,所需要的键盘按键个数非常有限,通常为几个到十几个不等(而标准键盘通常为一百多个按键),并且每个按键所代表的功能含义也各不相同。
所以,针对每一种嵌入式系统都应对键盘(包括键盘扫描模块和相关控制信号等)进行专门设计,结合工程实际情况充分利用该系统已有的各种资源,使所设计的键盘恰如其分地融合到嵌入式系统中,成为其不可分割的一部分。
1.2编码键盘和扫描键盘[2]在数字电路中,可以利用编码器实现按键键值的直接编码。
将每个按键的输出信号对应连接到编码器的每个输入端,通过编码逻辑就可以在编码器的输出端得到对应每个按键的码值,早期称这种键盘为编码键盘。
但是,当按键较多时数码逻辑的成本较高,直接编码的方法也不够灵活,一旦编码逻辑固定就难以更改。
在通用键盘上或当按键数量较多时,普遍采用扫描方式产生键值。
将按键连接成矩阵,每个按键位于某行、某列的交点上,如图1所示,先通过扫描方式确定按下键的行和列位,即位置码或扫描码。
再查表将位置码转换为按键码值或者直接使用扫描码,有些参考书称此为“非编码键盘”。
但这种名称容易让人误解为没有对应的键值,因此又称为扫描式键基于FPGA的键盘扫描模块的设计与实现王志辉1,林水生2(电子科技大学通信与信息工程学院,四川成都610054)摘要:在电子产品中,键盘是最基本的输入设备,然而在应用中都采用通用的键盘扫描器件是不现实的,需要单独设计成专用的小键盘。
现代EDA(电子设计自动化)技术提供了一种很好的途径,利用VHDL硬件描述语言和FPGA器件可以很方便地构建键盘扫描模块。
经过实际操作检验,该模块可以很好地对每一次按键动作进行扫描和响应,实现预先设计的功能。
实验八 键盘扫描显示实验
实验八键盘扫描显示实验一、实验目的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。
基于FPGA的矩阵式按键扫描的设计
基于FPGA的矩阵式按键扫描的设计摘要:本文介绍了一种基于FPGA的矩阵式按键扫描方案,实现了矩阵式键盘在FPGA时序逻辑的控制下自动完成按键的扫描、处理、编码等功能,按键结果的采集通过中断方式来获取,是一种电路设计简单,响应稳定、快速的方法。
关键词:FPGA,矩阵式,按键扫描引言矩阵式键盘是一种常用的键盘设计方式,具有电路设计简单的特点,通过可编程逻辑(FPGA)来实现按键的扫描和控制,具有反应快速,设计灵活,易于扩展等特点。
本文设计了一种基于FPGA的矩阵式按键扫描方法,系统架构如图1所示。
CPU主要完成系统的控制功能,FPGA完成按键逻辑的控制,矩阵式键盘是一个4*6键盘。
图1 矩阵式键盘系统架构1. 按键扫描的原理在矩阵式键盘中每个按键是跨接在一条列线和一条行线之间,列线作为键盘的输入信号,行线作为按键的输出信号,当按键闭合时,行线采集到的信号电平就是列线上输入的信号电平。
当按键断开时,行线采集到的信号是高电平[1]。
因此,通过在FPGA中产生一个周期性的列扫描信号,也就是每个列线周期性的变为低电平。
当某列为低电平时,采集行信号就可以判断是否有按键按下,同时也可以判断出是那个按键被按下。
如图2所示,一个4*6的矩阵式键盘,在逻辑时序控制下,循环扫描信号由列线进入键盘,列信号Y[5:0]以“111110->111101->111011->110111->101111->0111111”的序列循环扫描[2],当没有按键按下时,行信号X[3:0]就是“1111”,当采集到的行信号X[3:0]不为“1111”,就是有按键按下,如果是行信号X[3:0] “1101”,而此时列信号为Y[5:0]为:“110111”,就可以判断出是K42被按下。
123456Y图2矩阵式键盘示意图2.按键扫描信号的产生扫描信号是在FPGA 中通过VHDL 语言有限状态机实现的,通过周期性发送扫描序列信号来完成。
实验三 键盘扫描
实验三键盘扫描&8位7段码管显示实验一实验目的1.进一步熟悉用Quartus II开发SOPC的基本流程。
2.进一步掌握PIO外设的使用方法。
3.熟悉对PIO的更复杂的操作过程。
4.掌握驱动8位七段码管的方法。
二硬件需求1.EDA/SOPC实验箱一台。
三实验原理实验中要用到4×4键盘,系统需要完成4×4键盘的扫描,确定有键按下后需要获取其键值,根据预先存放的键值表,逐个进行对比,从而进行按键的识别,并将相应的按键值进行显示。
键盘扫描的实现过程如下:对于4×4键盘,通常连接为4行、4列,因此要识别按键,只需要知道是哪一行和哪一列即可,为了完成这一识别过程,首先输出4列中的第一列为低电平,其它列为高电平,然后读取行值;然后再输出4列中的第二列为低电平,读取行值,依此类推,不断循环。
系统在读取行值的时候会自动判断,如果读进来的行值全部为高电平,则说明没有按键按下,否则如果读进来的行值发现不全为高电平,则说明键盘整列中必定有至少一个按键按下,读取此时的行值和当前的列值,即可判断到当前的按键位置。
获取到行值和列值以后,组合成一个8位的数据,根据实现不同的编码在对每个按键进行匹配,找到键值后在7段码管显示。
8位七段码管的显示是在程序中定时扫描显示的,为了使显示的过程简化,可以在程序中开辟8个存储区,用于存放8个七段码管对应值,然后每按下按键一次,则相应的值出现在最右边的七段码管上,原先的显示的值依次左移。
为了完成键盘的扫描和七段码管的正确显示,必须在原来CPU模块的基础上再加入一个定时器模块,用以产生周期性中断,在中断服务程序中完成键盘的扫描以及七段码管的扫描。
四实验内容本实验要完成的内容是设计一个CPU模块,该CPU需要加入一个定时器模块,用以产生周期性中断进行键盘扫描和七段码管的扫描显示。
实验要求能够在按下按键时获取其键值,然后在8个七段码管上正确显示按下的键值,每按键一次,原先显示的值整体左移,新的键值出现在8个七段码管的最右边。
键盘扫描
基于FPGA的键盘扫描电路一、设计目的:1.通过设计熟练掌握VHDL硬件描述语言在FPGA芯片上实现键盘接口设计;二、设计要求:1.键盘按钮数为4,系统时钟10MHz;2.能识别出所按按钮;3.按钮被按下后,视为此按钮输入一次,若按钮长时间不松,(时限1S)后每隔0.5S视为再次输入,直至按钮松开;4.要求能对按钮按下时指令的抖动能正确处理。
对持续时间小于50ms的输入不作响应;5.各键设置不同优先级,多键同时按下时,视为优先级较高的按键被按下;三、设计内容1.行列式键盘介绍1)行列式键盘概述为了减少键盘与单片机接口时所占用I/O口线的数目,在键数较多时,通常都将键盘排列成行列矩阵式,行列式键盘又叫矩阵式键盘。
用带有I/O口的线组成行列结构,按键设置在行列的交点上。
例如用2*2的行列结构可以构成4个键的键盘,4*4的行列结构可以构成有16个键的键盘。
这样,当按键数量平方增长时,I/O口线只是线性增长,这样就可以节省I/O口线。
2)行列式键盘原理行列式键盘的电路原理图如图3所示图3 行列式键盘电路原理图按键设置在行列线交叉点,行、列线分别连接到按键开关的两端。
列线通过上拉电阻接+5V的电压,即列线的输出被钳位到高电平状态。
行线与按键的一个引脚相连,列线与按键的另一个引脚相连。
判断键盘中有无按键按下是通过行线送入扫描信号,然后从列线读取状态得到的。
其方法是依次给行线送低电平,检查列线的输入。
如果列线信号全为高电平,则代表低电平信号所在的行中无按键按下;如果列线有输入为低电平,则低电平信号所在的行和出现低电平的列的交点处有按键按下。
设行扫描信号为keydrv3~keydrv0,列线按键输入信号keyin3~keyin0与按键位置的关系如表1所示。
表1 行扫描信号、列按键输入信号与按键位置的关系2 键盘电路与FPGA 接口实现1)系统结构和模块划分keydrv3~keydrv0keyin3~keyin0 对应的按键11101110 1 1101 2 1011 3 0111 41101 1110 5 1101 6 1011 7 0111 81011 1110 9 1101 0 1011 A 0111 B0111 1110 C 1101 D 1011 E 0111 F图4 键盘接口电路结构图由行列式键盘的原理可以知道,要正确地完成按键输入工作必须有按键扫描电路产生keydrv3~keydrv0信号。
基于FPGA的数码显示和键盘扫描的电路设计
文档从互联网中收集,已重新修正排版,word格式支持编辑,如有帮助欢迎下载支持。
前言现在,电子技术的发展非常迅猛高新科技日新月异。
特别是专用集成电路(ASIC)设计技术的日趋进步和完善,推动着数字电路系统设计方法的发展,使他从单纯的ASIC设计走向了系统设计和单片系统的设计。
而经过几十年的发展越来越成熟的FPGA设计方式以他的短周期,低成本,灵活方便的独特优势走红于电子技术业内。
FPGA是英文Field Programmable Gate Array的缩写,即现场可编程门阵列,它是在PAL、GAL、PLD等可编程器件的基础上进一步发展的产物。
它是作为专用集成电路(ASIC)领域中的一种半定制电路而出现的,既能解决定制电路的不足,又能克服原有可编程器件门电路数有限的缺点。
本设计的的内容是基于FPGA的数码显示和键盘扫描电路的设计,通过键盘对数码显示调控来实现FPGA的思想。
键盘输入通过按键扫描检测和去抖动在通过编码输入到显示电路中,在显示过程中能通过键盘输入对显示内容进行校正和调节。
在通过编译仿真下载到FPGA电子板上后能显示预期的信号,当按下键盘时候能产生预期的结果。
在设计这个课题的过程中,遇到很多问题,比如开始的时候遇到的一个问题就是自己在在quartus中进行仿真,把模块单个的拿出来仿真仿真波形正常,但当把几个模块连在一起的时候仿真就出不来预期的波形。
最后在老师和同学的帮助下发现要对每个模块进行了解,对模块之间的连接要适当的处理。
经过这次设计,尽管结果不是那么完美,但为自己以后的生活,学习有了很大的帮助,特别是在设计过程中不断遇到问题不断解决问题的经验会让我受用终生。
第一章绪论.................................... 错误!未定义书签。
1.1选题背景...................................错误!未定义书签。
1.1.1 课题相关技术的发展.....................错误!未定义书签。
非编码键盘的扫描程序设计
学号:课程设计题目非编码键盘的扫描程序设计学院自动化学院专业自动化专业班级姓名指导教师陈静教授2014 年7 月 4 日课程设计任务书学生姓名:专业班级:班指导教师:陈静教授工作单位:自动化学院题目: 非编码键盘的扫描程序设计要求完成的主要任务:1.通过8155扩展I/O口行列式键盘;2.利用8031微控制器。
(1)8155扩展I/O口组成6×6行列式键盘,设计非编码键盘的扫描硬件系统,画出电路图;(2)对键盘按键能够正确识别,去抖动;(3)键盘扫描;(4)撰写设计说明书。
时间安排:6月25日介绍课程设计要求及任务6月26日查阅和准备相关技术资料,完成整体方案设计6月27日—6月29日完成硬件设计6月30日—7月1日编写调试程序7月2日—7月3日撰写课程设计说明书7月4日提交课程设计说明书、图纸、电子文档指导教师签名:年月日系主任(或责任教师)签名:年月日本次课程设计的内容是利用8031微控制器,通过8155扩展I/O口矩阵键盘。
要求通过8155扩展I/O口组成6×6矩阵键盘,设计非编码键盘的扫描系统,并且能够对键盘的按键正确识别,去抖动。
本文首先对方案进行了比较并确定了最终的方案,即采用软件去抖方法,然后列举了3种非编码键盘的扫描方式并确定采用编程扫描方式,接着阐述了扫描原理并介绍了8031和8155两个芯片,最后对硬件设计部分和软件设计部分分别进行了较为详细的分解分析和总体分析,硬件原理图采用的是protues软件,编程语言采用的是汇编语言,并针对本次课程设计表达了自己的真实想法和心得体会。
关键词:8155芯片矩阵键盘扫描去抖1设计任务及要求 (1)1.1初始要求 (1)1.2要求完成的主要任务 (1)2方案比较及确定 (2)2.1键盘去抖动方案的选择 (2)2.1扫描方式的选择 (3)3键盘扫描原理 (4)4键盘扫描系统硬件电路设计 (4)4.1元器件介绍 (4)4.1.1 8031单片机 (4)4.1.2 8155芯片 (6)4.2硬件电路设计 (7)4.2.1时钟电路和复位电路 (7)4.2.2 8031与8155连接电路 (9)4.2.3 矩阵键盘电路 (9)4.3设计总电路 (10)5键盘扫描系统软件设计 (11)5.1 编程思路 (11)5.2 程序流程图 (12)5.3子程序 (13)5.3.1 判断是否有键按下子程序 (13)5.3.2扫描子程序 (13)5.3.3 延时子程序 (15)6设计过程遇到的问题 (16)7心得体会 (17)参考文献: (18)附录1:硬件总电路图 (19)附录2:程序清单 (20)1设计任务及要求1.1初始要求1.通过8155扩展I/O口行列式键盘;2.利用8031微控制器。
基于FPGA的边界扫描测试系统设计
基于FPGA的边界扫描测试系统设计【摘要】随着集成电路技术的快速发展,传统的PCB电路板测试所采用探针的方法已经不现实,边界扫描技术解决了这一传统的PCB板测试的难题。
本文设计的边界扫描测试系统可以实现对JTAG的访问以及完成对被测电路板器件IDCODE等方面的测试。
实验结果表明,该系统测试方便,简单。
【关键词】边界扫描控制器;1149.1;FPGA;USB2.0Abstract:With the rapid development of integrated circuit technology,traditional PCB circuit board test methods used in the probe have many problems.Boundary-scan technology solve the traditional problems of PCB board testing.Boundary_scan test system designed in this paper can achieve to access to the JTAG and complete the IDCODE test on the device of the circuit boards.Experimental results show that the system testing convenient and simple.Key words:boundary scan controller;1149.1;FPGA;USB2.0在科技高度发达的今天,测试工作已经成为制造能力及实用性水平的重要标志。
随着社会的发展,对测试技术也提出了越来越高的要求。
采用物理接触的测试探针来测试PCB印刷电路板已经不符合时代发展的需要,而且随着集成电路的迅速发展,IC芯片的集成度不断提高,引脚数量增加的同时间距越来越小,传统方法已经力不从心。
基于VHDL的键盘扫描电路设计设计
毕业论文(设计)题目:基于VHDL的键盘扫描电路设计系:机电工程系学生姓名:专业:电子信息工程班级:指导教师:起止日期: 2012.10.15——2013.01.06 2013年1 月6 日基于VHDL的键盘扫描电路设计(东海科学技术学院机电工程系,浙江舟山 316000)摘要随着科技的发展,时代的进步,生活的需要,在我们生活的很多地方领域,都有键盘的应用,而且它的应用非常广,当然键盘扫描的方法也有很多种。
键盘是单片机系统设计中一种主要的信息输入接口,合理的设计,不仅可以节省系统的设计成本,更可以使仪器设备的操作变得更为简单、方便、快捷,很大程度上提高系统综合性能。
随着信息产业和微电子技术的发展,很多系统设计技术已经成为信息产业最热门的技术之一,在很多地方上都有应用,比如航空航天、医疗保健、通讯、广播、工业、测量测试等很多热门领域。
并且随着工艺的进步和技术的发展,向更广泛的应用领域扩展。
矚慫润厲钐瘗睞枥庑赖。
本次设计主要是运用VHDL硬件描述语言和图形设计综合方法,在MAX+PLUSⅡ软件平台的环境下建立波形文件,生成电路符号,设置输入端口,实现程序的模拟仿真,得到仿真波形图,才完成了键盘扫描电路的程序设计。
这个电路设计是一个关于小型的计算器的键盘按键电路的设计,主要由5个部分组成,它们分别为分频器电路、键盘扫描计数器电路、按键检测电路、按键抖动消除电路和键盘编码电路。
本次设计主要是设计一个4×4矩阵式的键盘扫描电路,它具有列扫描和行扫描的功能,有2个输入端口,分别为clk和col,同时也有2个输出端口,分别为row和bianma,按下按键的数据通过端口行、列线输入到FPGA芯片中去,FPGA芯片内部的扫描模块会将数据传送到编码器中进行编码,最终完成本次电路的设计。
在生活中是这种小型的计算器是非常常用的,虽然体型很小,但却被广泛的使用,很多其他的东西都是在这种小型的计算器的键盘的基础上设计的。
经典的verilog键盘扫描程序
经典的verilog键盘扫描程序作者:ilove314拿到威百仕( VibesIC )的板子后就迫不及待的开始我的学习计划,从最基础的分频程序开始,但看到这个键盘扫描程序后,直呼经典,有相见恨晚的感觉,还想说一句:威百仕( VibesIC ),我很看好你!WHY?待我慢慢道来,这个程序的综合后是0error,0warning。
想想自己编码的时候那个warning是满天飞,现在才明白HDL设计有那么讲究了,代码所设计的不仅仅是简单的逻辑以及时序的关系,更重要的是你要在代码中不仅要表现出每一个寄存器,甚至每一个走线。
想想我写过的代码,只注意到了前者,从没有注意过后者,还洋洋自得以为自己也算是个高手了,现在想来,实在惭愧啊!学习学习在学习,这也重新激发了我对HDL设计的激情,威百仕给了我一个方向,那我可要开始努力喽!废话说了一大堆,看程序吧:(本代码经过ise7.1i综合并下载到SP306板上验证通过)//当三个独立按键的某一个被按下后,相应的LED被点亮;再次按下后,LED熄灭,按键控制LED亮灭module key_debounce(clk,rst_n,s1_n,s2_n,s3_n,s4_n,s5_n,led_d1,led_d2,led_d3,led_d 4,led_d5);input clk; //主时钟信号,10MHzinput rst_n; //复位信号,低有效input s1_n,s2_n,s3_n,s4_n,s5_n;output led_d1,led_d2,led_d3,led_d4,led_d5;reg[4:0] s_rst;always @(posedge clk or negedge rst_n)if (!rst_n) s_rst <= 5'b11111;else s_rst <= {s5_n,s4_n,s3_n,s2_n,s1_n};reg[4:0] s_rst_r;always @ ( posedge clk or negedge rst_n )if (!rst_n) s_rst_r <= 5'b11111;else s_rst_r <= s_rst;wire[4:0] s_an = s_rst_r & ( ~s_rst);reg[19:0] cnt; //计数寄存器always @ (posedge clk or negedge rst_n)if (!rst_n) cnt <= 20'd0; //异步复位else if(s_an) cnt <=20'd0;else cnt <= cnt + 1'b1;reg[4:0] low_s;always @(posedge clk or negedge rst_n)if (!rst_n) low_s <= 5'b11111;else if (cnt == 20'h30D40)low_s <= {s5_n,s4_n,s3_n,s2_n,s1_n};reg [4:0] low_s_r;always @ ( posedge clk or negedge rst_n )if (!rst_n) low_s_r <= 5'b11111;else low_s_r <= low_s;wire[4:0] led_ctrl = low_s_r[4:0] & ( ~low_s[4:0]);reg d1,d2,d3,d4,d5;always @ (posedge clk or negedge rst_n)if (!rst_n) begind1 <= 1'b0;d2 <= 1'b0;d3 <= 1'b0;d4 <= 1'b0;d5 <= 1'b0; endelse begin //if ( led_ctrl[0] ) d1 <= ~d1;if ( led_ctrl[1] ) d2 <= ~d2;if ( led_ctrl[2] ) d3 <= ~d3;if ( led_ctrl[3] ) d4 <= ~d4;if ( led_ctrl[4] ) d5 <= ~d5; endassign led_d1 = d1 ? 1'b1 : 1'b0; //LED翻转输出assign led_d2 = d2 ? 1'b1 : 1'b0;assign led_d3 = d3 ? 1'b1 : 1'b0;assign led_d4 = d4 ? 1'b1 : 1'b0;assign led_d5 = d5 ? 1'b1 : 1'b0;endmodule也许初看起来这段代码似乎有点吃力,好多的always好多的wire啊,而我们通常用得最多的判断转移好像不是主流。
带FIFO存储的FPGA键盘扫描器设计(仿真+代码)
带FIFO存储的键盘扫描器设计一、模块结构:1、Keypad:顶层模块,负责调用其他模块;2、clock_divider:将50MHZ系统时钟分频,产生clk_slow(500HZ)和clk_display(1KHZ);3、keypad_scaner:扫描键盘,并产生编码值,测试时连续写入键盘值;4、code_fifo:将键盘值存入FIFO;5、rd_toggle:对read信号去抖动;6、decode_display:将键盘编码值映射成数码管编码值,并产生驱动数码管信号;7、row_signal:产生row,用于测试;二、模块仿真结果:1、clock_divider:clk_slow为500HZ;clk_sidplay为1KHZ,数码管的刷新频率1KHZ就可避免数码管闪烁;2、keypad_scaner:黄色信号为{col,row}的组合信号和对应的编码输出code,红色信号valid_o为FIFO的写使能信号;3、code_fifo:写进FIFO的数据;两条红线rd_en与valid分别为FIFO的读使能和写使能,黄色信号线为FIFO的输出,在读使能有效时,读出0001、0010、0011、0100、0101、0110;4、rd_toggle:两条红线分别为rd_up_cnt、rd_lw_cnt,用于消抖时read高低电平的计数,规定大于10ms可认为按键稳定。
黄线为稳定的read输出。
5、decode_display:三条红线分别为两个数码管的驱动信号left_code、right_code以及两个数码管的位选信号cathode。
6、row_signal:7、顶层仿真:当read有效时,读出“00”,“01”,“02”,“03”,“04”;三、综合-布局布线综合布局布线通过;四、模块代码:1、Keypad:`timescale 1ns / 1ps//////////////////////////////////////////////////////////////////////////////////// Company:// Engineer://// Create Date: 21:37:47 05/13/2015// Design Name:// Module Name: keypad// Project Name:// Target Devices:// Tool versions:// Description://// Dependencies://// Revision:// Revision 0.01 - File Created// Additional Comments:////////////////////////////////////////////////////////////////////////////////////module keypad(clk,reset,read,row,col,left_code,right_code,cathode,empty,full);input clk;input reset;input read;input[3:0] row;output[3:0] col;output[6:0] left_code;output[6:0] right_code;output empty;output full;output[1:0] cathode;wire[3:0] code;wire[3:0] code_out;wire[1:0] cathode;keypad_scaner u_keypad_scaner(.clk(clk_slow),.reset(reset),.row(row),.col(col),.code(code),.valid_o(valid));clock_divider u_clock_divider(.clk(clk),.reset(reset),.clk_slow(clk_slow),.clk_display(clk_display));code_fifo u_code_fifo(.clk(clk_slow),.reset(reset),.code(code),.valid(valid),.rd_en(read_fifo),.dout(code_out),.full(full),.empty(empty));rd_toggle u_rd_toggle(.clk(clk),.reset(reset),.read(read),.read_fifo(read_fifo));decode_display u_decode_display(.clk(clk_display),.reset(reset),.code(code_out),.left_code(left_code),.right_code(right_code),.cathode(cathode));endmodule2、keypad_scaner:`timescale 1ns / 1ps//////////////////////////////////////////////////////////////////////////////////// Company:// Engineer://// Create Date: 16:05:31 05/13/2015// Design Name:// Module Name: keypad_scaner// Project Name:// Target Devices:// Tool versions:// Description://// Dependencies://// Revision:// Revision 0.01 - File Created// Additional Comments://////////////////////////////////////////////////////////////////////////////////// module keypad_scaner(clk,reset,row,col,code,valid_o);input clk ;input reset ;input[3:0] row ;output valid_o ;output[3:0] col ;output[3:0] code;reg valid;reg valid_tmp;reg[3:0] row_tmp;reg[3:0] num;reg[3:0] row_tmp1;reg[3:0] row_tmp2;reg[3:0] col ;reg[3:0] code ;reg[1:0] cnt ;wire valid_o;wire[7:0] key_sample;assign key_sample = {col,row};//列扫描信号always @(posedge clk or posedge reset)if(reset)begincnt <= 2'b0;col <= 4'b0000;endelsebegincnt <= cnt + 2'b01;case(cnt)2'b00 : col <= 4'b1000;2'b01 : col <= 4'b0100;2'b10 : col <= 4'b0010;2'b11 : col <= 4'b0001;endcaseendalways @(posedge clk or posedge reset) if(reset)code <= 4'b0000;elsebegincase(key_sample)//第一列扫描8'b1000_0001 : code <= 4'b0000;8'b1000_0010 : code <= 4'b0001;8'b1000_0100 : code <= 4'b0010;8'b1000_1000 : code <= 4'b0011;//第二列扫描8'b0100_0001 : code <= 4'b0100;8'b0100_0010 : code <= 4'b0101;8'b0100_0100 : code <= 4'b0110;8'b0100_1000 : code <= 4'b0111;//第三列扫描8'b0010_0001 : code <= 4'b1000;8'b0010_0010 : code <= 4'b1001;8'b0010_0100 : code <= 4'b1010;8'b0010_1000 : code <= 4'b1011;//第四列扫描8'b0001_0001 : code <= 4'b1100;8'b0001_0010 : code <= 4'b1101;8'b0001_0100 : code <= 4'b1110;8'b0001_1000 : code <= 4'b1111;default:code <= code;endcaseendalways @(posedge clk or posedge reset)if(reset)num <= 4'd0;else if(row == 4'b0000)num <= num + 4'd1;elsenum <= 4'd0;always @(posedge clk or posedge reset)if(reset)row_tmp <= 4'b0000;elserow_tmp <= row;always @(posedge clk or posedge reset)if(reset)valid <= 1'b0;else if(num > 4'd4)valid <= 1'b0;else if(row_tmp)valid <= 1'b1;elsevalid <= valid;always @(posedge clk or posedge reset)if(reset)valid_tmp <= 1'b0;elsevalid_tmp <= valid;assign valid_o = valid & (~valid_tmp);endmodule3、clock_divider`timescale 1ns / 1ps//////////////////////////////////////////////////////////////////////////////////// Company:// Engineer://// Create Date: 09:09:00 05/16/2015// Design Name:// Module Name: clock_divider// Project Name:// Target Devices:// Tool versions:// Description://// Dependencies://// Revision:// Revision 0.01 - File Created// Additional Comments://////////////////////////////////////////////////////////////////////////////////// module clock_divider(clk,reset,clk_slow,clk_display);input clk;input reset;output clk_slow;output clk_display;reg clk_slow;reg clk_display;reg[17:0] divide_cnt1;reg[19:0] divide_cnt2;always @(posedge clk or posedge reset)if(reset)divide_cnt1 <= 18'd0;else if(divide_cnt1 == 17'd100000)divide_cnt1 <= 18'd0;elsedivide_cnt1 <= divide_cnt1 + 18'd1;always @(posedge clk or posedge reset)if(reset)divide_cnt2 <= 20'd0;else if(divide_cnt2 == 20'd50000)divide_cnt2 <= 20'd0;elsedivide_cnt2 <= divide_cnt2 + 20'd1;always @(posedge clk or posedge reset)if(reset)clk_slow <= 1'b0;else if(divide_cnt1 <= 18'd50000)clk_slow <= 1'b1;elseclk_slow <= 1'b0;always @(posedge clk or posedge reset)if(reset)clk_display <= 1'b0;else if(divide_cnt2 <= 20'd25000)clk_display <= 1'b1;elseclk_display <= 1'b0;endmodule4、code_fifo`timescale 1ns / 1ps//////////////////////////////////////////////////////////////////////////////////// Company:// Engineer://// Create Date: 10:47:48 05/14/2015// Design Name:// Module Name: key_fifo// Project Name:// Target Devices:// Tool versions:// Description://// Dependencies://// Revision:// Revision 0.01 - File Created// Additional Comments:////////////////////////////////////////////////////////////////////////////////////module code_fifo(clk,reset,code,valid,rd_en,dout,full,empty);input clk;input reset;input valid;input rd_en;input[3:0] code;output[3:0] dout;output full;output empty;key_fifo u_key_fifo(.clk(clk),.rst(reset),.din(code),.wr_en(valid),.rd_en(rd_en),.dout(dout),.full(full),.empty(empty));Endmodule5、rd_toggle:`timescale 1ns / 1ps//////////////////////////////////////////////////////////////////////////////////// Company:// Engineer://// Create Date: 16:59:34 05/13/2015// Design Name:// Module Name: rd_toggle// Project Name:// Target Devices:// Tool versions:// Description://// Dependencies://// Revision:// Revision 0.01 - File Created// Additional Comments://////////////////////////////////////////////////////////////////////////////////// module rd_toggle(clk,reset,read,read_fifo);input clk;input reset;input read;output read_fifo;reg read_fifo;reg[23:0] rd_up_cnt; //按键输入高电平计数器reg[23:0] rd_lw_cnt; //按键输入低电平计数器//对输入进行采样、计数always @(posedge clk or posedge reset)if(reset)rd_up_cnt <= 24'd0;else if(read)rd_up_cnt <= rd_up_cnt + 24'd1;elserd_up_cnt <= 24'd0;always @(posedge clk or posedge reset)if(reset)rd_lw_cnt <= 24'd0;else if(!read)rd_lw_cnt <= rd_lw_cnt + 24'd1;elserd_lw_cnt <= 24'd0;always @(posedge clk or posedge reset)if(reset)read_fifo <= 1'b0;else if(rd_up_cnt == 24'h7A120) //大于10ms认为按键稳定read_fifo <= 1'b1;else if(rd_lw_cnt == 24'h7A120)read_fifo <= 1'b0;elseread_fifo <= read_fifo;endmodule6、decode_display:`timescale 1ns / 1ps//////////////////////////////////////////////////////////////////////////////////// Company:// Engineer://// Create Date: 17:19:56 05/13/2015// Design Name:// Module Name: decode_display// Project Name:// Target Devices:// Tool versions:// Description://// Dependencies://// Revision:// Revision 0.01 - File Created// Additional Comments:////////////////////////////////////////////////////////////////////////////////////module decode_display(clk,code,reset,left_code,right_code,cathode);input clk;input reset;input[3:0] code;output[6:0] left_code;output[6:0] right_code;output[1:0] cathode;reg[6:0] left_code;reg[6:0] right_code;reg[15:0] cnt; //动态扫描计数器reg[1:0] cathode; //片选信号;//七段数码管段选(共阳极)parameter ZERO = 7'b100_0000; parameter ONE = 7'b111_1001; parameter TWO = 7'b010_0100; parameter THREE = 7'b011_0000; parameter FOUR = 7'b001_1001; parameter FIVE = 7'b001_0010; parameter SIX = 7'b000_0010; parameter SEVEN = 7'b111_1000; parameter EIGHT = 7'b000_0000; parameter NINE = 7'b001_0000;always @(posedge clk or posedge reset)if(reset)cathode <= 2'b00;elsecase(cathode)2'b00 : cathode <= 2'b01;2'b01 : cathode <= 2'b10;2'b10 : cathode <= 2'b01;endcasealways @(code)case(code)4'b0000 : beginright_code <= ZERO;left_code <= ZERO;end4'b0001 : right_code <= ONE;4'b0010 : right_code <= TWO;4'b0011 : right_code <= THREE;4'b0100 : right_code <= FOUR;4'b0101 : right_code <= FIVE;4'b0110 : right_code <= SIX;4'b0111 : right_code <= SEVEN;4'b1000 : right_code <= EIGHT;4'b1001 : right_code <= NINE;4'b1010 : beginright_code <= ZERO;left_code <= ONE;end4'b1011 : beginright_code <= ONE;left_code <= ONE;end4'b1100 : beginleft_code <= ONE;right_code <= TWO;end4'b1101 : beginleft_code <= ONE;right_code <= THREE;end4'b1110 : beginleft_code <= ONE;right_code <= FOUR;end4'b1111 : beginleft_code <= ONE;right_code <= FIVE;enddefault : beginleft_code <= ZERO;right_code <= ZERO;endendcaseendmodule7、row_signal:`timescale 1ns / 1ps//////////////////////////////////////////////////////////////////////////////////// Company:// Engineer://// Create Date: 20:00:46 05/14/2015// Design Name:// Module Name: row_signal// Project Name:// Target Devices:// Tool versions:// Description://// Dependencies://// Revision:// Revision 0.01 - File Created// Additional Comments:////////////////////////////////////////////////////////////////////////////////////module row_signal(row,key,col);input[15:0] key;input[3:0] col;output[3:0] row;reg[3:0] row;always @(posedge key or col)beginrow[0] = key[0]&&col[3] || key[4]&&col[2] || key[8]&&col[1] || key[12]&&col[0];row[1] = key[1]&&col[3] || key[5]&&col[2] || key[9]&&col[1] || key[13]&&col[0];row[2] = key[2]&&col[3] || key[6]&&col[2] || key[10]&&col[1] || key[14]&&col[0];row[3] = key[3]&&col[3] || key[7]&&col[2] || key[11]&&col[1] || key[15]&&col[0];endendmodule8、keypad_tst:`timescale 1ns / 1ps////////////////////////////////////////////////////////////////////////////////// Company:// Engineer://// Create Date: 19:16:02 05/14/2015// Design Name: keypad// Module Name: D:/FPGAProject/Xilinx/keypad_design/keypad_tst.v // Project Name: keypad_design// Target Device:// Tool versions:// Description://// Verilog Test Fixture created by ISE for module: keypad//// Dependencies://// Revision:// Revision 0.01 - File Created// Additional Comments://////////////////////////////////////////////////////////////////////////////////module keypad_tst;// Inputsreg clk;reg reset;reg read;wire[3:0] row;reg[39:0] pressed;reg[15:0] key_s;// Outputswire[3:0] col;wire[6:0] left_code;wire[6:0] right_code;wire empty;wire full;wire[1:0] cathode;wire[15:0] key;integer j;integer k;// Instantiate the Unit Under Test (UUT)keypad uut (.clk(clk),.reset(reset),.read(read),.row(row),.col(col),.left_code(left_code),.right_code(right_code),.cathode(cathode),.empty(empty),.full(full));parameter[39:0] key_0 = "key_0"; parameter[39:0] key_1 = "key_1"; parameter[39:0] key_2 = "key_2"; parameter[39:0] key_3 = "key_3"; parameter[39:0] key_4 = "key_4"; parameter[39:0] key_5 = "key_5"; parameter[39:0] key_6 = "key_6"; parameter[39:0] key_7 = "key_7"; parameter[39:0] key_8 = "key_8"; parameter[39:0] key_9 = "key_9"; parameter[39:0] key_A = "key_A"; parameter[39:0] key_B = "key_B"; parameter[39:0] key_C = "key_C"; parameter[39:0] key_D = "key_D"; parameter[39:0] key_E = "key_E"; parameter[39:0] key_F = "key_F"; parameter[39:0] none = "none";row_signal u_row_signal(.row(row),.key(key),.col(col));initialbeginclk = 0;reset = 1;read = 0;//row = 0;#20 reset = 0;endalways @(key)case(key)16'h0000 : pressed = none;16'h0001 : pressed = key_0;16'h0002 : pressed = key_1;16'h0004 : pressed = key_2;16'h0008 : pressed = key_3;16'h0010 : pressed = key_4;16'h0020 : pressed = key_5;16'h0040 : pressed = key_6;16'h0080 : pressed = key_7;16'h0100 : pressed = key_8;16'h0200 : pressed = key_9;16'h0400 : pressed = key_A;16'h0800 : pressed = key_B;16'h1000 : pressed = key_C;16'h2000 : pressed = key_D;16'h4000 : pressed = key_E;16'h8000 : pressed = key_F;default : pressed = none;endcasealways #10 clk = ~clk;initialbeginfor(k=0; k<=1; k=k+1)beginkey_s=0;#50 for(j=0; j<=16; j=j+1)begin#40000000 key_s[j] = 1;#50000000 key_s = 0; //50msendendendassign key = key_s;initialbegin#400000000 read = 1;#200000000 read = 0; // 60ms#400000000 read = 1;// #200000000 read = 0;// #100000000 read = 1; // #200000000 read = 0; // #100000000 read = 1; // #700000000 read = 0; endendmodule。
基于FPGA的键盘扫描电路EDA课程设计
目录1 课程设计综述——————————————————————2 1.1 课程设计的题目———————————————————— 21.2 题目要求——————————————————————— 22 方案选择———————————————————————— 23 整体电路的设计及分析——--——————————————— 3 3.1 顶层电路图—————————————————————— 33.2 各模块功能原理分析—————————————————— 44 心得体会——————————————————————— 121.课程设计综述1.1 课程设计的题目基于FPGA的键盘扫描电路。
1.3 题目要求(1)、键盘按钮数为4,系统时钟10MHz。
(2)、能识别出所按按钮。
(3)、按钮被按下后,视为此按钮输入一次,若按钮长时间不松,(时限1S)后每隔0.5S 视为再次输入,直至按钮松开。
(4)、要求能对按钮按下时指令的抖动能正确处理。
对持续时间小于50ms的输入不作响应。
(5)、各键设置不同优先级,多键同时按下时,视为优先级较高的按键被按下。
2.方案选择根据题目要求,需要4个按钮的键盘,通过查阅资料我选择通用的2*2行列式键盘,判断键盘中有无按键按下是通过行线送入扫描信号,然后从列线读取状态得到的。
其方法是依次给行线送低电平,检查列线的输入。
如果列线信号全为高电平,则代表低电平信号所在的行中无按键按下;如果列线有输入为低电平,则低电平信号所在的行和出现低电平的列的交点处有按键按下。
原理框图如下所示:由题知输入的是10MHz的系统时钟,我们需要通过一个分频器来输出一个1KHz的计数频率来扫描键盘以及一个40Hz(即25ms)的消除抖动的频率来计算是否属于抖动按键,计数值用来计算当前键盘扫描值,4按钮的话计数值则是00、01、10和11 ,若有按键信号发生则送计数值到按键检测电路和按键编码电路供确定按键位置用。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
摘要在现代电子工业的控制电路中,键盘扫描和显示电路对系统的调试和设置有着重要的作用。
随着EDA技术的发展,基于FPGA的扫描键盘因其结构简单,能有效防止机械键盘按键抖动带来的数据错误等优点在许多电子设备中都得到了广泛的应用。
本文主要是设计一个基于FPGA的键盘扫描程序,该设计在EDA工具Quarutus II9.0上开发完成,以Creat-SOPC2000实验箱上的4*4矩阵键盘为硬件实体,设计键盘扫描程序,将程序划分为时序产生模块、键盘扫描模块、弹跳消除模块、键值译码模块四个模块,时序产生模块为键盘扫描和弹跳消除模块产生时钟信号,键盘扫描模块采用行扫描法对4*4矩阵键盘进行扫描,键值译码模块将所按键值译码为共阳极8位7段数码管的显示码,几个模块组合起来实现键盘扫描的设计要求。
最后对程序进行仿真分析和硬件验证。
仿真结果表明,该系统具有集成度高、稳定性好、设计灵活和设计效率高等优点。
关键词: FPGA,Quartus II,VHDL,键盘扫描ABSTRACTIn 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 .......................................................................................................... I I 第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-6]。
1.2 课题的研究意义从计算机时代开始以来,数字系统设计就存在两个大的分类,即系统硬件设计和系统软件设计。
早期的数字系统设计人员也因此被分为两个族群:硬件设计人员和软件设计人员,他们都只从事自己的工作领域,很少涉足对方的领域,尤其是软件设计人员。
但是,随着数字技术和硬件系统的发展,这两个领域开始互相有所合作。
在硬件描述语言HDL(Hardware Description Language)出现后,数字系统的设计已无软硬件之分。
设计人员可以用HDL语言来描述系统的硬件构成及其行为,并通过仿真确定其运用到系统硬件上时是否可行,设计出符合要求的硬件系统。
不仅如此,利用HDL语言来设计系统硬件同传统的硬件设计方法相比,具有其独特的优势,它为系统的硬件设计带来了深远的影响,是硬件设计领域的一次重要的变革。
传统的键盘扫描是以硬件电路来确定键盘的变化,特定的硬件电路只能应用于特定的键盘,因此它存在这样一些缺点:不能根据实际应用的改变而变化,形式固定。
本文所采用的技术方案能克服上述所讲的技术缺点,该键盘扫描程序是由软件控制完成,不需要改变硬件电路,就可以适用于多种不同类型的键盘。
整个系统设计是自动化过程,减少了工作量,主要把精力放在创造性的方案和概念构思上,提高了工作效率,缩短了产品的研制周期。
1.3 本文的主要工作本设计主要是以计算机为设计平台,综合运用EDA软件工具开发环境,使用硬件描述语言VHDL,采用自顶而下的设计方法,把系统由上至下的分成几个模块设计,最后达到系统的要求,然后在Quartus II9.0上通过编程、调试、编译、仿真,从而实现键盘扫描的设计。