矩阵键盘按键的数码管显示矩阵键盘按键的数码管显示.docx

上传人:b****7 文档编号:26363637 上传时间:2023-06-18 格式:DOCX 页数:27 大小:503.77KB
下载 相关 举报
矩阵键盘按键的数码管显示矩阵键盘按键的数码管显示.docx_第1页
第1页 / 共27页
矩阵键盘按键的数码管显示矩阵键盘按键的数码管显示.docx_第2页
第2页 / 共27页
矩阵键盘按键的数码管显示矩阵键盘按键的数码管显示.docx_第3页
第3页 / 共27页
矩阵键盘按键的数码管显示矩阵键盘按键的数码管显示.docx_第4页
第4页 / 共27页
矩阵键盘按键的数码管显示矩阵键盘按键的数码管显示.docx_第5页
第5页 / 共27页
点击查看更多>>
下载资源
资源描述

矩阵键盘按键的数码管显示矩阵键盘按键的数码管显示.docx

《矩阵键盘按键的数码管显示矩阵键盘按键的数码管显示.docx》由会员分享,可在线阅读,更多相关《矩阵键盘按键的数码管显示矩阵键盘按键的数码管显示.docx(27页珍藏版)》请在冰豆网上搜索。

矩阵键盘按键的数码管显示矩阵键盘按键的数码管显示.docx

矩阵键盘按键的数码管显示矩阵键盘按键的数码管显示

一、矩阵键盘按键的数码管显示

1.实验目的

(1)掌握VHDL语言的语法规范,掌握时序电路描述方法

(2)掌握多个数码管动态扫描显示的原理及设计方法

2.实验所用仪器及元器件

计算机一台实验板一块电源线一根扁平线一根下载线一根

3.实验任务

要求设计出4*4矩阵键盘对某一按键按下就在数码管显示一个数字。

按键从左上角到右下角依次为1,2,…,16。

4.实验原理

按键模块原理

键盘扫描的实现过程如下:

对于4×4键盘,通常连接为4行、4列,因此要识别按键,只需要知道是哪一行和哪一列即可,为了完成这一识别过程,我们的思想是,首先固定输出4行为高电平,然后输出4列为低电平,在读入输出的4行的值,通常高电平会被低电平拉低,如果读入的4行均为高电平,那么肯定没有按键按下,否则,如果读入的4行有一位为低电平,那么对应的该行肯定有一个按键按下,这样便可以获取到按键的行值。

同理,获取列值也是如此,先输出4列为高电平,然后在输出4行为低电平,再读入列值,如果其中有哪一位为低电平,那么肯定对应的那一列有按键按下。

键盘键值的获取:

键盘上的每一个按键其实就是一个开关电路,当某键被按下时,该按键的接点会呈现0的状态,反之,未被按下时则呈现逻辑1的状态。

扫描信号由row进入键盘,变化的顺序依次为1110-1101-1011-0111-1110。

每一次扫描一排,依次地周而复始。

例如现在的扫描信号为1011,代表目前正在扫描9,10,11,12这一排的按键,如果这排当中没有按键被按下的话,则由column读出的值为1111;反之当9这个按键被按下的话,则由column读出的值为1110。

根据上面所述原理,我们可得到各按键的位置与数码关系如表所示:

row

1110

1110

1110

1110

1101

1101

1101

1101

column

1110

1101

1011

0111

1110

1101

1011

0111

键值

1

2

3

4

5

6

7

8

row

1011

1011

1011

1011

0111

0111

0111

0111

column

1110

1101

1011

0111

1110

1101

1011

0111

键值

9

10

11

12

13

14

15

16

动态显示原理

为使得输入控制电路简单且易于实现,采用动态扫描的方式实现设计要求。

动态扫描显示需要由两组信号来控制:

一组是字段输出口输出的字形代码,用来控制显示的字形,称为段码;另一组是位输出口输出的控制信号,用来选择第几位数码管工作,称为位码。

各位数码管的相同段是并联的,段码的输出对各位数码管来说都是相同的。

因此在同一时刻如果各位数码管都处于点亮状态,6位数码管将显示相同的字符。

若要各位数码管能够显示出与本位相应的字符,就必须采用扫描显示方式,即在某一时刻,只让某一位处于点亮状态,而其它各位处于灭灯状态。

同时,段码输出相应位要显示字符的字型码。

这样在同一时刻,只有选通的那一位显示出字符,而其它各位则是熄灭的,如此循环下去,就可以使各位数码管显示出要显示的字符。

虽然这些字符是在不同时刻出现的,而且同一时刻,只有一位显示,其它各位熄灭,但由于数码管具有余辉特性和人眼有视觉暂留现象,只要每位数码管显示间隔足够短,给人眼的视觉印象就会是连续稳定地显示。

