矩阵键盘EDA技术课程设计.docx
《矩阵键盘EDA技术课程设计.docx》由会员分享,可在线阅读,更多相关《矩阵键盘EDA技术课程设计.docx(20页珍藏版)》请在冰豆网上搜索。
矩阵键盘EDA技术课程设计
《电子设计EDA》课程设计
专业:
电子信息科学与技术
班级:
2010级电信本
(1)班
姓名:
***
学号:
*********
指导老师:
***
完成时间:
2012.11—2012.12
教师评分:
题目:
矩阵键盘控制接口设计
一、绪论
1.1FPGA概况
早期的可编程逻辑器件只有可编程只读存储器(PROM)、紫外线可擦除只读存储器(EPROM)和电可擦除只读存储器(E2PROM)三种。
由于结构的限制,它们只能完成简单的数字逻辑功能。
其后出现了一类结构上稍复杂的可编程芯片,即可编程逻辑器件(PLD),它能够完成各种数字逻辑功能。
典型的PLD由一个“与”门和一个“或”门阵列组成,而任意一个组合逻辑都可以用“与—或”表达式来描述,所以PLD能以乘积和的形式完成大量的组合逻辑功能。
这一阶段的产品主要有PAL(可编程阵列逻辑)和GAL(通用阵列逻辑)。
PAL由一个可编程的“与”平面和一个固定的“或”平面构成,或门的输出可以通过触发器有选择地被置为寄存状态。
PAL器件是现场可编程的,它的实现工艺有反熔丝技术、EPROM技术和E2PROM技术。
还有一类结构更为灵活的逻辑器件是可编程逻辑阵列(PLA),它也由一个“与”平面和一个“或”平面构成,但是这两个平面的连接关系是可编程的。
PLA器件既有现场可编程的,也有掩膜可编程的。
在PAL的基础上又发展了一种通用阵列逻辑(GAL、GenericArrayLogic),如GAL16V8、GAL22V10等。
它采用了E'PROM工艺,实现了电可擦除、电可改写,其输出结构是可编程的逻辑宏单元,因而它的设计具有很强的灵活性,至今仍有许多人使用。
这些早期的PLD器件的一个共同特点是可以实现速度特性较好的逻辑功能,但其过于简单的结构也使它们只能实现规模较小的电路。
为了弥补这一缺陷,20世纪80年代中期,Altera和Xilinx分别推出了类似于PAL结构的扩展型CPLD(ComplexProgrammableLogicDvice)和与标准门阵列类似的FPGA(FieldProgrammableGateArray),它们都具有体系结构和逻辑单元灵活、集成度高以及适用范围宽等特点。
这两种器件兼容了PLD和通用门阵列的优点,可实现较大规模的电路,编程也很灵活。
与门阵列等其他ASIC(ApplicationSpecificIC)相比,它们又具有设计开发周期短、设计制造成本低、开发工具先进、标准产品不需测试、质量稳定以及可实时在线检验等优点,因此被广泛应用于产品的原型设计和产品生产(一般在10000件以下)之中。
几乎所有应用门阵列、PLD和中小规模通用数字集成电路的场合均可应用FPGA和CPLD器件。
1.2本课题的研究意义
近年来EDA技术在电子领域引发的技术革命,推动着电子技术的迅猛发展,为世人所瞩目,而FPGA为代表的可编程逻辑器件的应用,更是受到业内人士的普遍关注。
伴随着大规模集成电路和计算机技术的高速发展,在设计工业自动化,仪器仪表,计算机设计与应用、通信、国防等领域的电子系统中,FPGA技术的含量正以惊人的速度提升。
将尽可能大的完整的电子系统在单一FPGA芯片中实现已成为现实,电子类新技术项目的开发也更多地依赖于FPGA技术的应用。
作为FPGA研究课题之一的矩阵键盘控制接口电路的设计,在FPGA设计中是一个经常被提到的话题,就像是利用PFGA设计数字中一样,虽然简单,但是却是一个很有研究意义的话题,涉及到怎么样才能是FPGA资源更加充分利用,现在很多电子产品都涉及到按键,小的有独立按键,大的有N*N的矩阵键盘,独立按键由于案件的个数少,也就没必要考虑资源的利用问题了。
而矩阵键盘,由于按键多,对整个系统的影响大,所以肯定要考虑资源的利用问题,而且还要考虑一下电路里面的时序问题。
本次设计要求设计一个4*9矩阵键盘,也就是行为4,列为9,一共可以设计36个按键。
其中设计方法为:
一般判断键盘中有没有按键按下是通过航线送入扫描信号,然后从列线中读取状态得到的,其方法是依次给行线送入低电平,检查列线的输入。
如果列线信号趣味高电平,则代表低电平信号所在的行中无按键按下,反之,则有,则在低电平信号所在的行和出现低电平的交叉处有按键按下。
一共有三个模块,分别为:
扫描电路模块、时钟产生模块、键盘译码电路和按键标志位产生电路。
扫描模块中是为了产生扫描信号,来利用扫描信号来扫描键盘中中是否有按键按下。
键盘译码电路和按键标志位产生电路是为了配合扫描模块来扫描电路中是否有按键按下,而且还要求它来产生按键标志信号,以便和外部电路握手。
时钟产生电路是为了产生不同频率的信号,来驱动上面两个电路的运转。
在设计完各个模块后,还要对每个模块进行仿真,在仿真的过程中要对参数精心设计,要不然看不出结果的。
二、课程设计的任务和目的
20世纪90年代,国际上电子和计算机技术较先进的国家,一直在积极探索新的电子电路设计方法,并在设计方法、工具等方面进行了彻底的变革,取得了巨大成功。
在电子技术设计领域,可编程逻辑器件(如CPLD、FPGA)的应用,已得到广泛的普及,这些器件为数字系统的设计带来了极大的灵活性。
这一切极大地改变了传统的数字系统设计方法、设计过程和设计观念,促进了EDA技术的迅速发展。
本次设计在EDA开发平台QUARTUSⅡ7.2上利用VHDL语言设计矩阵键盘控制接口电路。
要求设计一个4×9矩阵键盘,一共有三个模块,分别为:
扫描电路模块、时钟产生模块、键盘译码电路和按键标志位产生电路。
扫描模块中是为了产生扫描信号,来利用扫描信号来扫描键盘中是否有按键按下。
键盘译码电路和按键标志位产生电路也是为了配合扫描模块来扫描电路中是否有按键按下,而且还要求它来产生按键标志信号,以便和外部电路握手。
时钟产生电路是为了产生不同频率的信号,来驱动上面两个电路的运转。
通过对课题的分析研究,掌握了VHDL语言编程方法,同时也增强了个人的学习能力和动手能力。
3、矩阵键盘接口电路的原理与总体设计
本章首先介绍矩阵键盘的设计思路,总体来说行线输出是低电平,一旦有键按下,则输入线就会被拉低,这样,通过读入输入线的状态就可得知是否有键按下了。
最后介绍4*9键盘的总体设计思路。
3.1矩阵键盘接口电路的原理
在键盘中按键数量较多时,为了减少I/O口的占用,通常将按键排列成矩阵形式。
在矩阵式键盘中,每条水平线和垂直线在交叉处不直接连通,而是通过一个按键加以连接。
这样,一个端口就可以构成4*4=16个按键,比之直接将端口线用于键盘多出了一倍,而且线数越多,区别越明显,比如再多加一条线就可以构成20键的键盘,而直接用端口线则只能多出一键(9键)。
由此可见,在需要的键数比较多时,采用矩阵法来做键盘是合理的。
矩阵式结构的键盘显然比直接法要复杂一些,识别也要复杂一些,列线通过电阻接正电源,并将行线所接的FPGA的I/O口作为输出端,而列线所接的I/O口则作为输入。
这样,当按键没有按下时,所有的输出端都是高电平,代表无键按下。
行线输出是低电平,一旦有键按下,则输入线就会被拉低,这样,通过读入输入线的状态就可得知是否有键按下了。
行列式键盘的电路原理如图3.1.1所示:
(为了说明问题以4*4为例)
图3.1.1行列式键盘的电路原理图
设置扫描信号为keydrv3~keydrv0,列线按键输入信号keyin3~keyin0与按键位置的关系如表3.1.1所示:
表3.1.1扫描信号和列线按键输入信号与按键之间的关系表
keydrv3~keydrv0
keyin3~keyin0
对应的按键
1110
1110
1
1101
2
1011
3
0111
4
1110
5
1101
1101
6
1011
7
0111
8
1011
1110
9
1101
0
1011
A
0111
B
1110
C
0111
1101
D
1011
E
0111
F
3.2总体设计
矩阵键盘控制系统的总体设计如图3.2.1所示:
图3.2.1键盘接口电路结构图
由行列式键盘原理就可以知道,要正确的完成键盘输入工作必须有按键扫描电路产生keydrv3~keydrv0信号,同时还必须有按键译码电路从keydrv3~keydrv0信号和keyin3~keyin0信号中译码出按键的值。
此外,一般还需要一个按键发生信号用于和其他模块接口,通知其他模块键盘上有按键动作发生,并可以从键盘上读取按键的键值。
由于各个模块需要的时钟频率是不一样的,因此时钟产生模块就是用于产生各个模块需要的时钟信号。
因此得到键盘接口电路的结构如上图所示。
四、各模块的设计及仿真
4.1键盘扫描电路
键盘扫描电路是用于产生keydrv3~keydrv0信号,其变化的顺序依次是1110---1101---1011---0111---……周而复始地扫描。
其停留在某个状态的时间大约为10ms。
更短的停留时间是没有必要的,因为人按键的时间大约为10ms,不可能有更快的按键动作发生;另外,更短的停留时间还容易采集到抖动信号,会干扰判断,而太长的停留时间则会使某些较快的按键东走丢失。
键盘扫描电路的外部接口电路如图4.1.1所示,其中clk_scan是周期为10ms的扫描时钟,keydrv为输出到键盘的扫描信号,宽度为4位。
图4.1.1键盘扫描电路的外部接口电路图
其VHDL描述如下:
LIBRARYieee;
USEieee.std_logic_1164.all;
ENTITYkey_scanIS
--{{ALTERA_IO_BEGIN}}DONOTREMOVETHISLINE!
PORT
(
clk_scan:
INSTD_LOGIC;--扫描时钟,周期10ms
keydrv:
OUTSTD_LOGIC_VECTOR(3DOWNTO0)
--输出扫描信号
);
--{{ALTERA_IO_END}}DONOTREMOVETHISLINE!
ENDkey_scan;
--ArchitectureBody
ARCHITECTUREkey_scan_architectureOFkey_scanIS
CONSTANTs0:
STD_LOGIC_VECTOR(3DOWNTO0):
="1110";
--定义状态机编码
CONSTANTs1:
STD_LOGIC_VECTOR(3DOWNTO0):
="1101";
CONSTANTs2:
STD_LOGIC_VECTOR(3DOWNTO0):
="1011";
CONSTANTs3:
STD_LOGIC_VECTOR(3DOWNTO0):
="0111";
SIGNALpresent_state:
STD_LOGIC_VECTOR(3DOWNTO0);
--状态机现态
SIGNALnext_state:
STD_LOGIC_VECTOR(3DOWNTO0);
--状态机次态
BEGIN
--状态更新进程
PROCESS(clk_scan)
BEGIN
IF(clk_scan'eventandclk_scan='1')then
present_state<=next_state;
ENDIF;
ENDPROCESS;
--状态译码
PROCESS(present_state)
BEGIN
CASEpresent_stateIS
WHENs0=>next_state<=s1;
WHENs1=>next_state<=s2;
WHENs2=>next_state<=s3;
WHENs3=>next_state<=s0;
--多余状态处理
WHENOTHERS=>next_state<=s0;
ENDCASE;
ENDPROCESS;
--输出译码
keydrv<=present_state;
ENDkey_scan_architecture;
以上程序采用一个状态机来实现扫描电路。
该状态机是一个one-hot状态机,并且输出值就是状态机的状态,没有通过一个逻辑电路来做输出译码。
这样的好处是得到的输出信号比较“干净”,没有毛刺。
其仿真波形如图4.1.2所示:
图4.1.2键盘扫描电路的仿真图
从图4.1.2中很容易发现present_state的值的变化是随着扫描信号key_scan的上升沿的到来而变化的,也就是key_scan每来一个脉冲,相应的present_state的值就变化一次。
很容易发现keydrv的值的变化顺序为1110---1101---1011---0111,也就是每个key_scan来一个脉冲时,保证keydrv相邻的值只有一个变化,这样为了防止产生不必要的毛刺。
present_state值和keydrv值是相同的,只不过一个用的是二进制,一个用的是十进制,所以它的变化为14—13—11—7。
4.2键盘译码电路和按键标志位产生电路
键盘译码电路是从keydrv3~keydrv0和keyin3~keyin0信号中译码出按键的键值的电路,它的真值表就是以前行扫描信号、列扫描与按键位置的关系图。
按键标志位产生电路是产生按键标志位信号keypressed的电路。
由于这两个电路关系紧密,因此放入同一个模块中实现,其外部接口图如图4.2.1所示。
其中clk为局信号,它是由FPGA芯片的外部晶振给出的。
clk在系统中的频率是最高,其他时钟都是它的分频产生。
keydrv为键盘扫描信号,keyin为键盘输入信号,keyvalue为键值(代表按键所在的位置),keypressed表示有一个按键被按下,每发生一次按键动作,keypressed就输出一个宽度为全局时钟周期的正脉冲。
该信号用于与其他模块握手,负责通知其他模块键盘是否有按键发生。
其他模块在keypressed有效时,可以读取键值。
图4.2.1键盘译码电路的外部接口
其VHDL实现如下:
LIBRARYieee;
USEieee.std_logic_1164.all;
USEieee.std_logic_arith.all;
ENTITYkeydecoderIS
PORT(
clk:
INSTD_LOGIC;--全局时钟
clk_scan:
INSTD_LOGIC;--扫描时钟
keyin:
INSTD_LOGIC_VECTOR(8DOWNTO0);--键盘输入
keydrv:
INSTD_LOGIC_VECTOR(3DOWNTO0);--扫描信号
keyvalue:
OUTSTD_LOGIC_VECTOR(8DOWNTO0);--键值
keypressed:
OUTSTD_LOGIC--有按键按下
);
ENDkeydecoder;
ARCHITECTUREkeydecoder_architectureOFkeydecoderIS
--TEMP<=keyin&keydrv;
SIGNALtemp:
STD_LOGIC_VECTOR(12DOWNTO0);
SIGNALtemp_pressed:
STD_LOGIC;
SIGNALkeypressed_asy:
STD_LOGIC;
SIGNALq1,q2,q3,q4,q5,q6:
STD_LOGIC;
BEGIN
temp<=keyin&keydrv;
--译码进程
参见附录程序
--按键标志产生电路
process(clk_scan)
begin
if(clk_scan'eventandclk_scan='1')then
q1<=temp_pressed;
q2<=q1;
q3<=q2;
q4<=q1;
endif;
keypressed_asy<=q1orq2orq3orq4;
endprocess;
--同步化keypressed_asy
process(clk)
begin
if(clk'eventandclk='1')then
q5<=keypressed_asy;
q6<=q5;
endif;
keypressed<=q5andnot(q6);
endprocess;
ENDkeydecoder_architecture;
上面程序是改进的程序,原程序是:
--同步化有键被按下
PROCESS(clk)
BEGIN
IF(clk'eventandclk='1')THEN
q1<=temp_pressed;
q2<=q1;
ENDIF;
keypressed<=q1andnot(q2);
ENDPROCESS;
ENDkeydecoder_architecture;
上面程序中有两个进程。
第一个进程负责译码,值得注意的是WHENOTHEN语句有没有对temp_pressed和keyvalue信号赋值,这相当于不改变temp_presed和keyvalue信号的值,即实现了锁存输出。
在不需要锁存输出时,在WHENO-THEN语句中,一定要对所有的case语句中出现的信号逐一赋值,以免产生意想不到的结果。
第二个进程负责把按键同步信号同步化与全局时钟同步的并且脉宽为一个周期的脉冲。
重新编写按键发生标志电路,该电路不仅要解决按键抖动导致一次按键被当成多次的问题,同时还要解决按键太长导致一次按键被当成多次的问题。
考虑这些因素之后,编写的程序应该是阴影部分的程序。
该电路的仿真结果如图4.2.2所示:
图4.2.2键盘译码电路仿真图
通过仿真波形图可以看出,按键的抖动不会影响输出结果;无论一个按键动作持续时间有多久,但仍然认为是一个按键。
4.3时钟产生模块
时钟产生模块是用于扫描时钟的,它的输出供给给键盘扫描模块和按键标志位的产生模块,其外部接口图如图4.3.1所示:
图4.3.1时钟产生模块外部接口电路
其VHDL实现如下:
LIBRARYieee;
USEieee.std_logic_1164.all;
USEieee.std_logic_ARITH.all;
ENTITYclk_genIS
PORT
(clk:
INSTD_LOGIC;--全局时钟
clk_scan:
OUTSTD_LOGIC--扫描时钟
);
ENDclk_gen;
ARCHITECTUREclk_gen_architectureOFclk_genIS
--做程序仿真时,用这个语句
signalcnt:
integerrange0to150;
--需要下载到芯片上时,替换为下面这个语句
signalcnt:
integerrange0to119999;
begin
--计数模块
process(clk)
begin
if(clk'eventandclk='1')then
if(cnt=cnt'high)then
cnt<=0;
else
cnt<=cnt+1;
endif;
endif;
endprocess;
--译码输出
process(cnt,clk)
begin
if(clk'eventandclk='1')then
ifcnt>=cnt'high/2then
clk_scan<='1';
else
clk_scan<='0';
endif;
endif;
endprocess;
ENDclk_gen_architecture;
该程序主要包含有一个计数器模块和一个译码输出模块,该程序是通过计数器模块实现分频的。
要从12MHZ全局时钟得到100HZ的时钟,必须进行120000倍的分频。
这么大的分频需要仿真时间很久。
仿真时一般采用小分频来代替,(在本程序中采用150分频来仿真)以便快速观察到结果。
等到真正下载到电路上时,就需要采用120000分频了。
该电路的仿真结果如图4.3.2所示:
图4.3.2时钟产生模块的仿真图
4.4键盘接口电路顶层电路实现
键盘接口电路的顶层电路只是把键盘扫描模块、键盘译码且按键标志位产生模块和时钟产生模块连接起来,其结构如图4.4.1所示:
图4.4.1键盘接口电路的顶层电路
该电路的仿真波形如图4.4.2所示:
图4.4.2键盘接口电路的顶层电路仿真图
五、参考文献
[1]潘松,黄继业.EDA技术实用教程[M].北京:
科学出版社,2010.
[2]黄正槿,徐坚.CPLD系统设计技术入门与应用[M].北京:
电子工业出版社,2006.
[3]徐惠民,安德宁.数字逻辑设计与VHDL描述[M].北京:
机械工业出版社,2008.
[4]周国祥.汇编语言程序设计[M].合肥:
合肥工业大学出版社,2010.
[5]赵曙光.可编程逻辑器件原理开发与应用[M].西安:
西安电子科技大学出版社,2008.
[6]求是科技.CPLD/FPGA应用开发技术与工程实践[M].北京:
人民邮电出版社,2007.
六、心得体会
矩阵式键盘是一种常见的输入装置,在日常的生活中,矩阵式键盘在计算机、电话、手机、微波炉等电子产品上已被广泛应用,各式各样的矩阵键盘控制着各种各样的功能。
矩阵键盘控制接口电路是最基本的输入电路,我们利用软件QuartusII自行设计并修改的键盘输入显示电路是通过VHDL语言的编写并实现了键码的对应显示,在设计中发现了许多问题,比如去按键抖动,这个过程很有意思但却很繁琐,在利用QuartusII进行仿真的时候,要细心地对参数进行设置,最后才能够仿真出结果。
本次设计中最为突出的是对键盘译码电路和按键标志位产生电路的设计,主要是去抖动,其中重要一点是按键去抖动电路不仅要解决按键抖动导致一次按键被当成多次的问题,同时还要解决按键太长导致一次按键被当成多次的问题。
否则,当设计的键盘在实际中应用的时候,就会出现错误,所以应该把之前的程序重新编写。
在新程序中:
◆多了一个输入信号clk_scan,它是用于产生扫描信号的时钟,周期为10ms。
◆按键信号tepm_pressed首先通过clk_scan信号的上升沿采样,通过采样后,抖动噪声被消除。
◆采样后得到信号被分别延迟1~4个clk_csan周期得到4个信号q1、q2、q3、q4。
这四个信号进行或运算得到一个宽度约为80ms并且与全局时钟异步的按键信号keypressed_asy。
原来程序中一个长时间的按键过程有可能被认为是多次按键,通过这种方法使得一个长时间的按键仍然是一次按键。
◆把keypressed_asy同步化。
◆消除了按键抖动。
七、附录
7.1源程序代码
PROCESS(temp)
BEGIN
casetempis
when"1111111101110"=>keyvalue<=conv_std_logic_vector(1,9);
temp_pr