verilog_矩阵键盘

合集下载

矩阵键盘的verilog代码分享

矩阵键盘的verilog代码分享

矩阵键盘的verilog代码分享defineSCANmodulekey_scan(clk ,rst_n,key_col, //键盘列输入key_row, //键盘行输出key_num, //指示哪一个按键按下,用0~15指示key_vld//按下有效指示信号,其为1表示按下一次。

);parameter KEY_W = 4 ;parameter COL = 0 ;parameter ROW = 1 ;parameter DLY = 2 ;parameter FIN = 3 ;parameter COL_CNT= 16;parameter TIME_20MS= 1000000;//输入信号定义input clk ;input rst_n;input[3:0] key_col;//输出信号定义output key_vld;output[3:0] key_num;output[KEY_W-1:0] key_row;//输出信号reg定义reg [3:0] key_num;reg [KEY_W-1:0] key_row;reg key_vld;reg [ 3:0] key_col_ff0 ;reg [ 3:0] key_col_ff1 ;reg [ 1:0] key_col_get ;reg shake_flag ;reg shake_flag_ff0;reg [ 3:0] state_c ;reg [19:0] shake_cnt ;reg [ 3:0] state_n ;reg [ 1:0] row_index ;reg [15:0] row_cnt ;reg [ 2:0] x ;always@(posedge clk or negedge rst_n)begin if(rst_n==1b0)beginkey_col_ff0 = 4b1111;key_col_ff1 = 4b1111;endelse beginkey_col_ff0 = key_col ;key_col_ff1 = key_col_ff0;endendalways@(posedge clk or negedge rst_n)begin if(rst_n==1b0)beginshake_cnt = 0;endelse if(add_shake_cnt)beginif(end_shake_cnt)shake_cnt = 0;elseshake_cnt = shake_cnt + 1;endelse beginshake_cnt = 0;endassignadd_shake_cnt = key_col_ff1!=4hf shake_flag==0; assignend_shake_cnt = add_shake_cnt shake_cnt==TIME_20MS-1; always@(posedge clk or negedge rst_n)beginif(rst_n==1b0)beginshake_flag = 0;endelse if(end_shake_cnt) beginshake_flag = 1b1;endelse if(key_col_ff1==4hf) beginshake_flag = 1b0;endend`ifdef SCANalways@(posedge clk or negedge rst_n)beginif(rst_n==1b0)beginstate_c = COL;endelse beginstate_c = state_n;endendalways@(*)begincase(state_c)COL: beginif(col2row_start)beginstate_n = ROW;endelse beginstate_n = state_c;endROW: beginif(row2dly_start)beginstate_n = DLY;endelse beginstate_n = state_c;endendDLY :beginif(dly2fin_start)beginstate_n = FIN;endelse beginstate_n = state_c;endendFIN: beginif(fin2col_start)beginstate_n = COL;endelse beginstate_n = state_c;endenddefault: state_n = COL;endcaseendassigncol2row_start = state_c==COL end_shake_cnt; assignrow2dly_start = state_c==ROW end_row_index; assigndly2fin_start = state_c==DLY end_row_index; assignfin2col_start = state_c==FIN key_col_ff1==4hf; always@(posedge clk or negedge rst_n)beginif(rst_n==1b0)beginkey_row = 4b0;endelse if(state_c==ROW)beginkey_row = ~(1b1 row_index);endelse beginkey_row = 4b0;endendalways@(posedge clk or negedge rst_n)beginif(rst_n==1b0)beginrow_cnt = 0;endelse if(add_row_cnt) beginif(end_row_cnt)row_cnt = 0;elserow_cnt = row_cnt + 1;endendassign add_row_cnt = state_c==ROW || state_c==DLY; assign end_row_cnt = add_row_cnt row_cnt==COL_CNT-1; always@(posedge clk or negedge rst_n)beginif(rst_n==1b0)beginrow_index = 0;endelse if(add_row_index) beginif(end_row_index)row_index = 0;elserow_index = row_index + 1;endassign add_row_index = end_row_cnt;assign end_row_index = add_row_index row_index==x-1; always@(*)beginif(state_c==ROW)x = 4;elsex = 1;endalways@(posedge clk or negedge rst_n)beginif(rst_n==1b0)beginkey_col_get = 0;endelse if(col2row_start) beginif(key_col_ff1==4b1110)key_col_get = 0;else if(key_col_ff1==4b1101)key_col_get = 1;else if(key_col_ff1==4b1011)key_col_get = 2;elsekey_col_get = 3;endendalways@(posedge clk or negedge rst_n)beginif(rst_n==1b0)beginkey_num = 0;endelse if(state_c==ROW end_row_cnt)beginkey_num = {row_index,key_col_get};endelse beginkey_num = 0;endalways@(posedge clk or negedge rst_n)beginif(rst_n==1b0)beginkey_vld = 1b0;endelse if(state_c==ROW end_row_cnt key_col_ff1[key_col_get]==1b0)begin key_vld = 1b1;endelse beginkey_vld = 1b0;endend`elsealways@(posedge clk or negedge rst_n)beginif(rst_n==1b0)beginkey_vld = 0;endelse beginkey_vld = end_shake_cnt;endendalways@(*)beginkey_num = 0;end`endifendmodule。

verilog语言FPGA键盘程序解析

verilog语言FPGA键盘程序解析