总之,多个数码管动态扫描显示,是将所有数码管的相同段并联在一起,通过选通信号分时控制各个数码管的公共端,循环点亮多个数码管,并利用人眼的视觉暂留现象,只要扫描的频率大于50Hz,将看不到闪烁现象。

5.设计思路

该程序可分为两个模块:

获取并存储键值模块和动态显示模块

获取并存储键值模块:

此次实验只要求仿真而不需要接硬件,因而不存在按键这个动作,所以键盘扫描原理在这里并不适用。

在程序设计中我们将row和column都设置为输入信号,则低电平出现的行和列所交处即为按键处,以此简单模拟按键。

根据上表所列,将对应按键的键值存储在key_code中。

这样就完成了键值的存储。

动态显示模块:

此次实验只需用到两个显示数码管,因此只要用一个高频时钟信号控制这两个数码管交替亮灭,并在对应位显示正确的键值,就完成动态显示了。

综上就可以实现矩阵案件的数码管显示了。

具体流程图如下:

6.仿真波形

当row=1110,column=1110时,key_code=0000,键值为1,所以第一个数码管不亮,第二个数码管显示1,如下图:

当row=0111,column=0111时,key_code=1111,键值为16,所以第一个数码管显示1,第二个数码管显示6,如下图:

7.硬件实现

以上步骤都完成后,在硬件上实现就比较简单了。

此时要注意两个问题:

第一,时钟频率的设置,在仿真时由于没有外在时钟源,所以把row和column都设置为手动输入,但当在硬件上实现时要采用实验板上的低频时钟源,并设计分频电路提供合适的时钟频率。

这就需要对程序做相应的修改;第二,管脚号的编写,根据各实物图纸标号和ATF1508的对应关系编写对应管脚号。

接下来要做的就是硬件连接,然后就是下载程序。

程序通过编译后生成*.pof文件,用pof2jed软件将文件转换为jed格式,然后用AtmelISP软件实现下载。

如果下载成功的话,就能实现从左上到右下按键分别显示数字1-16。

8.实物展示

 

二、数码管学号滚动显示

1.实验目的

(1)掌握VHDL语言的语法规范,掌握时序电路描述方法

(2)掌握多个数码管动态扫描显示的原理及设计方法

2.实验所用仪器及元器件

计算机一台实验板一块电源线一根扁平线一根下载线一根

3.实验任务

要求学生在六个数码管滚动显示自己的学号(六位),每隔一定时间循环移位一次,学号为奇数则左移,学号为偶数则右移。

间隔时间可由开关选择1秒,2秒,3秒和4秒。

4.实验原理

该实验同样主要用到按键模块和数码管的动态显示,实验原理和实验一所阐述的相同。

5.设计思路

循环右滚动,始终点亮6个数码管,左出右进。

状态为:

010506-105060-050601-506010-060105-601050-010506

主要思路如下:

(1)加入按键控制,主要用到4个键,用来选择不同的移位周期。

具体实现方案是引入一个变量time_count,用时钟信号和按键值来控制time_count的累加周期,从而控制移位周期。

例如当按2键,key_code=0001,time_count以000,001为周期循环计数(即2s),每循环一次,shift就加1即移位周期为2s(shift控制移位)。

以此类推,可以选择1s,2s,3s,4s不同的移位周期。

(2)为实现移位,关键改动为新增一个计数器,计数周期远远大于扫描周期,这样,在一个大的计数周期内,对于要显示的6位数码进行动态扫描,显示出6种移位状态中的一种;在下一个大的周期内,计数变量shift加1。

定义led_sel_count来控制初始时刻对应位显示的数字(固定不变的关系),定义led_sel_llb控制数字显示的对应位置,则led_sel_llb=led_sel_count+shift则代表相对于初始时刻移位shift位后该数字显示的对应位,这样就实现了移位。

以此类推,实现循环移位。

(3)按键模块和动态显示模块同实验一

 

具体流程图如下:

 

6.仿真波形

1 Row=1110,Column=1110,key_code=0000,shift的计数周期是1s,即移位周期为1s

 

2 Row=1110,Column=1101,key_code=0001,time_count以000,001循环计数,shift的周期为2s即移位周期为2s

 

3 Row=1110,Column=1011,key_code=0010,time_count以000,001,010循环计数,shift的周期为3s即移位周期为3s

4 Row=1110,Column=1110,key_code=0011,time_count以000,001,010,011循环计数,shift的周期为4s即移位周期为4s

7.硬件实现

这个实验要注意的问题和上一个实验基本相同。

这个实验涉及到动态显示,所以还要特别注意Clk和Clk-temp的设置,后者要比前者大的多才能实现动态显示。

程序编译通过后连接硬件并进行下载,下载成功则可以实现学号的动态显示和右移,并通过按键选择右移的周期。

