VHDL键盘扫描.docx

上传人:b****5 文档编号:14939388 上传时间:2023-06-28 格式:DOCX 页数:48 大小:533.28KB
下载 相关 举报
VHDL键盘扫描.docx_第1页
第1页 / 共48页
VHDL键盘扫描.docx_第2页
第2页 / 共48页
VHDL键盘扫描.docx_第3页
第3页 / 共48页
VHDL键盘扫描.docx_第4页
第4页 / 共48页
VHDL键盘扫描.docx_第5页
第5页 / 共48页
VHDL键盘扫描.docx_第6页
第6页 / 共48页
VHDL键盘扫描.docx_第7页
第7页 / 共48页
VHDL键盘扫描.docx_第8页
第8页 / 共48页
VHDL键盘扫描.docx_第9页
第9页 / 共48页
VHDL键盘扫描.docx_第10页
第10页 / 共48页
VHDL键盘扫描.docx_第11页
第11页 / 共48页
VHDL键盘扫描.docx_第12页
第12页 / 共48页
VHDL键盘扫描.docx_第13页
第13页 / 共48页
VHDL键盘扫描.docx_第14页
第14页 / 共48页
VHDL键盘扫描.docx_第15页
第15页 / 共48页
VHDL键盘扫描.docx_第16页
第16页 / 共48页
VHDL键盘扫描.docx_第17页
第17页 / 共48页
VHDL键盘扫描.docx_第18页
第18页 / 共48页
VHDL键盘扫描.docx_第19页
第19页 / 共48页
VHDL键盘扫描.docx_第20页
第20页 / 共48页
亲,该文档总共48页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

VHDL键盘扫描.docx

《VHDL键盘扫描.docx》由会员分享,可在线阅读,更多相关《VHDL键盘扫描.docx(48页珍藏版)》请在冰点文库上搜索。

VHDL键盘扫描.docx

VHDL键盘扫描

VHDL键盘扫描

一、设计目的

巩固和运用所学课程,理论联系实际,提高分析、解决计算机技术实际问题的独立工作能力,通过对FPGA几个简单的模块设计,进一步加深对计算机原理以及数字电路应用技术方面的了解与认识,进一步熟悉数字电路系统设计、制作与调试的方法和步骤。

二、设计内容

(1)设计一个4×4的键盘扫描模块,要求有防抖动功能。

(2)用键盘控制16×16点阵LED显示各种字符。

(3)用键盘控制蜂鸣器发声,能有各种音调。

三、实现方法

本系统的系统组成及连接原理如图3.1所示,主系统由四个功能模块组成:

分频模块(为键盘扫描模块和提供时钟)、键盘扫描模块、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口的线组成行列结构,按键设置在行列的交点上。

本次试验用到的是4×4的行列结构键盘,可以构成16个按键。

这样,当按键数量平方增长是,I/O口只是线性增长,这样就可以节省I/O口。

行列式键盘的原理如图3.4所示。

keyin上拉电阻

 

keydrv

 

图3.4行列式键盘的原理

按键设置在行列线交叉点,行、列线分别连接到按键开关的两端。

列线通过上拉电阻接+5V的电压,即列线的输出被嵌位在高电平状态。

判断按键中有无键按下时通过行线输入扫描信号,然后从列线读取到状态实现的。

其方法是依次给行线送低电平,检查列线的输入。

如果列线信号全为高电平,则代表低电平所在的行中无按键按下;如果列线有输入为低电平,则低电平信号所在的行和出现低电平的列的交点处有按键按下。

设行扫描信号为keydrv3~keydrv0,列线按键输入信号keyin3~keyin0与按键位置的关系如表3.1所示

表3.1行扫描信号、列线按键输入信号与按键位置的关系

keydrv3~keydrv0

keyin3~keyin0

对应的按键

1110

1110

0

1101

1

1011

2

0111

3

1101

1110

4

1101

5

1011

6

0111

7

1011

1110

8

1101

9

1011

A

0111

B

0111

1110

C

1101

D

1011

E

0111

F

2.2键盘扫描系统模块划分

图3.5键盘扫描系统模块划分

键盘扫描电路时用于产生keydrv3-keydrv0信号,其变化顺序为1110→1101→1011→0111……周而复始的扫描。

其停留在每个状态的时间大约有10ms。

扫描电路的模型如下:

图3.6扫描电路外观接口

扫描电路的仿真如图3.7所示:

图3.7扫描电路仿真

键盘译码电路是从keydrv3~keydrv0和keyin3~keyin0译出按键值的电路,它的真值表如表1所示。

键盘译码电路的模型如图3.8所示:

图3.8键盘译码电路外观

其中键值keycode用5位编码,keycode为00000~01111表示键值0~F,keycode为11111时表示无按键按下。

译码电路的仿真如图3.9所示:

图3.9译码电路仿真

图3.9仿真的是扫描信号在keydrv=1011时有按键按下,并且keyin=0111时的键值,由表1可知这时的键值因该是B,而由图中可以看出仿真结果是5’h0B,即预测结果与仿真结果一致。

2.3按键去抖动电路实现

由于机械触点的弹性作用,触点在闭合和断开瞬间的电接触情况不稳定,造成了电压信号的抖动现象,如图3.10所示。

键的抖动时间一般为5~10ms。

这种现象会引起FPGA对于一次键操作进行多次处理,因此须设法消除键接通或断时的抖动现象。

去抖动的方法有硬件和软件两种:

硬件去抖动和软件去抖动。

图3.10按键抖动现象

去抖动模块采用多次连续检测输入键值的原理防抖。

当检测到有键值输入时并不马上输出,而是当16次输入的键值都一样时才输出,其中只要有一次键值不同的话计数器都会置零,重新记数。

这样就能消除按键的抖动影响。

其模块外观如图3.11所示。

图3.11去抖动模块外观

按键去抖动仿真:

图3.12按键去抖动仿真

由仿真图形可以看出,输入keyvaluein开始和结束时都产生抖动,但经过去抖模块后抖动消失了。

起到了去抖动的功能。

3、16×16LED点阵显示屏的设计

3.116x16LED点阵的工作原理及连接组成方式:

16x16LED点阵的工作原理同8x8LED点阵的工作原理,图3.13是8x8的LED点阵单色行共阳模块的内部结构图,其单点工作电压Uf为1.8V,正向电流IF为8~10mA。

当某一行线为高电平而某一列线为低时,其行列交叉的点就被点亮;而当其某一列线为高时,其行列交叉的点为暗;当某一行线为低电平时,无论列线如何,对应这一行的点全部为暗。

图3.13:

8x8的LED点阵单色行共阳模块的内部结构图

本实验采用的16x16LED点阵用四个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点阵显示构成的16x16LED点阵

3.216x16LED点阵的驱动方式

本实验采用动态扫描型驱动方式显示,即显示屏上的16行发光二极管共用一组列驱动寄存器,然后通过行驱动管的分时工作,来使每行LED的点亮时间占总时间的1/16。

只要每行的刷新速率大于50Hz,利用人眼的视觉暂留效应,人们就可以看到一幅完整的文字或画面。

扫描驱动分行扫描驱动和列扫描驱动。

由于16x16点阵显示器有16行,故使用行扫描信号,本电路中加入了一个4-16线译码器,其输入是一个频率为1000Hz的时钟信号,内部采用4位二进制加法器,分别为0000~1111,然后使每种状态只控制一路输出,解码输出为低态扫描信号,即会有16路输出。

本实验的列信号由事先存于寄存器中的16进制码构成,每个矩阵表示一个字符的列扫描信号,伴随行扫描信号进行交替的扫描,其设计图见附录中16x16LED点阵扫描设计草图。

本实验所显示的字符由键盘编码所确定,其编码与显示字符对应的关系如表3.2所示:

表3.2:

键盘编码与对应显示字符

键盘编码

00000

00001

00010

00011

显示字符

0

1

2

3

键盘编码

00100

00101

00110

00111

显示字符

4

5

6

7

键盘编码

01000

01001

01010

01011

显示字符

8

9

A

B

键盘编码

01100

01101

01110

01111

显示字符

C

D

E

F

键盘编码

11111

显示字符

音符图形

3.316x16LED点阵驱动电路

16x16LED点阵驱动外观电路如图3.15所示:

图3.1516x16LED点阵驱动电路外观

16x16LED点阵驱动电路原理图如图3.16所示:

图3.16:

16x16LED点阵驱动电路原理图

驱动行信号仿真如图3.17所示:

图3.17驱动行信号

4、发声模块

4.1音调的产生

音调的产生是通过分频实现的。

设计要求产生不同的音调,就需要不同的分频器。

可以先构造一个分频器,然后通过VHDL中的参数传递语句构造出十二个不同的分频器,其分频数见表3.2(输入时钟是2MHz)。

表3.3音符频率对照表

键值

音符

频率

分频数

键值

音符

频率

分频数

0

低5

392

5102.0408

7

中5

784

2551.0204

1

低6

440

4545.4545

8

中6

880

2272.7273

2

低7

494

4048.583

9

中7

988

2024.2915

3

中1

523

3824.0918

A

高1