//------------------------------------------------------------------------------------------------- // File : top.v // Generated : 2011-07-20 // Author : wangliang //------------------------------------------------------------------------------------------------- `timescale 1 ns / 1 ps module top ( KEYO ,KEYI ,clk ,Y , rst; input [3:0] KEYO ; //与原理图一致,是键盘输出端口给FPGA input clk ; input rst ; output [3:0] KEYI ; //与原理图一致,是FPGA输出给键盘 output [7:0] Y ; wire keypress; wire scanclk; wire [7:0] temp ; wire [3:0] keydrv ; reg [7:0] temp_r ; reg [7:0] Y_r; reg [4:0] keyvalue ; reg [3:0] scankey_o; reg [3:0] scankey_i; wire dis; reg dis_pre; assign dis = &KEYO ; scan_clk key_clk( .clk ( clk, .clkout( scanclk , .rst ( rst ; key_scan key_scan( .clk ( scanclk , .keydrv (keydrv , .rst ( rst ; always @ ( posedge clk or negedge rst begin if ( rst==1'b0 begin scankey_o <= 4'b0 ; scankey_i <= 4'b0 ; dis_pre <= dis; end else if ( clk ==1'b1 begin dis_pre <= dis; if ( (dis == 1'b0&&(dis_pre==1'b1 begin scankey_o <= keydrv ; scankey_i <= KEYO ; end end end assign KEYI = keydrv; assign temp = {scankey_o,scankey_i}; always @ ( posedge clk or negedge rst begin if ( rst==1'b0 begin temp_r <= 8'b0; end else if ( clk == 1'b1 temp_r <= temp ; end always @( temp_r or rst begin if ( rst==1'b0 begin //译码输出keyvalue <= 5'b0; end else case ( temp_r 8'b0111_0111 : keyvalue <= 5'hb; //无用,仅作为复位 8'b1110_1110 : keyvalue <= 5'h7; 8'b1110_1101 : keyvalue <= 5'h8;8'b1110_1011 : keyvalue <= 5'h9; 8'b1101_1110 : keyvalue <= 5'h4; 8'b1101_1101 : keyvalue <= 5'h5; 8'b1101_1011 : keyvalue <= 5'h6; 8'b1011_1110 : keyvalue <= 5'h1;8'b1011_1101 : keyvalue <= 5'h2; 8'b1011_1011 : keyvalue <= 5'h3; 8'b0111_1101 : keyvalue <= 5'h0; 8'b0111_1011 : keyvalue <= 5'b1_0001; //小数点 default: keyvalue <= 5'h0; endcase end always @(keyvalue or rst begin if ( rst==1'b0 //译码输出 Y_r <= 8'b0000_0000; else begin Y_r =8'b0000_0000; case (keyvalue 5'h0: Y_r =8'b0011_1111; // 0 5'h1: Y_r = 8'b0000_0110; // 1 5'h2: Y_r = 8'b0101_1011; // 2 5'h3:Y_r = 8'b0100_1111; // 3 5'h4: Y_r = 8'b0110_0110; // 4 5'h5: Y_r = 8'b0110_1101; // 5 5'h6: Y_r = 8'b0111_1101; // 6 5'h7: Y_r = 8'b0000_0111; // 7 5'h8: Y_r = 8'b0111_1111; // 8 5'h9: Y_r = 8'b0110_1111; // 9 5'b1_0001: Y_r = 8'b1000_0000; //. default: Y_r =8'b0000_0000; endcase end end assign Y =~Y_r; endmodule。

verilog_矩阵键盘

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 行有一位为低电平,那么对应的该行肯定有一个按键按下,这样便可以获取到按键的行值。

【Easy CPLD570】Verilog实现4x4矩阵按键检测

【Easy CPLD570】Verilog实现4x4矩阵按键检测

Verilog实现4x4矩阵按键检测1 原理图4x4的矩阵按键,8个IO,检测原理是IO63、66、67、68作为输出信号,轮流赋值高电平,IO59、60、61、62作为输入信号,检测对应的按键按下。

比如,在IO68赋值高电平时,检测到IO59信号为高电平,则表示按键K1被按下。

拨码开关用于测试。

2 CPLD代码module key_array (clk_24m,reset_n,Hline, //输出4bit按键赋高电平信号。

Vline, //输入4bit按键检测信号。

ledline, //测试使用LED点灯信号switch //测试使用按键表现选择信号,因只有8个LED,而按键有16个,通过此信号来选择是表现K1-K8,还是K9-K16。

);input wire clk_24m;input wire reset_n;output wire [3:0] Hline;input wire [3:0] Vline;output reg [7:0] ledline;input wire switch;/****************************************************************************** 24M时钟分频,用于内部控制及计数等。

******************************************************************************/ reg [14:0] count_div1;wire condition_732; //732 Hz时钟信号。