8.体会和建议

由于上学期没有做过软件部分,所以这学期的任务还是比较重的。

但是老师给的资料很全,照着资料一步步做下来还比较顺利。

但还是发生了一些小插曲,AtmelISP支持的下载文件类型为*.JED,而JED文件是由POF文件转换而来的。

但是我们在编译的文件夹中却找不到POF文件,最后XX得知Quartus6.0版本编译后无法生成POF文件,必须破解到9.0版本才行。

还有一开始电源线是坏的,下载一直不成功,但这个问题很快就排查出来了。

之前同学告诉我们下载不成功是因为热插拔冷插拔的原因,后来发现其实那个没什么关系貌似,是下载的电源线有问题。

我觉得课程设计的安排是有必要的,让我学到了很多:

首先就是排查故障的方法,在确保软件不出错的情况下找硬件问题,这样一级级排查很有效;其次就是善于发现问题并有效解决问题的能力。

通过这个阶段的努力把学到的理论知识运用到实践中,更直观也有利于对理论知识的理解。

9.附录(VHDL源程序)

-测试数码管,控制最右边2个数码管动态显示1~16

--40M有源晶振2脚

--32.768晶振83脚

--数码管a~h75,76,77,79,80,81,69,70

--6个选择管脚54,55,56,57,58,60

LIBRARYieee;

USEieee.std_logic_1164.all;

USEieee.std_logic_unsigned.all;

--显示模块

ENTITYcount2IS

PORT(

clk:

INSTD_LOGIC;--40M高频时钟,也可以接低频时钟,看数码管显示的情况

led_out:

OUTSTD_LOGIC_VECTOR(7DOWNTO0);--数码管8段显示,可显示0~9,A~F

led_sel:

bufferSTD_LOGIC_VECTOR(5DOWNTO0);--选择6个数码管,‘1’表示点亮对应数码管

row:

outSTD_LOGIC_VECTOR(3downto0);--行列式键盘的4行

column:

inSTD_LOGIC_VECTOR(3downto0)--行列式键盘的4列

);

ENDcount2;

ARCHITECTUREBehaviorOFcount2IS

SIGNALclk_temp:

STD_LOGIC;--分频后的电路时钟输出

signaldata:

STD_LOGIC_VECTOR(3DOWNTO0);--数码管要显示的数0~15表示1~16

signalled_sel_count:

STD_LOGIC;--用于选择第5个和第6个数码管,分别用1和0代表

SIGNALdiv_cnt:

std_logic_vector(1downto0);--行扫描驱动

SIGNALscan_key:

std_logic_vector(3DOWNTO0);--扫描码寄存器

SIGNALkey_code:

std_logic_vector(3DOWNTO0);--存储键值

begin

row<=scan_key;

data<=key_code;

PROCESS(clk)--行扫描驱动,产生行扫描的值

BEGIN