1046

1912.0459

4

中2

578

3460.2076

B

高2

1175

1702.1277

5

中3

659

3034.9014

C

高3

1318

1517.4507

6

中4

698

2865.3295

D

高4

1397

1431.6392

4.2电路实现

发声模块其内部是一个有一个输入,十二个输出的分频器,用于产生十二种音调。

然后根据键值判断哪个口输出。

其顶层视图如图3.18所示。

图3.18发声模块外观

发声模块的仿真见图3.19

图3.19发声模块仿真

仿真波形中l5~h4是分频器的十二个输出口,当键值是C时speaker输入的是h3的值,达到了要求。

5、顶层模块实现

顶层电路只是把分频模块、键盘扫描模块、LED点阵模块和发声模块连接起来,其外观和内部结构如图3.20和3.21所示。

图3.20顶层模块外观

图3.21顶层模块内部结构

6、管脚的定义

管脚的定义如表3.4所示

表3.4管脚的定义

I/OName

I/ODirection

Loc

Bank

clk

Input

P3

BANK7

Speaker

Output

P95

BANK4

keydrv<0>

Output

P120

BANK3

keydrv<1>

Output

P121

BANK3

keydrv<2>

Output

P122

BANK3

keydrv<3>

Output

P123

BANK3

keyin<0>

Input

P125

BANK3

keyin<1>

Input

P127

BANK3

keyin<2>

Input

P129

BANK3

keyin<3>

Input

P132

BANK2

LEDcolumn<0>

Output

P133

BANK2

LEDcolumn<1>

Output

P134

BANK2

LEDcolumn<2>

Output

P136

BANK2

LEDcolumn<3>

Output

P138

BANK2

LEDcolumn<4>

Output

P139

BANK2

LEDcolumn<5>

Output

P140

BANK2

LEDcolumn<6>

Output

P141

BANK2

LEDcolumn<7>

Output

P147

BANK2

LEDcolumn<8>

Output

P148

BANK2

LEDcolumn<9>

Output

P149

BANK2

LEDcolumn<10>

Output

P150

BANK2

LEDcolumn<11>

Output

P151

BANK2

LEDcolumn<12>

Output

P152

BANK2

LEDcolumn<13>

Output

P162

BANK1

LEDcolumn<14>

Output

P163

BANK1

LEDcolumn<15>

Output

P164

BANK1

LEDrow<0>

Output

P165

BANK1

LEDrow<1>

Output

P167

BANK1

LEDrow<2>

Output

P73

BANK5

LEDrow<3>

Output

P74

BANK5

LEDrow<4>

Output

P70

BANK5

LEDrow<5>

Output

P71

BANK5

LEDrow<6>

Output

P68

BANK5

LEDrow<7>

Output

P69

BANK5

LEDrow<8>

Output

P63

BANK5

LEDrow<9>

Output

P67

BANK5

LEDrow<10>

Output

P61

BANK5

LEDrow<11>

Output

P62

BANK5

LEDrow<12>

Output

P59

BANK5

LEDrow<13>

Output

P60

BANK5

LEDrow<14>

Output

P57

BANK5

LEDrow<15>

Output

P58

BANK5

附录Ⅰ程序代码

1、顶层模块

libraryIEEE;

useIEEE.STD_LOGIC_1164.ALL;

useIEEE.STD_LOGIC_ARITH.ALL;

useIEEE.STD_LOGIC_UNSIGNED.ALL;

----Uncommentthefollowinglibrarydeclarationifinstantiating

----anyXilinxprimitivesinthiscode.

--libraryUNISIM;

--useUNISIM.VComponents.all;

entityplay_showis

Port(clk:

inSTD_LOGIC;

keyin:

inSTD_LOGIC_VECTOR(3downto0);

keydrv:

outSTD_LOGIC_VECTOR(3downto0);

LEDrow:

outSTD_LOGIC_VECTOR(15downto0);--LED行扫描信号

LEDcolumn:

outSTD_LOGIC_VECTOR(15downto0);

Displayshow:

outSTD_LOGIC_VECTOR(6downto0);

Displayselect:

outSTD_LOGIC_VECTOR(3downto0);

speaker:

outSTD_LOGIC);

endplay_show;

architecturertlofplay_showis

componentfreq_division

Port(clk:

inSTD_LOGIC;

clkout_kb:

outSTD_LOGIC;

clkout_LED:

outSTD_LOGIC;

clkout_display:

outstd_logic);

endcomponent;

componentkeyboard