always @ (posedge clk_24m or negedge reset_n)beginif(reset_n == 1'b0)count_div1 <= 15'h0000;elsecount_div1 <= count_div1 + 15'h0001;end/****************************************************************************** condition_732:732Hz时钟信号,高电平持续一个24MHz时钟周期,其余时间为低电平。

verilog矩阵键盘

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 行有一位为低电平,那么对应的该行肯定有一个按键按下,这样便可以获取到按键的行值。

EDA实验七 矩阵键盘与数码管显示测试

EDA实验七 矩阵键盘与数码管显示测试

实验七4*4键盘数据读取及数据显示设计一、实验目的:1、了解数码管的工作原理;2、掌握4*4矩阵键盘和数码管显示的编程方法。

3、学会用于Verilog语言进行程序设计。

二、实验仪器设备1、PC机一台2、FPGA实验开发系统一套。

三、实验原理:本实验通过扫描4*4矩阵键盘的值,在数码管上显示对应按钮的编号数据。

矩阵键盘及数码管电路如下所示。

四、实验要求1、预习教材中的相关内容。

2、阅读并熟悉本次实验的内容。

3、完成实验内容。

五、实验步骤(1)启动 Quartus II 建立一个空白工程,选择的器件为 Altera 公司的 Cyclone 系列的 EP2C8Q240C8芯片,命名为 keyarray.qpf;(2)新建一个 Schematic File 文件,命名为 keyarray.bdf;(3)分别新建 3 个 Verilog HDL File 文件,分别命名为 seg_show.v、 divclk.v、keyarraycontrol.v。

输入程序代码并保存(对应源程序 8),然后进行综合编译。

若在编译过程中发现错误,则找出错误并更正错误,直至编译成功为止。

(4)从设计文件创建模块(File→Creat Update→Creat Symbol Files for Current File),seg_show.v 生成名为seg_show.bsf;divclk.v 生成名为divclk.bsf;keyarraycontrol.v 生成名为keyarraycontrol.bsf;(5)在 keyarray.bdf 文件中,在空白处双击鼠标左键,在 Symbol 对话框左上角的libraries 中,分别将 Project 下的 seg_show, divclk, keyarraycontrol 模块放在图形文件 keyarray.bdf 中,加入输入、输出引脚,双击每个引脚,进行引脚命名,并锁定管脚,将未使用的引脚设置为三态输入(一定要设置,否则可能会损坏芯片);完整的顶层模块原理图如图所示(6)将keyarray.bdf 设置为顶层实体。

fpga矩阵键盘

fpga矩阵键盘

FPGA课程设计报告项目名称基于FPGA的4*4矩阵键盘的设计专业班级通信1学生姓名张指导教师2016年7 月10 日摘要本课程设计提出了基于FPGA的4*4矩阵键盘的设计,主要是在软件Quartus II 9.0这个环境中,以硬件描述语言Verilog进行编写程序,从而完成矩阵键盘的相关设计。

主要由矩阵式键盘电路、显示电路等组成,实现过程是通过行扫描输入随机信号,列扫描判断哪一个键被按下,并最后由数码管显示该按键。

此次课程设计完成了4*4矩阵键盘控制LED数码管显示系统的设计,该设计具有灵活性强,易于操作,可靠性高,广泛应用于各种场合的特点,是进行按键操作管理的有效方法,它可以提高系统准确性,有利于资源的节约,降低对操作者本身的要求,并能正确、实时、高效地显示按键信息,以提高工作效率和资源换利用率的意义。

关键词:数码管;矩阵键盘;按键;显示电路AbstractThis course is designed based on FPGA is proposed 4 * 4 matrix keyboard design, mainly in the Quartus II software 9.0 this environment, with the Verilog hardware description language program, so as to complete the related design of matrix keyboard. Main matrix keyboard circuit, display circuit and so on, complete the 4 * 4 matrix keyboard control LED digital tube display system design, the design has strong flexibility, easy operation, high reliability, widely used in various occasions. Into 4 * 4 matrix keyboard control LED digital tube display system design, design flexibility is strong, easy to operate, high reliability, widely used in various occasions. Matrix keyboard control system, can improve efficiency, and is an effective method to manage the keystrokes, it can improve the system accuracy, and is conducive to resource saving and reduce the requirement of the operator itself, and correctly, real-time and efficient to show the key information, in order to improve the work efficiency and the utilization ratio of resources in meaning.Keywords: Digital tube; Matrix keyboard; The key; Disply circuit目录摘要 (I)Abstract (II)第1章绪论 (1)1.1 课题背景 (1)1.2 国内外发展现状 (1)1.3 本文主要研究内容 (1)第2章软件及语言简介 (2)2.1 Quartus软件简介 (3)2.2 Verilog语言简介 (4)2.2.1 Verilog语言的主要功能 (4)2.2.2 Verilog语言设计数字系统的特点 (4)第3章 4*4矩阵键盘的原理 (6)3.1 4*4矩阵式键盘 (6)3.2 总体结构 (6)3.2.1 LED数码管 (8)3.2.2 键盘结构 (9)3.3 键盘扫描 (9)3.4 矩阵键盘接口电路的原理 (9)第4章程序调试 (11)4.1 流程图 (11)4.2 程序结果讨论 (11)第5章波形仿真及讨论 (13)5.1 波形结果 (13)5.2 结果讨论 (14)结论 (15)参考文献 (16)附录程序 (17)致谢 (19)第1章绪论1.1 课题背景在现代的个人计算机系统中,一般都采用通用的标准键盘如标准键盘(如:标准101/102键盘或Microsoft自然PS/2键盘)来实现人与计算机之间的接口交互, 从而将需要的各种数据和指令等信息都通过键盘来输人计算机。

Verilog HDL 编写 4.4 3.3键盘程序

Verilog HDL 编写 4.4  3.3键盘程序

这里有一段4*4的,哪位大哥能帮我改成3*3的,谢谢!!! module Verilog1(clk,//50MHZreset,row,//行col,//列key_value//键值);input clk,reset;input [3:0] row;output [3:0] col;output [3:0] key_value;reg [3:0] col;reg [3:0] key_value;reg [5:0] count;//delay_20msreg [2:0] state;//状态标志reg key_flag;//按键标志位reg clk_500khz;//500KHZ时钟信号reg [3:0] col_reg;//寄存扫描列值reg [3:0] row_reg;//寄存扫描行值always @(posedge clk or negedge reset)if(!reset)begin clk_500khz<=0; count<=0;endelsebeginif(count>=50)begin clk_500khz<=~clk_500khz;count<=0;endelse count<=count+1;endalways @(posedge clk_500khz or negedge reset) if(!reset)begin col<=4'b0000;state<=0;endelsebegincase (state)0:begincol[3:0]<=4'b0000;key_flag<=1'b0;if(row[3:0]!=4'b1111)begin state<=1;col[3:0]<=4'b1110;end //有键按下,扫描第一行else state<=0;end1:beginif(row[3:0]!=4'b1111)begin state<=5;end//判断是否是第一行elsebegin state<=2;col[3:0]<=4'b1101;end//扫描第二行end2:beginif(row[3:0]!=4'b1111)begin state<=5;end//判断是否是第二行elsebegin state<=3;col[3:0]<=4'b1011;end//扫描第三行end3:beginif(row[3:0]!=4'b1111)begin state<=5;end//判断是否是第三一行elsebegin state<=4;col[3:0]<=4'b0111;end//扫描第四行end4:beginif(row[3:0]!=4'b1111)begin state<=5;end//判断是否是第一行else state<=0;end5:beginif(row[3:0]!=4'b1111)begincol_reg<=col;//保存扫描列值row_reg<=row;//保存扫描行值state<=5;key_flag<=1'b1;//有键按下endelsebegin state<=0;endendendcaseendalways @(clk_500khz or col_reg or row_reg) beginif(key_flag==1'b1)begincase ({col_reg,row_reg})8'b1110_1110:key_value<=0;8'b1110_1101:key_value<=1;8'b1110_1011:key_value<=2;8'b1110_0111:key_value<=3;8'b1101_1110:key_value<=4;8'b1101_1101:key_value<=5;8'b1101_1011:key_value<=6;8'b1101_0111:key_value<=7;8'b1011_1110:key_value<=8;8'b1011_1101:key_value<=9;8'b1011_1011:key_value<=10;8'b1011_0111:key_value<=11;8'b0111_1110:key_value<=12;8'b0111_1101:key_value<=13;8'b0111_1011:key_value<=14;8'b0111_0111:key_value<=15;endcaseendendendmodule提问者:roddyni - 二级3*3module Verilog1(clk,//50MHZreset,row,//行col,//列key_value//键值);input clk,reset;input [2:0] row;output [2:0] col;output [3:0] key_value;reg [2:0] col;reg [3:0] key_value;reg [5:0] count;//delay_20msreg [2:0] state;//状态标志reg key_flag;//按键标志位reg clk_500khz;//500KHZ时钟信号reg [2:0] col_reg;//寄存扫描列值reg [2:0] row_reg;//寄存扫描行值always @(posedge clk or negedge reset)if(!reset)begin clk_500khz<=0; count<=0;endelsebeginif(count>=50)begin clk_500khz<=~clk_500khz;count<=0;endelse count<=count+1;endalways @(posedge clk_500khz or negedge reset) if(!reset)begin col<=3'b000;state<=0;endelsebegincase (state)0:begincol[2:0]<=3'b000;key_flag<=1'b0;if(row[2:0]!=3'b111)begin state<=1;col[2:0]<=3'b110;end //有键按下,扫描第一行else state<=0;end1:beginif(row[2:0]!=3'b111)begin state<=4;end//判断是否是第一行elsebegin state<=2;col[2:0]<=3'b101;end//扫描第二行end2:beginif(row[2:0]!=3'b111)begin state<=4;end//判断是否是第二行elsebegin state<=3;col[2:0]<=3'b011;end//扫描第三行end3:beginif(row[2:0]!=3'b111)begin state<=4;end//判断是否是第一行else state<=0;end4:beginif(row[2:0]!=3'b111)begincol_reg<=col;//保存扫描列值row_reg<=row;//保存扫描行值state<=4;key_flag<=1'b1;//有键按下endelsebegin state<=0;endendendcaseendalways @(clk_500khz or col_reg or row_reg) beginif(key_flag==1'b1)begincase ({col_reg,row_reg})6'b110_110:key_value<=0;6'b110_101:key_value<=1;6'b110_011:key_value<=2;6'b101_110:key_value<=3;6'b101_101:key_value<=4;6'b101_011:key_value<=5;6'b011_110:key_value<=6;6'b011_101:key_value<=7;6'b011_011:key_value<=8;endcaseendendendmodule3。

VerilogHDL键盘编程

VerilogHDL键盘编程

VerilogHDL键盘编程Verilog HDL-键盘编程今天看了一下Verilog HDL的按键程序,收获如下:1、HDL硬件描述语言和一般的软件编程语言有着很大的差别,它跟硬件是息息相关的,什么样的HDL就有什么样的硬件。

要学会查看QII里面的RTL视图,这个就是比较优略的地方。

2、Verliog HDL跟C的语法比较相近,但描述的方式有很大的不同,Verilog 里面跟多的是alawys块,这个跟VHDL的进程有异曲同工之处啊。

C跟时序不相关的多,但HDL跟时序太密切了,如果忘了这一点,理解程序就很麻烦了。

3、阻塞赋值跟非阻塞赋值也得深入的学习,往往会多出一个D触发器来。

4、虽然每个alawys块是并行的,但是上下两个寄存器有联系(然后就开始我的备忘了。

1、第一段程序中的key_rst和key_rst_r寄存器分别存储着差一个时钟周期的按键值,这条语句wire[2:0] key_an = key_rst_r & ( ~key_rst)的功能是检测一个脉冲,也就是说当寄存器key_rst由1变为0时,key_an的值变为高,维持一个时钟周期,这样就检测到了一个时钟周期的脉冲。

2、第二段程序与第一段的程序有点相似,前两个always语句里其实是做了一个20ms的计数,每隔20ms 就会读取键值,把这个键值放到寄存器low_sw中,接下来的一个always语句就是把low_sw 的值锁存到low_sw_r里,这样以来,low_sw和low_sw_r就是前后两个时钟周期里的键值了,为什么要这样呢?看下一个语句吧:wire [2:0] led_ctrl = low_sw_r[2:0] &( ~low_sw[2:0]);仔细分析,你会发现当没有键按下时,low_sw=low_sw_r=3’b111,此时的led_ctrl=3’b000;只有当low_sw和low_sw_r的某一位分别为0和1时,才可能使led_ctrl的值改变(也就是把led_ctrl的某一位拉高)。

矩阵键盘及其电路设计

矩阵键盘及其电路设计

矩阵键盘及其电路设计
矩阵键盘是一种常见的输入设备,常用于计算机、电视机、手机等电
子产品中。

它由多个按键组成,每个按键都与一个矩阵电路相连。

矩阵键
盘的设计简单、成本低廉,因此在许多场景中广泛应用。

矩阵键盘的电路设计可以分为两个主要方面:行扫描电路和列扫描电路。

行扫描电路负责控制行通道。

它由多个行扫描引脚组成,每一个引脚
都与一个行通道相连。

通常情况下,行扫描电路会以一定的频率依次将每
一个引脚置高电平,然后检测列通道是否有相应的信号。

如果检测到信号,就说明用户按下了对应的按键。

通过依次扫描所有的行通道,可以获取用
户整个键盘的按键状态。

列扫描电路负责控制列通道。

它由多个列扫描引脚组成,每一个引脚
都与一个列通道相连。

当行扫描电路扫描到其中一行时,列扫描电路会检
测到该行通道与列通道之间的电位差。

如果电位差存在,则说明用户按下
了该行和列交叉点处的按键。

在实际的电路设计中,还可以使用连接电阻和电容的方式来降低电路
的噪声。

通过在矩阵键盘中添加适当的抗干扰电路,可以有效减少外界干
扰对键盘输入的影响。

总结起来,矩阵键盘的电路设计主要包括行扫描电路和列扫描电路。

通过行列通道的扫描和检测,可以判断用户所按下的按键。

在实际的设计中,还可以添加抗干扰电路来提高键盘的输入稳定性。

矩阵键盘的设计简
单且成本低廉,因此被广泛应用于各种电子产品中。

基于VHDL的矩阵键盘及显示电路设计

基于VHDL的矩阵键盘及显示电路设计

基于VHDL的矩阵键盘及显示电路设计摘要:为了有效防止机械式键盘按键抖动带来的数据错误,这里在Quartus ?开发环境下,采用VHDL 语言设计了一种能够将机械式4 ×4 矩阵键盘的按键值依次显示到8 个7 段数码管上的矩阵键盘及显示电路。

仿真结果表明,所设计的矩阵键盘及显示电路成功地实现了按键防抖和按键数据的准确显示。

以ACEX1K系列EP1K30QC208 芯片为硬件环境,验证了各项设计功能的正确性。

FPGA/ CPLD 在数字系统设计中的广泛应用,影响到了生产生活的各个方面。

在FPGA/ CPLD 的设计开发中,V HDL 语言作为一种主流的硬件描述语言,具有设计效率高, 可靠性好, 易读易懂等诸多优点。

作为一种功能强大的FPGA/ CPLD 数字系统开发环境,Altera 公司推出的Quart us ?,为设计者提供了一种与结构无关的设计环境,使设计者能方便地进行设计输入、快速处理和器件编程,为使用V HDL 语言进行FPGA/ CPLD 设计提供了极大的便利。

矩阵键盘作为一种常用的数据输入设备,在各种电子设备上有着广泛的应用,通过7 段数码管将按键数值进行显示也是一种常用的数据显示方式。

在设计机械式矩阵键盘控制电路时,按键防抖和按键数据的译码显示是两个重要方面。

本文在Quart us ?开发环境下,采用V HDL语言设计了一种按键防抖并能连续记录并显示8 次按键数值的矩阵键盘及显示电路。

1 矩阵键盘及显示电路设计思路矩阵键盘及显示电路能够将机械式4 ×4矩阵键盘的按键值依次显示到8 个7段数码管上,每次新的按键值显示在最右端的第0 号数码管上,原有第0,6号数码管显示的数值整体左移到第1,7号数码管上显示,见图1 。

总体而言,矩阵键盘及显示电路的设计可分为4 个部分:(1) 矩阵键盘的行及列的扫描控制和译码。

该设计所使用的键盘是通过将列扫描信号作为输入信号,控制行扫描信号输出,然后根据行及列的扫描结果进行译码。

矩阵键盘程序设计

矩阵键盘程序设计

矩阵键盘程序设计一、介绍矩阵键盘是一种常见的输入设备,通常由多个行和列组成。

每个键都和一个特定的行列交叉点相连,通过检测行和列的连接状态来判断按下的是哪个键。

本文档将介绍如何设计一个基于矩阵键盘的程序。

二、硬件要求为了实现矩阵键盘程序,我们需要以下硬件设备:1-矩阵键盘:包括行和列连接点,每个键与一个特定行列连接。

2-微控制器:用于检测行列的连接状态,并处理按键输入。

3-连接线:连接矩阵键盘和微控制器的电缆。

三、程序设计步骤设计一个矩阵键盘程序的基本步骤如下:1-初始化:设置微控制器的输入输出引脚,并配置矩阵键盘的行列连接点。

2-扫描键盘:循环扫描每个连接点,判断是否有按键按下。

3-按键处理:如果有按键按下,触发相应的事件或执行相应的操作。

4-循环:重复进行扫描和处理,实现实时响应。

四、初始化设置在程序的启动阶段,需要进行初始化设置以准备矩阵键盘的使用。

1-设置输入输出引脚:将微控制器上的引脚设置为输入或输出模式,以便连接矩阵键盘和其他设备。

2-配置连接点:设置行和列的连接点,将矩阵键盘的每个键与特定的行列连接。

五、扫描键盘扫描矩阵键盘是检测按键状态的关键步骤。

1-选定一行:将矩阵键盘的行连接点设置为高电平,其他行连接点设置为低电平。

2-读取列状态:读取每一列连接点的状态,判断是否有按键按下。

3-判断按键:根据读取到的列状态,确定按下的是哪个键。

可以使用一个矩阵或查找表来管理键和行列交叉点之间的对应关系。

六、按键处理一旦检测到按键按下,程序需要触发相应的事件或执行相应的操作。

1-事件处理:例如,如果按下的是数字键,则触发相应数字的事件。

2-操作执行:例如,如果按下的是功能键,则执行相应的功能。

七、附件本文档涉及的附件包括以下内容:1-矩阵键盘的电路图:详细描述了键盘的连接方式和连接点的布局。

2-微控制器的引脚分配表:列出了微控制器上各个引脚与矩阵键盘的连接方式。

八、法律名词及注释1-版权:对于矩阵键盘的设计,可能涉及版权保护的内容,需要遵守相关法律法规。

矩阵键盘电路

矩阵键盘电路
矩阵键盘电路
知识点目录
1
矩阵键盘电路结构与工作原理
矩阵键盘的编码
矩阵式键盘按键识别
键盘的工作方式
1.矩阵键盘电路结构与工作原理
2
矩阵式键盘又称为行列式键盘。用I/O接口线组成行和列结构,键位设置在行和 列的交叉点上。如图1所示,8个I/O口实现了16个按键。
图1 矩阵键盘电路结构
1.矩阵键盘电路结构与工作原理
3
工作原理:以第一组键盘为例。设置KeyOut1输出一个低电平,相当于KeyOut1接 地,电路相当于4个独立按键电路,此时KeyIn1-KeyIn4四个输入端为高电平;当 键盘K1按下时,由于电路导通,此时KeyIn1变为低电平。同理,哪个按键按下, 相对应的输入端为低电平,单片机通过读输入端的状态,判断是否有按键按下。 对应图1四组按键,当KeyOut1输出为低电平时,KeyOut2-KeyOut4输出必须为高 电平,才能避免相互间的干扰。
2.矩阵键盘的编码
பைடு நூலகம்
4
对于矩阵式键盘,按键的位置由行号 和列号唯一确定,因此可分别对行号 和列号进行二进制编码,然后将两值 合成一个字节,高4位是行号,低4位 是列号。
3.矩阵式键盘按键识别
5
扫描法:
1) 判断有无键按下。
2) 如果有键按下,识别是哪一个键按下,键盘扫描取得闭合键的行、列值。
3) 用计算法或查表法得到键值。
4) 判断闭合键是否释放,如没释放则继续等待。
5) 将闭合键键号保存,同时转去执行该闭合键的功能。
4.键盘的工作方式
6
(1)编程扫描方式
利用CPU在完成其它工作的空余时间,调用键盘扫描子程序来响应键盘输入 的要求。
(2)定时扫描工作方式

