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

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

电路图:

代码

/********************************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. PL/0编译器(java version)–Pcode.java

    1: package compiler; 2:   3: /** 4: * //虚拟机指令 5: * 6: * @author jiangnan 7: * 8: */ 9: public class ...

  2. POJ3259Wormholes(判断是否存在负回路)

    Wormholes Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 38300   Accepted: 14095 Descr ...

  3. NSKeyedArchiver 类 格式

    结论:NSKeyedArchiver 以健值对+类名的形式保存数据: NSDictionary *tDic = @{@"kxxxx":@"hhhh",@&quo ...

  4. struts+spring action应配置为scope="prototype"

    truts+spring action应配置为scope="prototype" <bean id="personAction" scope=" ...

  5. 新浪微博客户端(13)-使用UIWebView加载OAuth授权界面

    使用UIWebView加载OAuth授权界面 DJOAuthViewController.m #import "DJOAuthViewController.h" @interfac ...

  6. Request请求总结

    Request.ServerVariables["Url"] 返回服务器地址 Request.ServerVariables["Path_Info"] 客户端提 ...

  7. Apache prefork 模块指令分析

    问题背景: 在一台只有内存的vps上安装directadmin之后经常内存耗,经过查看之后发现Apache成了罪魁祸首急速消耗内存SWAP剩余空间都是0,最终导致内核开始大下杀手,把MySQL都杀了, ...

  8. [codeforces 509]C. Sums of Digits

    [codeforces 509]C. Sums of Digits 试题描述 Vasya had a strictly increasing sequence of positive integers ...

  9. BZOJ 2818

    2818:GCD Description 给定整数$N$,求$1\le x,y\le N$且$\gcd{x,y}$为素数的数对$(x,y)$有多少对. Input $N$ Output RT Samp ...

  10. WAF绕过神器 (过安全狗、智创SQL注入)

    WAF绕过神器 (过安全狗.智创SQL注入) 发布时间:-- :10文章来源:网络文章作者:panni007 点击次数: 次 分享到: QQ空间 QQ微博 新浪微博 开心网 人人网 摘要:起因: by ...