IF(clk'EVENTANDclk='0')THEN

div_cnt<=div_cnt+1;

ENDIF;

ENDPROCESS;

PROCESS(div_cnt)

BEGIN

CASEdiv_cntIS

WHEN"00"=>scan_key<="1110";

WHEN"01"=>scan_key<="1101";

WHEN"10"=>scan_key<="1011";

WHEN"11"=>scan_key<="0111";

WHENOTHERS=>NULL;

ENDCASE;

ENDPROCESS;

PROCESS(clk)

BEGIN

IF(clk'EVENTANDclk='1')THEN

CASEscan_keyIS--检测何处有键按下

WHEN"1110"=>

CASEcolumnIS

WHEN"1110"=>

key_code<="0000";

WHEN"1101"=>

key_code<="0001";

WHEN"1011"=>

key_code<="0010";

WHEN"0111"=>

key_code<="0011";

WHENOTHERS=>

NULL;

ENDCASE;

WHEN"1101"=>

CASEcolumnIS

WHEN"1110"=>

key_code<="0100";

WHEN"1101"=>

key_code<="0101";

WHEN"1011"=>

key_code<="0110";

WHEN"0111"=>

key_code<="0111";

WHENOTHERS=>

NULL;

ENDCASE;

WHEN"1011"=>

CASEcolumnIS

WHEN"1110"=>

key_code<="1000";

WHEN"1101"=>

key_code<="1001";

WHEN"1011"=>

key_code<="1010";

WHEN"0111"=>

key_code<="1011";

WHENOTHERS=>

NULL;

ENDCASE;

WHEN"0111"=>

CASEcolumnIS

WHEN"1110"=>

key_code<="1100";

WHEN"1101"=>

key_code<="1101";

WHEN"1011"=>

key_code<="1110";

WHEN"0111"=>

key_code<="1111";

WHENOTHERS=>

NULL;

ENDCASE;

WHENOTHERS=>

key_code<="1111";

ENDCASE;

ENDIF;

ENDPROCESS;

process(clk)--显示数据

begin

if(clk'eventandclk='0')then--下降沿有效

led_sel_count<=NOTled_sel_count;--在0和1之间切换

caseled_sel_countis

when'0'=>led_sel<="000001";--点亮第6个数码管

when'1'=>led_sel<="000010";--点亮第5个数码管

whenothers=>led_sel<="000001";

endcase;

casedatais--显示到对应数码管的数据

when"0000"=>if(led_sel_count='0')then--0表示要显示1

led_out<=X"f9";--数码管6显示1

elseled_out<=X"ff";--数码管5显示空

endif;

when"0001"=>if(led_sel_count='0')then--1表示要显示2

led_out<=X"a4";--数码管6显示2

elseled_out<=X"ff";--数码管5显示空

endif;

when"0010"=>if(led_sel_count='0')then--2表示要显示3

led_out<=X"b0";--数码管6显示3

elseled_out<=X"ff";--数码管5显示空

endif;

when"0011"=>if(led_sel_count='0')then--3表示要显示4

led_out<=X"99";--数码管6显示4

elseled_out<=X"ff";--数码管5显示空

endif;

when"0100"=>if(led_sel_count='0')then--4表示要显示5

led_out<=X"92";--数码管6显示5

elseled_out<=X"ff";--数码管5显示空

endif;

when"0101"=>if(led_sel_count='0')then--5表示要显示6

led_out<=X"82";--数码管6显示6

elseled_out<=X"ff";--数码管5显示空

endif;

when"0110"=>if(led_sel_count='0')then--6表示要显示7

led_out<=X"f8";--数码管6显示7

elseled_out<=X"ff";--数码管5显示空

endif;

when"0111"=>if(led_sel_count='0')then--7表示要显示8

led_out<=X"80";--数码管6显示8

elseled_out<=X"ff";--数码管5显示空

endif;

when"1000"=>if(led_sel_count='0')then--8表示要显示9

led_out<=X"90";--数码管6显示9

elseled_out<=X"ff";--数码管5显示空

endif;

when"1001"=>if(led_sel_count='0')then--9表示要显示10

led_out<=X"c0";--数码管6显示0

elseled_out<=X"f9";--数码管5显示1

endif;

when"1010"=>if(led_sel_count='0')then--10表示要显示11

led_out<=X"f9";--数码管6显示1

elseled_out<=X"f9";--数码管5显示1

endif;

when"1011"=>if(led_sel_count='0')then--11表示要显示12

led_out<=X"a4";--数码管6显示2

elseled_out<=X"f9";--数码管5显示1

endif;

when"1100"=>if(led_sel_count='0')then--12表示要显示13

led_out<=X"b0";--数码管6显示3

elseled_out<=X"f9";--数码管5显示1

endif;

when"1101"=>if(led_sel_count='0')then--13表示要显示14

led_out<=X"99";--数码管6显示4

elseled_out<=X"f9";--数码管5显示1

endif;

when"1110"=>if(led_sel_count='0')then--14表示要显示15

led_out<=X"92";--数码管6显示5

elseled_out<=X"f9";--数码管5显示1

endif;

when"1111"=>if(led_sel_count='0')then--15表示要显示16

led_out<=X"82";--数码管6显示6

elseled_out<=X"f9";--数码管5显示1

endif;

whenothers=>led_out<=X"ff";

endcase;

endif;

endprocess;

endBehavior;

数码管学号滚动显示代码

--测试数码管,控制最右边2个数码管动态显示1~16

--32.768晶振83脚

--数码管a~h75,76,77,79,80,81,69,70

--6个选择管脚54,55,56,57,58,60

LIBRARYieee;

USEieee.std_logic_1164.all;

USEieee.std_logic_unsigned.all;

--显示模块

ENTITYllbIS

PORT(

clk:

INSTD_LOGIC;--接低频时钟32.768KHz,已经进过CD406的5分频

led_out:

OUTSTD_LOGIC_VECTOR(7DOWNTO0);--数码管8段显示,可显示0~9,A~F

led_sel:

bufferSTD_LOGIC_VECTOR(5DOWNTO0);--选择6个数码管,‘1’表示点亮对应数码管

row:

outSTD_LOGIC_VECTOR(3downto0);--行列式键盘的4行

column:

inSTD_LOGIC_VECTOR(3downto0)--行列式键盘的4列

);

ENDllb;

ARCHITECTUREBehaviorOFllbIS

signalclk_temp:

std_logic;--用作分频后的电路时钟

signalled_sel_count:

std_logic_vector(3DOWNTO0);--信号量,6个数码管显示的选择

signaldiv_cnt:

std_logic_v

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

当前位置:首页 > 农林牧渔 > 林学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1