verilog矩阵键盘.docx

上传人:b****8 文档编号:11021177 上传时间:2023-02-24 格式:DOCX 页数:14 大小:33.21KB
下载 相关 举报
verilog矩阵键盘.docx_第1页
第1页 / 共14页
verilog矩阵键盘.docx_第2页
第2页 / 共14页
verilog矩阵键盘.docx_第3页
第3页 / 共14页
verilog矩阵键盘.docx_第4页
第4页 / 共14页
verilog矩阵键盘.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

verilog矩阵键盘.docx

《verilog矩阵键盘.docx》由会员分享,可在线阅读,更多相关《verilog矩阵键盘.docx(14页珍藏版)》请在冰豆网上搜索。

verilog矩阵键盘.docx

verilog矩阵键盘

二、矩阵键盘显示电路设计(显示键盘值的平方)

矩阵键盘显示电路的设计

一、实验目的

1、了解普通4×4键盘扫描的原理。

2、进一步加深七段码管显示过程的理解。

3、了解对输入/输出端口的定义方法。

二、实验原理

实现键盘有两种方案:

一是采用现有的一些芯片实现键盘扫描;再就是用软件实现键盘扫描。

作为一个嵌入系统设计人员,总是会关心产品成本。

目前有很多芯片可以用来实现键盘扫描,但是键盘扫描的软件实现方法有助于缩减一个系统的重复开发成本,且只需要很少的CPU开销。

嵌入式控制器的功能能强,可能充分利用这一资源,这里就介绍一下软键盘的实现方案。

 

图10-1简单键盘电路

通常在一个键盘中使用了一个瞬时接触开关,并且用如图10-1所示的简单电路,微处理器可以容易地检测到闭合。

当开关打开时,通过处理器的I/O口的一个上拉电阻提供逻辑1;当开关闭合时,处理器的/IO口的输入将被拉低得到逻辑0。

可遗憾的是,开关并不完善,因为当它们被按下或者被释放时,并不能够产生一个明确的1或者0。

尽管触点可能看起来稳定而且很快地闭合,但与微处理器快速的运行速度相比,这种动作是比较慢的。

当触点闭合时,其弹起就像一个球。

弹起效果将产生如图10-2所示的好几个脉冲。

弹起的持续时间通常将维持在5ms∼30ms之间。

如果需要多个键,则可以将每个开关连接到微处理器上它自己的输入端口。

然而,当开关的数目增加时,这种方法将很快使用完所有的输入端口。

 

图10-2按键抖动

键盘上阵列这些开关最有效的方法(当需要5个以上的键时)就形成了一个如图10-3所示的二维矩阵。

当行和列的数目一样多时,也就是方型的矩阵,将产生一个最优化的布列方式(I/O端被连接的时候),一个瞬时接触开关(按钮)放置在每一行与线一列的交叉点。

矩阵所需的键的数目显然根据应用程序而不同。

每一行由一个输出端口的一位驱动,而每一列由一个电阻器上拉且供给输入端口一位。

 

图10-3矩阵键盘

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

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

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

获取到行值和列值以后,组合成一个8位的数据,根据实现不同的编码在对每个按键进行匹配,找到键值后在7段码管显示。

三、实验容

本实验要求完成的任务是通过编程实现对4X4矩阵键盘按下键的键值的读取,并在数码管上完成一定功能(如移动等)的显示。

按键盘的定义,按下“*”键则在数码管是显示“E”键值。

按下“#”键在数码管上显示“F”键值。

其它的键则按键盘上的标识进行显示。

在此实验中数码管与FPGA的连接电路和管脚连接在以前的实验中都做了详细说明,这里不在赘述。

本实验箱上的4X4矩阵键盘的电路原理如图10-4所示。

与FPGA的管脚连接如表10-1所示。

 

图10-44X4矩阵键盘电路原理图

表10-14X4矩阵键与FPGA的管脚连接表

信号名称

对应FPGA管脚名

说明

KEY-C0

B8

矩阵键盘的第1列选择

KEY-C1

A9

矩阵键盘的第2列选择

KEY-C2

B9

矩阵键盘的第3列选择

KEY-C3

E5

矩阵键盘的第4列选择

KEY-R0

B6

矩阵键盘的第1行选择

KEY-R1

A7

矩阵键盘的第2行选择

KEY-R2

B7

矩阵键盘的第3行选择