4 4矩阵键盘(未消抖)verilog

4 4矩阵键盘(未消抖)verilog

4*4矩阵键盘(未消抖):module Matrix_keyboard(clk,in_s,out_s,num);//定义模块端口信息input clk;input [3:0] in_s;output [3:0] out_s;output [4:0] num;//定义输出信号类型及局部变量reg [4:0] num;reg [1:0] cnt = 0;reg [1:0] tmp = 0;reg [3:0] o_ut_st = 0;wire [7:0] dsample;//将扫描输出和输入信号级联,得到矩阵扫描结果assign dsample = {o_ut_st, in_s};assign out_s = o_ut_st;//产生按钮矩阵的列扫描信号always @(posedge clk)begincnt <= cnt + 1'b1;case (cnt)2'b00: o_ut_st <= 4'b1000;2'b01: o_ut_st <= 4'b0100;2'b10: o_ut_st <= 4'b0010;2'b11: o_ut_st <= 4'b0001;endcaseend//根据按钮的列扫描信号和行输入信号判断按钮是否被按下always @(posedge clk)begin//如果无按钮按下,定义num=16为无效状态if (in_s == 4'b0000)beginif (tmp == 3)beginnum <= 16; //无按键输入,输出16tmp <= 0;endelsebeginnum <= num;tmp <= tmp + 1'b1; //扫描周期,3个时钟周期endendelsebegintmp <= 0;case (dsample)//第1列扫描结果8'b1000_0001: num <= 0;8'b1000_0010: num <= 1;8'b1000_0100: num <= 2;8'b1000_1000: num <= 3;//第2列扫描结果8'b0100_0001: num <= 4;8'b0100_0010: num <= 5;8'b0100_0100: num <= 6;8'b0100_1000: num <= 7;//第3列扫描结果8'b0010_0001: num <= 8;8'b0010_0010: num <= 9;8'b0010_0100: num <= 10;8'b0010_1000: num <= 11;//第4列扫描结果8'b0001_0001: num <= 12;8'b0001_0010: num <= 13;8'b0001_0100: num <= 14;8'b0001_1000: num <= 15;endcaseendendendmodule独立按键消抖程序:module Btn_without_shake(Clk_50MHz,PB_UP,PB_Out,count_sel); //定义模块端口信息input Clk_50MHz; //模块时钟50MHzinput PB_UP; //按钮输入output PB_Out; //去抖后按钮输出output [1:0] count_sel; //计数器输出//定义输出信号类型及局部变量reg [19:0] count_high = 0; //按钮输入高电平计数器reg [19:0] count_low = 0; //按钮输入低电平计数器reg PB_reg = 0;reg [1:0] count_sel_reg = 0;//输出赋值assign PB_Out = PB_reg;assign count_sel = count_sel_reg;//对输入进行采样,计数always @(posedge Clk_50MHz)if(PB_UP == 1'b0)count_low <= count_low + 1'b1;elsecount_low <= 20'h0_0000;always @(posedge Clk_50MHz)if(PB_UP == 1'b1)count_high <= count_high + 1'b1;elsecount_high <= 20'h0_0000;//防抖输出always @(posedge Clk_50MHz)if(count_high == 20'h7_FFFF) //判断高电平信号是否符合输出条件10msPB_reg <= 1'b1; //如果符合条件,则防抖输出高电平elseif(count_low == 20'h7_FFFF) //判断低电平信号是否符合输出条件10msPB_reg <= 1'b0; //如果符合条件,则防抖输出低电平elsePB_reg <= PB_reg;//使用去抖输出PB_reg控制count_sel计数always @(posedge PB_reg)count_sel_reg <= count_sel_reg + 1'b1;endmodule初学,参考书上的《Verilog HDL程序设计与实践》,准备用状态机做一下矩阵键盘,恩,坛子里也有,不过还是自己尝试一下,坛里老牛很多呀!。