Port(clk:

inSTD_LOGIC;--扫描时钟,周期10ms

keyin:

inSTD_LOGIC_VECTOR(3downto0);

keydrv:

outSTD_LOGIC_VECTOR(3downto0);

keyvalue:

outSTD_LOGIC_VECTOR(4downto0));--输出扫描信号

endcomponent;

componentLEDArray

Port(clk:

inSTD_LOGIC;--时钟信号,经分灯鞯玫1ms脉冲

keycode:

inSTD_LOGIC_VECTOR(4downto0);--键盘给的编码

LEDrow:

outSTD_LOGIC_VECTOR(15downto0);--LED行扫描信号

LEDcolumn:

outSTD_LOGIC_VECTOR(15downto0)--LED列信号

);

endcomponent;

componentplay

port(clk:

inSTD_LOGIC;

keyvalue:

inSTD_LOGIC_VECTOR(4downto0);

speaker:

outSTD_LOGIC);

endcomponent;

componentIBUF

port(I:

instd_logic;O:

outstd_logic);

endcomponent;

componentDisplay

Port(Keyvalue:

inSTD_LOGIC_VECTOR(4downto0);

clk:

inSTD_LOGIC;

Display:

outSTD_LOGIC_VECTOR(6downto0);

Diselect:

outSTD_LOGIC_VECTOR(3downto0));

endcomponent;

--signalclkin:

STD_LOGIC;

signalclkout_kb,clkout_LED,clkout_display:

STD_LOGIC;

--signalkeydrv1:

STD_LOGIC_VECTOR(3downto0);

signalkeyvalue1:

STD_LOGIC_VECTOR(4downto0);

signalCLK_SIG:

std_logic;

begin

--keydrv<=keydrv1;

U1:

IBUFportmap(I=>clk,O=>CLK_SIG);

U2freq_division:

freq_division

portmap(CLK_SIG,clkout_kb,clkout_LED,clkout_display);

U3keyboard:

keyboard

portmap(clkout_kb,keyin,keydrv,keyvalue1);

U4LEDArray1616:

LEDArray

portmap(clkout_LED,keyvalue1,LEDrow,LEDcolumn);

U5Uplay:

play

portmap(CLK_SIG,keyvalue1,speaker);

U6Display:

Display

portmap(keyvalue1,clkout_display,Displayshow,Displayselect);

endrtl;

2、分频器

entityfredivnis

generic(N:

integer:

=2);

Port(clkin:

inSTD_LOGIC;

clkout:

outSTD_LOGIC);

endfredivn;

architectureBehavioraloffredivnis

signalclk1:

std_logic:

='0';

signalcounter:

integerrange0ton;

begin

process(clkin)

begin

ifrising_edge(clkin)then

ifcounter=(n-1)/2then

clk1<=notclk1;

counter<=0;

else

counter<=counter+1;

endif;

endif;

endprocess;

clkout<=clk1;

endBehavioral;

3、总分频器

entityfreq_divisionis

Port(clk:

inSTD_LOGIC;

clkout_kb:

outSTD_LOGIC;

clkout_LED:

outSTD_LOGIC;

clkout_display:

outSTD_LOGIC);

endfreq_division;

architectureRTLoffreq_divisionis

componentfredivnis

generic(N:

positive);

Port(clkin:

inSTD_LOGIC;

clkout:

outSTD_LOGIC);

endcomponent;

begin

U1:

fredivn

genericmap(N=>kb_N)

portmap(clk,clkout_kb);

U2:

fredivn

genericmap(N=>LED_N)

portmap(clk,clkout_LED);

U3:

fredivn

genericmap(N=>display_N)

portmap(clk,clkout_display);

endRTL;

4、键盘扫描驱动

entitykeyscanis

Port(clkin:

inSTD_LOGIC;--扫描时钟,周期20ms

keydrv:

outSTD_LOGIC_VECTOR(3downto0));--输出扫描信号

endkeyscan;

architecturebehavioralofkeyscanis

signalcount:

std_logic_vector(1downto0):

="00";--计数器信号

begin

process(clkin)

begin

ifrising_edge(clkin)then

ifcount="11"then

count<="00";

else

count<=count+1;

endif;

endif;

endprocess;

process(count)

begin

casecountis

when"00"=>keydrv<="1110";

when"01"=>keydrv<="1101";

when"10"=>keydrv<="1011";

when"11"=>keydrv<="0111";

whenothers=>keydrv<="0000";

endcase;

endprocess;

endbehavioral;

5、键盘编码

entitykeydecoderis

Port(clkin:

instd_logic;

keyin:

inSTD_LOGIC_VECTOR(3downto0);

keydrv:

inSTD_LOGIC_VECTOR(3downto0);

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 医药卫生 > 基础医学

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2