KEY-R3

A8

矩阵键盘的第4行选择

 

四、实验步骤

1、打开QUARTUSII软件,新建一个工程。

2、建完工程之后,再新建一个VHDLFile,打开VHDL编辑器对话框。

3、按照实验原理和自己的想法,在VHDL编辑窗口编写VHDL程序,用户可参照光盘中提供的示例程序。

4、编写完VHDL程序后,保存起来。

方法同实验一。

5、对自己编写的VHDL程序进行编译并仿真,对程序的错误进行修改。

6、编译仿真无误后,依照4X4矩阵键、数码管与FPGA的管脚连接表(表或参照附录)进行管脚分配。

表10-2是示例程序的管脚分配表。

分配完成后,再进行全编译一次,以使管脚分配生效。

端口名

使用模块信号

对应FPGA管脚

说明

CLK

数字信号源

C13

时钟为1KHZ

KR0

4*4矩阵键盘R0

B6

矩阵键盘行信号

KR1

4*4矩阵键盘R1

A7

KR2

4*4矩阵键盘R2

B7

KR3

4*4矩阵键盘R3

A8

KC0

4*4矩阵键盘C0

B8

矩阵键盘列信号

KC1

4*4矩阵键盘C1

A9

表10-2端口管脚分配表

KC2

4*4矩阵键盘C2

B9

矩阵键盘列信号

KC3

4*4矩阵键盘C3

E5

A

数码管模块A段

F13

键值显示

B

数码管模块B段

F14

C

数码管模块C段

F15

D

数码管模块D段

E15

E

数码管模块E段

F16

F

数码管模块F段

F17

G

数码管模块G段

E18

SA

数码管模块SEL0

G18

SB

数码管模块SEL1

G17

SC

数码管模块SEL2

G16

 

7、用下载电缆通过JTAG口将对应的sof文件加载到FPGA中。

观察实验结果是否与自己的编程思想一致。

五、实验结果与现象

以设计的参考示例为例,当设计文件加载到目标器件后,将数字信号源模块的时钟选择为1KHz,按动“模式”按键使单8字数码管显示“0”(参考实验四),按下矩阵键盘的某一个键,则在数码管上显示对应的这个键标识的键值,当再按下第二个键的时候前一个键的键值在数码管上左移一位。

按下“*”键则在数码管是显示“E”键值。

按下“#”键在数码管上显示“F”键值。

 

/************************************************

工程:

4x4矩阵键盘

日期:

2011-08-3

最后修改:

功能:

键盘

说明:

ROW【3:

0】设为输入,COL【3:

0】设为输出。

如果没有按键按下,则ROW【3:

0】一直被上

拉为高电平,且COL【3:

0】有低电平输出,

ROW【3:

0】中才有可能低电平输入。

*************************************************/

modulekeys(clk_50M,rst_n,row,col,dataout,smg_wei);

/*************************************************/

output[3:

0]col;//矩阵键盘列

inputrst_n;//复位键

inputclk_50M;//系统时钟

input[3:

0]row;//矩阵键盘行

output[7:

0]dataout;//键盘值数码管显示数据

output[7:

0]smg_wei;//数码管显示使能

reg[7:

0]dataout;

reg[3:

0]col;

reg[3:

0]key_board_val;

/*************************************************/

assignsmg_wei=0;//八个数码管显示

 

/*************************************************/

//分频部分开始

/*************************************************/

reg[19:

0]t;//计数子

always(posedgeclk_50Mornegedgerst_n)

if(!

rst_n)

t<=0;

else

t<=t+1'b1;

wirekey_clk=t[19];

//2^20/50M=21ms

/*************************************************

状态机部分独热码编码

*************************************************/

parameterNO_KEY_PRESSED=6'b000_001;//没有键按下

parameterSCAN_COL0=6'b000_010;//扫描第0列

parameterSCAN_COL1=6'b000_100;//扫描第1列

parameterSCAN_COL2=6'b001_000;//扫描第2列

parameterSCAN_COL3=6'b010_000;//扫描第3列

parameterKEY_PRESSED=6'b100_000;//有键按下

/*************************************************/

reg[5:

0]current_state,next_state;//现态和次态

/*************************************************/

//复位

/*************************************************/

always(posedgekey_clkornegedgerst_n)

if(!

rst_n)

current_state<=NO_KEY_PRESSED;

else

current_state<=next_state;

