VHDL键盘扫描Word文档格式.docx
《VHDL键盘扫描Word文档格式.docx》由会员分享,可在线阅读,更多相关《VHDL键盘扫描Word文档格式.docx(41页珍藏版)》请在冰豆网上搜索。
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
显示字符
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音符频率对照表
键值
音符
频率
分频数
低5
392
5102.0408
中5
784
2551.0204
低6
440
4545.4545
中6
880
2272.7273
低7
494
4048.583
中7
988
2024.2915
中1
523
3824.0918
高1
1046
1912.0459
中2
578
3460.2076
高2
1175
1702.1277
中3
659
3034.9014
高3
1318
1517.4507
中4
698
2865.3295
高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>
P120
BANK3
1>
P121
2>
P122
3>
P123
keyin<
P125
P127
P129
P132
BANK2
LEDcolumn<
P133
P134
P136
P138
4>
P139
5>
P140
6>
P141
7>
P147
8>
P148
9>
P149
10>
P150
11>
P151
12>
P152
13>
P162
BANK1
14>
P163
15>
P164
LEDrow<
P165
P167
P73
BANK5
P74
P70
P71
P68
P69
P63
P67
P61
P62
P59
P60
P57
P58
附录Ⅰ程序代码
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:
Displayshow:
outSTD_LOGIC_VECTOR(6downto0);
Displayselect:
speaker:
outSTD_LOGIC);
endplay_show;
architecturertlofplay_showis
componentfreq_division
Port(clk:
inSTD_LOGIC;
clkout_kb:
outSTD_LOGIC;
clkout_LED:
clkout_display:
outstd_logic);
endcomponent;
componentkeyboard
Port(clk:
--扫描时钟,周期10ms
keydrv:
outSTD_LOGIC_VECTOR(3downto0);
keyvalue:
outSTD_LOGIC_VECTOR(4downto0));
--输出扫描信号
componentLEDArray
--时钟信号,经分灯鞯玫1ms脉冲
keycode:
inSTD_LOGIC_VECTOR(4downto0);
--键盘给的编码
LEDrow:
outSTD_LOGIC_VECTOR(15downto0)--LED列信号
);
componentplay
port(clk:
keyvalue:
inSTD_LOGIC_VECTOR(4downto0);
speaker:
outSTD_LOGIC);
componentIBUF
port(I:
instd_logic;
O:
outstd_logic);
componentDisplay
Port(Keyvalue:
inSTD_LOGIC_VECTOR(4downto0);
clk:
Display:
Diselect:
outSTD_LOGIC_VECTOR(3downto0));
--signalclkin:
STD_LOGIC;
signalclkout_kb,clkout_LED,clkout_display:
--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:
clkout:
endfredivn;
architectureBehavioraloffredivnis
signalclk1:
std_logic:
='
0'
;
signalcounter:
integerrange0ton;
process(clkin)
ifrising_edge(clkin)then
ifcounter=(n-1)/2then
clk1<
=notclk1;
counter<
=0;
else
=counter+1;
endif;
endprocess;
clkout<
=clk1;
endBehavioral;
3、总分频器
entityfreq_divisionis
endfreq_division;
architectureRTLoffreq_divisionis
componentfredivnis
generic(N:
positive);
endcomponent;
U1:
fredivn
genericmap(N=>
kb_N)
portmap(clk,clkout_kb);
U2:
LED_N)
portmap(clk,clkout_LED);
U3:
display_N)
portmap(clk,clkout_display);
endRTL;
4、键盘扫描驱动
entitykeyscanis
Port(clkin:
--扫描时钟,周期20ms
outSTD_LOGIC_VECTOR(3downto0));
endkeyscan;
architecturebehavioralofkeyscanis
signalcount:
std_logic_vector(1downto0):
="
00"
--计数器信号
process(clkin)
begin
ifrising_edge(clkin)then
ifcount="
11"
then
count<
else
=count+1;
endif;
endif;
endprocess;
process(count)
casecountis
when"
=>
1110"
01"
1101"
10"
1011"
0111"
whenothers=>
0000"
endcase;
endbehavioral;
5、键盘编码
entitykeydecoderis
keyin:
keycode:
outSTD_LOGIC_VECTOR(4downto0));
endkeydecoder;
architectureRtlofkeydecoderis
signaltemp:
STD_LOGIC_VECTOR(7downto0);
signalkeyvalue1:
STD_LOGIC_VECTOR(4downto0):
11111"
signalcount:
std_logic_vector(1downto0):
--signalkeypressed:
boolean:
=false;
--signalq1,q2,q3,q4:
boolean;
temp<
=keydrv&
keyin;
begin
iffalling_edge(clkin)then
ifkeyin="
1111"
keyvalue1<
else
count<
casetempis
when"
11101110"
keyvalue1<
00000"
11101101"
00001"
11101011"
00010"
11100111"
00011"
11011110"
00100"
11011101"
00101"
11011011"
00110"
11010111"
00111"
10111110"
01000"
10111101"
01001"
10111011"
01010"
10110111"