FPGA培训资料矩阵键盘驱动数码管

FPGA培训资料矩阵键盘驱动数码管

矩阵键盘驱动数码管1.矩阵键盘的结构和驱动原理2.扫描法获得矩阵键盘扫描码的原理和方法3.扫描码驱动数码管矩阵键盘的结构和驱动原理Row0Row1Row2Row3Col0 Col1 Col2 Col3扫描法获得矩阵键盘扫描码的原理和方法无按键按下时,col0~col3输出分别为“1111”当输入扫描时,扫描第一行,即IN1<=’0’,当按下Button 1,那么输出col输出信号将发生变化,Out1变为’0’,则col0~col3输出分别为“1110”,取反,则为“0001”,代表BT1被按下。

因此,可通过行扫描码和列输出码来获得分时扫描的键盘按压信号。

只要扫描时间适当,就可得到按键的按压情况。

因有四行,因此,扫描后存储的扫描码为16位,扫描行列输出也分4位4位地存放。

library IEEE;use IEEE.STD_LOGIC_1164.ALL;use IEEE.STD_LOGIC_ARITH.ALL;use IEEE.STD_LOGIC_UNSIGNED.ALL;--------------------------------------------------实体entity key_seg_test isPort ( clk : in std_logic; --系统时钟,40MHz -----------------------key_row : out std_logic_vector(3 downto 0); --FPGA输出到键盘的行扫描信号key_col : in std_logic_vector(3 downto 0); ----键盘输入到FPGA的列响应信号 -----------------------seg_d : out std_logic_vector(7 downto 0); --7段数码管数据线seg_sel : out std_logic_vector(3 downto 0) --7段数码管位数选择,'1'表示对应位数的数码管有效);end key_seg_test;--------------------------------------------------构造体architecture topdesign_arch of key_seg_test is signal key_row_reg : std_logic_vector(3 downto 0);signal key_code : std_logic_vector(15 downto 0);signal count_clk : std_logic_vector(22 downto 0);--------------------------------------------------主程序begin------------------------------------------------process(clk) --时钟计数分频beginif(clk'event and clk='1')thencount_clk<=count_clk+1;end if;end process;-----------------------process(clk)beginif(clk'event and clk='1')then --逐行扫描 case count_clk(19 downto 16) is --数码管动态扫描,扫描频率为(40*10^6)/(2^20)=38.15Hz(扫描周期为0.026s) when "0000"=> key_row_reg<="1110"; --第一行when "0001"=> key_code(3 downto 0) <= not key_col;when "0010"=> key_row_reg<="1101"; --第二行when "0011"=> key_code(7 downto 4) <= not key_col;when "0100"=> key_row_reg<="1011"; --第三行when "0101"=> key_code(11 downto 8) <= not key_col;when "0110"=> key_row_reg<="0111"; --第四行when "0111"=> key_code(15 downto 12)<= not key_col;when others =>end case;end if;end process;-----------------------key_row<=key_row_reg;-----------------------process(key_code)begincase key_code iswhen "0000000000000001"=>seg_d<="00111111"; --0when "0000000000000010"=>seg_d<="00000110"; --1when "0000000000000100"=>seg_d<="01011011"; --2when "0000000000001000"=>seg_d<="01001111"; --3when "0000000000010000"=>seg_d<="01100110"; --4when "0000000000100000"=>seg_d<="01101101"; --5when "0000000001000000"=>seg_d<="01111101"; --6when "0000000010000000"=>seg_d<="00000111"; --7when "0000000100000000"=>seg_d<="01111111"; --8when "0000001000000000"=>seg_d<="01101111"; --9when "0000010000000000"=>seg_d<="01110111"; --Awhen "0000100000000000"=>seg_d<="01111100"; --Bwhen "0001000000000000"=>seg_d<="00111001"; --Cwhen "0010000000000000"=>seg_d<="01011110"; --Dwhen "0100000000000000"=>seg_d<="01111001"; --Ewhen "1000000000000000"=>seg_d<="01110001"; --Fwhen others => seg_d<="00000000";end case;end process;-----------------------seg_sel<="1111"; --4位数码管全部输出有效,共阳---end topdesign_arch;思考题1.通过4X4键盘驱动原理,改变程序定义,实现计算器键盘输入2.3.4.5.(注:可编辑下载,若有不当之处,请指正,谢谢!)6.7.8.9.10.11.。