/*************************************************/

always*//(current_state)//根据条件转移状态

case(current_state)

NO_KEY_PRESSED:

//没有键按下

if(row!

=4'hf)

next_state=SCAN_COL0;

else

next_state=NO_KEY_PRESSED;

 

SCAN_COL0:

//扫描第0列

if(row!

=4'hf)

next_state=KEY_PRESSED;

else

next_state=SCAN_COL1;

 

SCAN_COL1:

//扫描第1列

if(row!

=4'hf)

next_state=KEY_PRESSED;

else

next_state=SCAN_COL2;

 

SCAN_COL2:

//扫描第2列

if(row!

=4'hf)

next_state=KEY_PRESSED;

else

next_state=SCAN_COL3;

 

SCAN_COL3:

//扫描第3列

if(row!

=4'hf)

next_state=KEY_PRESSED;

else

next_state=NO_KEY_PRESSED;

 

KEY_PRESSED:

//有按键按下

if(row!

=4'hf)

next_state=KEY_PRESSED;

else

next_state=NO_KEY_PRESSED;

 

endcase

/*************************************************/

regkey_pressed_flag;//按键按下标志

reg[3:

0]col_val;//列值

reg[3:

0]row_val;//行值

/*************************************************/

//根据次态,给相应的寄存器赋值

/*************************************************/

always(posedgekey_clkornegedgerst_n)

if(!

rst_n)//复位

begin

col<=4'h0;

key_pressed_flag<=0;

end

else

case(next_state)

NO_KEY_PRESSED:

begin

col<=4'h0;

key_pressed_flag<=0;

end

SCAN_COL0:

//扫描第0列

col<=4'b1110;

SCAN_COL1:

//扫描第1列

col<=4'b1101;

SCAN_COL2:

//扫描第2列

col<=4'b1011;

SCAN_COL3:

//扫描第3列

col<=4'b0111;

KEY_PRESSED:

//有按键按下

begin

col_val<=col;//锁存列值

row_val<=row;//锁存行值

key_pressed_flag<=1;

//置键盘按下标

end

endcase

/********************************************************************************/

//扫描行列值部分开始

/********************************************************************************/

 

always(posedgekey_clkornegedgerst_n)

if(!

rst_n)

key_board_val<=4'h0;

else

if(key_pressed_flag)

case({col_val,row_val})

8'b11101110:

key_board_val<=4'h0;

8'b11101101:

key_board_val<=4'h4;

8'b11101011:

key_board_val<=4'h8;

8'b11100111:

key_board_val<=4'hC;

8'b11011110:

key_board_val<=4'h1;

8'b11011101:

key_board_val<=4'h5;

8'b11011011:

key_board_val<=4'h9;

8'b11010111:

key_board_val<=4'hD;

8'b10111110:

key_board_val<=4'h2;

8'b10111101:

key_board_val<=4'h6;

8'b10111011:

key_board_val<=4'hA;

8'b10110111:

key_board_val<=4'hE;

8'b01111110:

key_board_val<=4'h3;

8'b01111101:

key_board_val<=4'h7;

8'b01111011:

key_board_val<=4'hB;

8'b01110111:

key_board_val<=4'hF;

endcase

/*********************************************************************************/

//键盘值转换为数码管显示

/*********************************************************************************/

always*//(key_board_val)

begin

case(key_board_val)

4'h0:

dataout<=8'b11000000;//0

4'h1:

dataout<=8'b11111001;//1

4'h2:

dataout<=8'b10100100;//2

4'h3:

dataout<=8'b10110000;//3

4'h4:

dataout<=8'b10011001;//4

4'h5:

dataout<=8'b10010010;//5

4'h6:

dataout<=8'b10000010;//6

4'h7:

dataout<=8'b11111000;//7

4'h8:

dataout<=8'b10000000;//8

4'h9:

dataout<=8'b10010000;//9

4'hA:

dataout<=8'b10001000;//a

4'hB:

dataout<=8'b10000011;//b

4'hC:

dataout<=8'b11000110;//c

4'hD:

dataout<=8'b10100001;//d

4'hE:

dataout<=8'b10000110;//e

4'hF:

dataout<=8'b10001110;//f

endcase

end

/*********************************************************************************/

//键盘值转换为数码管显示结束

/*********************************************************************************/

endmodule

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

当前位置:首页 > 表格模板 > 合同协议

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

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