矩阵键盘的试验,采用三段式状态机处理方法。

难点在于检测状态机中:按键消抖以后逐列检测。

电路图:

代码

/********************************Copyright**************************************
**----------------------------File information--------------------------
** File name :keyboard.v
** CreateDate :2015.04
** Funtions :4x4矩阵键盘
** Operate on :M5C06N3L114C7
** Copyright :All rights reserved.
** Version :V1.0
**---------------------------Modify the file information----------------
** Modified by :
** Modified data :
** Modify Content: 2015.6
*******************************************************************************/ module keyboard(
clk,
rst_n, l_in,
h_out, test_1,
test_2, key_val,
key_val_flag
);
input clk; /* clk = 24M */
input rst_n;
input [:] l_in; //列输入,一般接上拉,为高电平 output test_1;
output test_2; output [:] h_out; //行输出信号,低有效
output [:] key_val; //按键值,输出
output key_val_flag; wire [:] key_val;
reg test_1;
reg test_2;
//*************************************
/* 分频Ƶ*20ms,用于消抖 .状态机直接用clk_20ms,则可以跳过消抖*/ // `define CLK_24M
`define CLK_20M `ifdef CLK_24M
parameter t_20ms = 'd479999;
`endif `ifdef CLK_20M
parameter t_20ms = 'd399999;
`endif reg [:] cnt;
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
cnt <= 'd0;
end
else
begin
if(cnt == t_20ms) cnt <= 'd0;
else cnt <= cnt + 'd1;
end
end
wire shake_over = (cnt == t_20ms);
//******************状态机******************
localparam NO_KEY_pressed = 'd0; /* 初始化 */
localparam key_shake_1 = 'd1; /* 消抖1 */
localparam KEY_h_1 = 'd2; /* 检测第一列 */
localparam KEY_h_2 = 'd3; /* 检测第二列 */
localparam KEY_h_3 = 'd4; /* 检测第三列 */
localparam KEY_h_4 = 'd5; /* 检测第四列 */
localparam KEY_pressed = 'd6; /* 按键值输出*/
localparam key_shake_2 = 'd7; /* 消抖2 */ /* 3-1 */
reg [:] current_state;
reg [:] next_state;
reg key_pressed_flag;
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
current_state <= ;
end
else if(shake_over)
begin
current_state <= next_state;
end
else
current_state <= current_state ;
end /* 3-2 */
always @(*)
begin
next_state = NO_KEY_pressed;
case(current_state)
NO_KEY_pressed:
begin
if(l_in != 'hf) next_state = key_shake_1;
else next_state = NO_KEY_pressed;
end
key_shake_1:
begin
if(l_in != 'hf) next_state = KEY_h_1;
else next_state = NO_KEY_pressed;
end
KEY_h_1:
begin
if(l_in != 'hf) next_state = KEY_pressed;
else next_state = KEY_h_2;
end
KEY_h_2:
begin
if(l_in != 'hf) next_state = KEY_pressed;
else next_state = KEY_h_3;
end
KEY_h_3:
begin
if(l_in != 'hf) next_state = KEY_pressed;
else next_state = KEY_h_4;
end
KEY_h_4:
begin
if(l_in != 'hf) next_state = KEY_pressed;
else next_state = NO_KEY_pressed;
end
KEY_pressed:
begin
if(l_in != 'hf) next_state = key_shake_2;
else next_state = NO_KEY_pressed;
end
key_shake_2:
begin
if(l_in != 'hf) next_state = key_shake_2;
else next_state = NO_KEY_pressed;
end
default:;
endcase
end /* 3-3 */ reg [:] l_in_reg;
reg [:] h_out_reg;
reg [:] h_out;
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
l_in_reg <= 'd0;
h_out_reg<= 'd0;
h_out <= 'd0;
key_pressed_flag <= ;
end
else if(shake_over)
begin
case(next_state)
NO_KEY_pressed:
begin
l_in_reg <= l_in_reg;
h_out_reg<= h_out_reg;
h_out <= 'd0;
key_pressed_flag <= ;
end
KEY_h_1:
begin
h_out <= 'b1110;
end
KEY_h_2:
begin
h_out <= 'b1101;
end
KEY_h_3:
begin
h_out <= 'b1011;
end
KEY_h_4:
begin
h_out <= 'b0111;
end KEY_pressed:
begin
l_in_reg <= l_in;
h_out_reg<= h_out;
end
key_shake_2: begin key_pressed_flag <= ; end
default:;
endcase
end
end reg [:] temp_key_val;
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
temp_key_val <= 'd0;
else
begin
if(key_pressed_flag)
begin
case ({h_out_reg,l_in_reg})
'b1110_1110 : temp_key_val <= 4'd0;
'b1110_1101 : temp_key_val <= 4'd1;
'b1110_1011 : temp_key_val <= 4'd2;
'b1110_0111 : temp_key_val <= 4'd3; 'b1101_1110 : temp_key_val <= 4'd4;
'b1101_1101 : temp_key_val <= 4'd5;
'b1101_1011 : temp_key_val <= 4'd6;
'b1101_0111 : temp_key_val <= 4'd7; 'b1011_1110 : temp_key_val <= 4'd8;
'b1011_1101 : temp_key_val <= 4'd9;
'b1011_1011 : temp_key_val <= 4'd10;
'b1011_0111 : temp_key_val <= 4'd11; 'b0111_1110 : temp_key_val <= 4'd12;
'b0111_1101 : temp_key_val <= 4'd13;
'b0111_1011 : temp_key_val <= 4'd14;
'b0111_0111 : temp_key_val <= 4'd15; default: temp_key_val <= 'd0;
endcase
end
end
end
assign key_val = ~temp_key_val;
assign key_val_flag = ~key_pressed_flag;
endmodule

测试代码:

module  testbench;

 reg             clk;          /* clk = 24M */
reg rst_n;
reg [:] l_in; //列输入,一般接上拉,为高电平 wire test_1;
wire test_2; wire [:] h_out; //行输出信号,低有效
wire [:] key_val; //按键值,输出
wire key_val_flag; keyboard u1(
.clk,
.rst_n, .l_in,
.h_out, .test_1,
.test_2, .key_val,
.key_val_flag
);
defparam u1. t_20ms = ; parameter tck = ;
parameter t = /tck; always
#(t/) clk = ~clk; task key_test;
input [:] data_key;
begin
#(*t) l_in = data_key;
#(*t) l_in = 'b1111;
#(*t);
end
endtask initial
begin
clk = ;
rst_n = ;
l_in = 'd0; #(*t) rst_n = ; #(*t);
key_test('B1101);
key_test('B1011); end endmodule

仿真波形:

矩阵按键的试验---verilog的更多相关文章

  1. C51 矩阵按键 个人笔记

    矩阵按键 电路 每个按键一端和同行一端相连(JP4的高4位),另一端和同列一端相连(JP4的低4位) 判断按键是否按下: 法一:逐行扫描 for(int i = 8 ; i>3 ; i-- ) ...

  2. 按键消抖-----verilog

    实际系统中常用的按键大部分都是轻触式按键,如下图所示.该按键内部由一个弹簧片和两个固定触点组成,当弹簧片被按下,则两个固定触点接通,按键闭合.弹簧片松开,两个触点断开,按键也就断开了.根据这种按键的机 ...

  3. 【C51】单片机独立按键与矩阵按键

    独立按键 首先既然是检测输入,对于当然要用到拉电阻,来检测引脚电平变化变化.51单片机中,除了P0口外,P2,P3,P4都是内置上拉电阻的准双向IO口,一般 的 51 P0引脚都外接了上拉电阻,当然也 ...

  4. AD按键-矩阵按键:

    原理:利用数组分压+AD采集: 优点:一个IO口可以做成多个按键,节省IO口(矩阵键盘在>4时优点才能体现出来):可备用作为AD基准输入. 缺点:不能做成组合按键(或者电阻要精确选择):且离IO ...

  5. AD按键-矩阵按键-独立按键:

    原理:利用数组分压+AD采集: 优点:一个IO口可以做成多个按键,节省IO口(矩阵键盘在>4时优点才能体现出来):可备用作为AD基准输入. 缺点:不能做成组合按键(或者电阻要精确选择):且离IO ...

  6. C51 原创电子琴 (蜂鸣器/计时器/中断/矩阵按键)

    需求分析 用C51的16个矩阵按键当作两个八度的琴键 按下时发出相应音调的声音,静态数码管显示相应音符的数字. 为了解锁更多曲目,两个多的琴键设计成#4,显示时加上小数点 下图分别为1和#4的显示,其 ...

  7. 【.NET 与树莓派】矩阵按键

    欢迎收看火星卫视,本期节目咱们严重探讨一下矩阵按键. 所谓矩阵按键,就是一个小键盘(其实一块PCB板),上面有几个 Key(开关),你不按下去的时候,电路是断开的,你按下去电路就会接通.至于说有多少个 ...

  8. ARDUINO入门按键通信试验

    1.1按键实验 1.需要学习的知识: 1) Arduino 的输入口配置方法,配置函数的用法 通过pinMode()函数,可以将ADUINO的引脚配置(INPUT)输入模式 2) 搞懂什么是抖动 机械 ...

  9. SPI的通信试验 --verilog (从机-全双工)

    SPI的 有关知识参考FPGA作为主机的通信实验. 本实验中FPGA作为从机通过SPI与MCU等通信的试验,可以在时钟上升沿接收数据并且在时钟下降沿发送数据,模仿全双工模式.接收的 数据作为地址,通过 ...

随机推荐

  1. 如何在 Ubuntu 14.04 里面配置 chroot 环境

    你可能会有很多理由想要把一个应用.一个用户或者一个环境与你的 Linux 系统隔离开来.不同的操作系统有不同的实现方式,而在 Linux 中,一个典型的方式就是 chroot 环境. 在这份教程中,我 ...

  2. 在ECSHOP后台左侧导航中增加新菜单

    在ECSHOP后台左侧导航中增加新菜单 ECSHOP教程/ ecshop教程网(www.ecshop119.com) 2011-11-08   有个别高级用户(懂PHP的),提到这样的问题: 在后台管 ...

  3. 一种透明效果的view

    设置这个view背景色: [UIColor colorWithRed: green: blue: alpha:0.3]; 效果如下:

  4. shell中的循环

    shell中的循环 for循环 类似于C语言的步长控制 例如: ;i<=;i++)); ); done 将1到10,依次乘以4,然后打印出来. 这里顺便提一下,shell里面表达式的计算,可以有 ...

  5. TFS2008解除独占式锁定文件命令(转载)

    使用场景:如果项目团队成员A对项目某个文件以独占式方式签出,恰好那天该成员A没有来上班而成员需要对此文件进入修改并check in,这时需要先把A对该文件的锁定解除.没有IDE可以使用,只能使用下面的 ...

  6. 把电脑装成ubuntu系统了

    2014年一月11日 今天本来想在自己的电脑上装双系统,电脑本来有个win7,想再装一个ubuntu. 本来想用wubi装,可是wubi没法安装13.10,并且wubi安装后,读写速度也不快. 在网上 ...

  7. js实现剪切、复制、粘贴——clipBoard.js

    摘要: 最近项目上要实现一个点击按钮复制链接的功能,刚开始查找了一些资料,找了几款插件,ZeroClipboard是通过flash实现的复制功能,随着越来越多的提议废除flash,于是就想能不能通过j ...

  8. quartz定时任务时间设置

    这些星号由左到右按顺序代表 :     *    *     *     *    *     *   *                                   格式: [秒] [分] ...

  9. xcode Git

    http://blog.csdn.net/w13770269691/article/details/38704941 在已有的git库中搭建新库,并且将本地的git仓库,上传到远程服务器的git库中, ...

  10. ruby Errors & Exceptions

    When you first started coding, errors were probably the last thing you wanted to see. After all, it’ ...