矩阵键盘程序设计

矩阵键盘程序设计

矩阵键盘程序设计1. 引言矩阵键盘是一种常见的输入设备,广泛应用于电脑、方式等各种电子设备中。

将介绍如何设计一个简单的矩阵键盘程序。

2. 程序设计思路矩阵键盘由多个按键组成,每个按键对应一个特定的字符或功能。

通常情况下,矩阵键盘是通过行列扫描的方式来检测按键的状态,即通过扫描每行和每列的电平来判断是否有按键被按下。

要设计一个矩阵键盘程序,需要确定矩阵键盘的行列数,然后通过相应的硬件电路将其连接到控制器上。

接下来,程序需要循环扫描每行和每列的电平,并记录下按下的按键。

根据按键的状态来执行相应的操作,输出对应的字符或执行特定的功能。

3. 硬件设计硬件设计主要包括确定矩阵键盘的行列数以及将其连接到控制器上的电路设计。

通常情况下,矩阵键盘的行使用输出电平,列使用输入电平。

在连接到控制器之前,还需要添加电阻和二极管来保护电路和消除反馈。

4. 软件设计软件设计主要包括程序的循环扫描和按键状态的处理。

可以使用循环来不断扫描每行和每列的电平,当检测到按键被按下时,记录下按键的位置信息。

