这里我们要验证一键两用的情况:点击与长击,单击与双击

代码:

    /********************************Copyright**************************************
**----------------------------File information--------------------------
** File name :key_function_2.v
** CreateDate :2015.03
** Funtions :按键的用法(二):点击和长击,单击和双击
** Operate on :M5C06N3L114C7
** Copyright :All rights reserved.
** Version :V1.0
**---------------------------Modify the file information----------------
** Modified by :
** Modified data :
** Modify Content:
*******************************************************************************/ module key_function_2 (
clk,
rst_n, key_4,
key_5, led_d41,
led_d42,
led_d51,
led_d52 );
input clk;
input rst_n; input key_4; //按键的点击与长击:按下按键后,2S内松开按键则为点击,2s后松开按键为长击,默认未按下为高。
input key_5; /*按键的单击和双击,完成第一次按键后100ms之内第二次按下按键则为双击,否则为单击 */ output led_d41;
output led_d42;
output led_d51;
output led_d52; //---------------------------
//定时2s
reg cnt_en;
localparam t_1s = 'd23999999; /* //实际使用 */
// localparam t_1s = 25'd239; /* //测试使用 */ localparam t_2s = 'd2;
reg [:] cnt;
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
cnt <= ;
end
else if(cnt_en)
begin
if(cnt == t_1s)
cnt <= ;
else
cnt <= cnt + ;
end
else
cnt <= ;
end reg [:] cnt1;
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
cnt1 <= ;
end
else if(cnt_en)
begin
if(cnt1 == 'd2)
cnt1 <= 'd2;
else if(cnt == t_1s)
cnt1 <= cnt1 + ;
end
else
cnt1 <= ;
end //-------------------------------
/* 取key_4的上升沿和下降沿 */
reg [:] key_4_reg;
wire key_4_pos;
wire key_4_neg;
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
key_4_reg <= 'b111;
end
else
begin
key_4_reg <= {key_4_reg[:],key_4};
end
end
assign key_4_pos = (key_4_reg[:] == 'b01);
assign key_4_neg = (key_4_reg[:] == 'b10); //------------------------------
/* 状态机 */
reg [:] state1;
reg key_S;
reg key_L;
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
state1 <= 'd0;
cnt_en <= ;
key_S <= ;
key_L <= ;
end
else
begin
case(state1)
'd0:
begin
cnt_en <= ;
key_S <= ;
key_L <= ;
if(key_4_neg) /* 按键按下 */
state1 <= 'd1;
else
state1 <= 'd0;
end
'd1:
begin
if(key_4_pos) /* 按键释放 */
begin
cnt_en <= ;
state1 <= 'd2;
key_S <= ;
end
else if((key_4_reg=='b000)&&(cnt1 == 2'd2)) /* 按键一直为低,延时2s之后 */
begin
cnt_en <= ;
state1 <= 'd3;
key_L <= ;
end
else
cnt_en <= ;
end
'd2: /* 点击 */
begin
key_S <= ;
state1 <= 'd5;
end
'd3:
begin
key_L <= ;
state1 <= 'd4;
end
'd4:
begin
if(key_4_pos)
state1 <= 'd5;
else
state1 <= 'd4;
end
'd5:
begin
state1 <= 'd0;
end
default:state1 <= 'd0;
endcase end
end reg led_s;
reg led_l;
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
led_s <= ;
end
else if(key_S)
begin
led_s <= ~led_s;
end
end always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
led_l <= ;
end
else if(key_L)
begin
led_l <= ~led_l;
end
end //------------------------------------
localparam t_100ms = 'd2399999; /* //实际使用 */
// localparam t_100ms = 22'd23; /* //测试使用 */
reg [:] cnnt;
reg cnnt_en;
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
cnnt <= ;
end
else if(cnnt_en)
begin
if(cnnt == t_100ms )
cnnt <= t_100ms;
else
cnnt <= cnnt + ;
end
else
cnnt <= ;
end
//-------------------------------
/* 取key_5的上升沿和下降沿 */
reg [:] key_5_reg;
wire key_5_pos;
wire key_5_neg;
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
key_5_reg <= 'b111;
end
else
begin
key_5_reg <= {key_5_reg[:],key_5};
end
end
assign key_5_pos = (key_5_reg[:] == 'b01);
assign key_5_neg = (key_5_reg[:] == 'b10); //------------------------------
/* 状态机 */
reg [:] state2;
reg key_SS;
reg key_D;
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
state2 <= 'd0;
cnnt_en <= ;
key_SS <= ;
key_D <= ;
end
else
begin
case(state2)
'd0:
begin
cnnt_en <= ;
key_SS <= ;
key_D <= ;
if(key_5_neg) /*第一次 按键按下 */
state2 <= 'd1;
else
state2 <= 'd0;
end
'd1:
begin
if(key_5_pos) /*第一次 按键释放 */
begin
state2 <= 'd2;
end
else
state2 <= 'd1;
end
'd2:
begin
if((key_5_neg)&&(cnnt < t_100ms))
begin
cnnt_en <= ;
state2 <= 'd3;
key_D <= ;
end
else if(cnnt ==t_100ms)
begin
cnnt_en <= ;
state2 <= 'd4;
key_SS <= ;
end
else
cnnt_en <= ;
end
'd3:
begin
key_D <= ;
if(key_5_pos)
state2 <= 'd5;
end
'd4:
begin
key_SS <= ;
state2 <= 'd5;
end
'd5:
begin
state2 <= 'd0;
end
default:state2 <= 'd0;
endcase end
end reg led_signal;
reg led_double;
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
led_signal <= ;
end
else if(key_SS)
begin
led_signal <= ~led_signal;
end
end always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
led_double <= ;
end
else if(key_D)
begin
led_double <= ~led_double;
end
end //------------------------
assign led_d41 = led_s;
assign led_d42 = led_l;
assign led_d51 = led_signal;
assign led_d52 = led_double; endmodule

仿真代码:

    /********************************Copyright**************************************
**----------------------------File information--------------------------
** File name :key_function_testbench.v
** CreateDate :2015.03
** Funtions :按键功能的测试文件
** Operate on :M5C06N3L114C7
** Copyright :All rights reserved.
** Version :V1.0
**---------------------------Modify the file information----------------
** Modified by :
** Modified data :
** Modify Content:
*******************************************************************************/
`timescale ns/ ns module key_function_2_tb;
reg clk;
reg rst_n; reg key_4; //按键的点击与长击:按下按键后,2S内松开按键则为点击,2s后松开按键为长击,默认未按下为高。
reg key_5; /*按键的单击和双击,完成第一次按键后100ms之内第二次按下按键则为双击,否则为单击 */ wire led_d41;
wire led_d42;
wire led_d51;
wire led_d52; key_function_2 key_function_2(
.clk,
.rst_n, .key_4,
.key_5, .led_d41,
.led_d42,
.led_d51,
.led_d52 ); parameter tck = ;
parameter t = /tck; always #(t/) clk = ~clk; initial
begin
clk = ;
rst_n = ;
key_4 = ;
key_5 = ; #(*t) rst_n = ;
/* 点击 */
#(*t) key_4 = ;
#(*t) key_4 = ;
#(*t) key_4 = ; /* 长击 */
#(*t);
#(*t) key_4 = ;
#(*t) key_4 = ;
#(*t);
#(*t) key_4 = ; /* 单击 */
#(*t);
#(*t) key_5 = ;
#(*t) key_5 = ;
#(*t) key_5 = ; /* 双击 */
#(*t);
#(*t) key_5 = ;
#(*t) key_5 = ;
#(*t) key_5 = ;
#(*t) key_5 = ;
#(*t) key_5 = ;
#(*t) key_5 = ; end endmodule

仿真波形:

1、点击与长击

2、单击与双击

注:参考资料来自网络。

按键使用方法(二)------verilog的更多相关文章

  1. Android抓包方法(二)之Tcpdump命令+Wireshark

    Android抓包方法(二) 之Tcpdump命令+Wireshark 前言 做前端测试,基本要求会抓包,会分析请求数据包,查看接口是否调用正确,数据返回是否正确,问题产生是定位根本原因等.学会抓包分 ...

  2. Java 简单实用方法二

    整理以前的笔记,在学习Java时候,经常会用到一些方法.虽然简单但是经常使用.因此做成笔记,方便以后查阅 这篇博文先说明构造和使用这些方法. 1,判断String类型数据是否包含中文 可以通过正则表达 ...

  3. SSH框架的多表查询(方法二)增删查改

     必须声明本文章==>http://www.cnblogs.com/zhu520/p/7773133.html  一:在前一个方法(http://www.cnblogs.com/zhu520/p ...

  4. RAC(ReactiveCocoa)使用方法(二)

    RAC(ReactiveCocoa)使用方法(一) RAC(ReactiveCocoa)使用方法(二) 上篇文章:RAC(ReactiveCocoa)使用方法(一) 中主要介绍了一些RAC中常见类的用 ...

  5. Microsoft Edge浏览器下载文件乱码修复方法(二)

    之前有写过"Microsoft Edge浏览器下载文件乱码修复方法",发现很多情况下下载文件乱码问题还是存在,这里对之前内容做简单补充,希望可以帮到大家. 方法二: 默认如果提示下 ...

  6. mybatis由浅入深day02_2一对一查询_2.3方法二:resultMap_resultType和resultMap实现一对一查询小结

    2.3 方法二:resultMap 使用resultMap,定义专门的resultMap用于映射一对一查询结果. 2.3.1 sql语句 同resultType实现的sql SELECT orders ...

  7. Selenium应用代码(常见封装的方法二)

    滚动窗口: //将滚动条滚到适合的位置 , 方法一 public static void setScroll(WebDriver driver,int height){ try { // String ...

  8. HDU - 1166 敌兵布阵 方法一:(线段树+单点修改,区间查询和) 方法二:利用树状数组

    C国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了.A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任务就是要监视这些工兵营地的活动情况.由于 ...

  9. js获取及判断键盘按键的方法

    这篇文章主要介绍了js获取及判断键盘按键的方法,涉及JavaScript键盘事件的获取及键值的判定技巧,具有一定参考借鉴价值,需要的朋友可以参考下   本文实例讲述了js获取及判断键盘按键的方法.分享 ...

  10. 2016/1/25 多线程 作业 方法一 继承Thread 方法二 实现Runnable 多线程笔记

    /* * 1,尝试定义一个继承Thread类的类,并覆盖run()方法, * 在run()方法中每隔100毫秒打印一句话.*/ package Stream; //方法一 继承Thread 实现多线程 ...

随机推荐

  1. UOJ30——【CF Round #278】Tourists

    1.感谢taorunz老师 2.题目大意:就是给个带权无向图,然后有两种操作, 1是修改某个点的权值 2是询问,询问一个值,就是u到v之间经过点权的最小值(不可以经过重复的点) 操作数,点数,边数都不 ...

  2. 如何用phpstorm编辑远程项目

    背景介绍:LAMP开发是很多公司喜欢采用的技术组合,故而做php开发,使用linux环境也是很多公司的要求.本文就来介绍下如何在windows下,使用phpstorm集成开发环境,来开发放在linux ...

  3. hdu 5492

    动态规划 #include<iostream> #include<cstdio> #include<cstring> #include<algorithm&g ...

  4. django xadmin 插件(1)

    1. 插件的作用可以是全局的,也可以是只针对某个模型的.通过其 init_request控制是否加载此插件, demo如下: class SCPCardOverviewPlugin(BaseAdmin ...

  5. EXT Grid celleditor列编辑,动态控制某一单元格只读

    listeners : { beforeedit:function(editor, context, eOpts) { if(context.record.data.hasRatio == " ...

  6. Routing in ASP.NET Web API和配置文件的设定读取

    Routing Tables In ASP.NET Web API, a controller is a class that handles HTTP requests. The public me ...

  7. 通过分析 JDK 源代码研究 TreeMap 红黑树算法实现

    本文转载自http://www.ibm.com/developerworks/cn/java/j-lo-tree/ 目录: TreeSet 和 TreeMap 的关系 TreeMap 的添加节点 Tr ...

  8. 指针 与 数组 以及 a 与 &a的区别

      指针 与数组 并没有什么关系,   指针就是指针,指针变量在32位系统下,永远占4个byte,其值为某一个内存的地址,指针可以指向任何地方,但是不是任何地方你都能通过这个指针变量访问到;   数组 ...

  9. 彻底卸载MySql

    刚装了下MySql,装的过程中由于修改了服务名,导致最后配置假死,不得已,重装. 但是重装时总是失败,于是google了一下,找到彻底卸载mysql的方法: 最近安装本地测试用 MySQL 服务器时总 ...

  10. android课件和源代码

    ppt.rar 代码.rar 也可以自己从这里下载http://pan.baidu.com/share/link?shareid=1287391506&uk=2634355140