接下来,根据按键的状态,进行相应的处理操作,输出对应的字符或执行特定的功能。

程序还需要处理按键的反弹,以避免误操作。

5. 示例代码以下是一个简单的矩阵键盘程序设计的示例代码,采用C语言编写:cinclude <stdio.h>include <stdbool.h>// 定义矩阵键盘的行列数define ROWS 4define COLS 4// 定义矩阵键盘的字符映射表char keys[ROWS][COLS] = {{'1', '2', '3', 'A'},{'4', '5', '6', 'B'},{'7', '8', '9', 'C'},{'', '0', '', 'D'}};// 定义矩阵键盘状态数组bool keyState[ROWS][COLS] = {0};// 矩阵键盘扫描函数void scanKeyboard() {// 扫描行for (int row = 0; row < ROWS; row++) {// 将当前行的输出电平设置为低电平setRowLow(row);// 扫描列for (int col = 0; col < COLS; col++) {// 检测当前列的输入电平if (getColLevel(col)) {// 当检测到按键被按下时,更新按键状态 keyState[row][col] = true;} else {// 当检测到按键未按下时,更新按键状态 keyState[row][col] = false;}}// 将当前行的输出电平恢复为高电平setRowHigh(row);}}int mn() {while (1) {// 扫描矩阵键盘scanKeyboard();// 处理按键状态for (int row = 0; row < ROWS; row++) {for (int col = 0; col < COLS; col++) {// 检测到按键被按下时,输出对应的字符if (keyState[row][col]) { printf(\。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

二、矩阵键盘显示电路设计(显示键盘值的平方)矩阵键盘显示电路的设计一、实验目的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 所示。

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

图10-4 4X4 矩阵键盘电路原理图表10-1 4X4 矩阵键与F PGA 的管脚连接表四、实验步骤1、打开Q UARTUSII 软件,新建一个工程。

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

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

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

方法同实验一。

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

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

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

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

表 10-2 端口管脚分配表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】中才有可能低电平输入。

*************************************************/module keys(clk_50M,rst_n,row,col,dataout,smg_wei);/*************************************************/output [3:0]col; //矩阵键盘列input rst_n; //复位键input clk_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;/*************************************************/assign smg_wei=0; //八个数码管显示/*************************************************///分频部分开始/*************************************************/ reg[19:0]cnt; //计数子always @(posedge clk_50M or negedge rst_n)if(!rst_n)cnt<=0;elsecnt<=cnt+1'b1;wire key_clk=cnt[19];// 2^20/50M=21ms/*************************************************状态机部分独热码编码*************************************************/parameter NO_KEY_PRESSED=6'b000_001;//没有键按下parameter SCAN_COL0 =6'b000_010;//扫描第0 列parameter SCAN_COL1 =6'b000_100;//扫描第1 列parameter SCAN_COL2 =6'b001_000;//扫描第2 列parameter SCAN_COL3 =6'b010_000;//扫描第3 列parameter KEY_PRESSED =6'b100_000;//有键按下/*************************************************/ reg [5:0]current_state,next_state; //现态和次态/*************************************************///复位/*************************************************/always @(posedge key_clk or negedge rst_n)if(!rst_n)current_state<=NO_KEY_PRESSED;elsecurrent_state<=next_state;/*************************************************/always @ * //(current_state) //根据条件转移状态case (current_state)NO_KEY_PRESSED: //没有键按下if(row!=4'hf)next_state=SCAN_COL0;elsenext_state=NO_KEY_PRESSED;SCAN_COL0: //扫描第0 列if(row!=4'hf)next_state=KEY_PRESSED;elsenext_state=SCAN_COL1;SCAN_COL1: //扫描第1 列if(row!=4'hf)next_state=KEY_PRESSED;elsenext_state=SCAN_COL2;SCAN_COL2: //扫描第2 列if(row!=4'hf)next_state=KEY_PRESSED;elsenext_state=SCAN_COL3;SCAN_COL3: //扫描第3 列if(row!=4'hf)next_state=KEY_PRESSED;elsenext_state=NO_KEY_PRESSED;KEY_PRESSED: //有按键按下if(row!=4'hf)next_state=KEY_PRESSED;elsenext_state=NO_KEY_PRESSED;endcase/*************************************************/reg key_pressed_flag; //按键按下标志reg [3:0]col_val; //列值reg [3:0]row_val; //行值/*************************************************/ //根据次态,给相应的寄存器赋值/*************************************************/always @(posedge key_clk or negedge rst_n)if(!rst_n) //复位begincol<=4'h0;key_pressed_flag<=0;endelsecase (next_state)NO_KEY_PRESSED:begincol<=4'h0;key_pressed_flag<=0;endSCAN_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: //有按键按下begincol_val<=col; // 锁存列值row_val<=row; // 锁存行值key_pressed_flag<=1;// 置键盘按下标endendcase/****************************************************************************** **/// 扫描行列值部分开始/****************************************************************************** **/always @(posedge key_clk or negedge rst_n)if(!rst_n)key_board_val<=4'h0;elseif(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)begincase(key_board_val)4'h0:dataout<=8'b11000000; //04'h1:dataout<=8'b11111001; //14'h2:dataout<=8'b10100100; //24'h3:dataout<=8'b10110000; //34'h4:dataout<=8'b10011001; //44'h5:dataout<=8'b10010010; //54'h6:dataout<=8'b10000010; //64'h7:dataout<=8'b11111000; //74'h8:dataout<=8'b10000000; //84'h9:dataout<=8'b10010000; //94'hA:dataout<=8'b10001000; //a4'hB:dataout<=8'b10000011; //b4'hC:dataout<=8'b11000110; //c4'hD:dataout<=8'b10100001; //d4'hE:dataout<=8'b10000110; //e4'hF:dataout<=8'b10001110; //fendcaseend/*********************************************************************************/// 键盘值转换为数码管显示结束/****************************************************************************** ***/endmodule。

相关文档
最新文档