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

代码:

    /********************************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. mysql 在linux 修改账号密码

    1.root用户登录到mysql数据库代码示例:/usr/local/mysql/bin/mysql -u root -p (输入密码进入mysql)2.进入mysql,输入:代码示例:use mys ...

  2. SSH如何通过公钥连接云服务器

    导读 通常我们连接远程服务器(linux)windows下通过putty或xshell等工具远程连接.linux下可以直接通过ssh命令连接.其实这两者都是一致的,都是通过ssh协议进行传输. 如果我 ...

  3. SMT 的基本流程?SMT的工艺流程?SMT的设备操作?

    一.SMT工艺流程------单面组装工艺来料检测 --> 丝印焊膏(点贴片胶)--> 贴片 --> 烘干(固化) --> 回流焊接 --> 清洗 --> 检测 - ...

  4. POJ 3641 快速幂+素数

    http://poj.org/problem?id=3641 练手用,结果念题不清,以为是奇偶数WA了一发 #include<iostream> #include<cstdio> ...

  5. BZOJ 2342: [Shoi2011]双倍回文

    Sol Manacher. 非常裸的Manacher啊...为什么有那么多人写Manacher+并查集?Set?Treap?...好神奇... 你只需要在 \(p[i]++\) 的位置加上判断就可以了 ...

  6. 前端之js的常用用法

    js生成标签 // 将标签添加到i1里面 var tag = document.createElement('input'); tag.setAttribute('type', 'text'); ta ...

  7. 9.5---括号是否有效(CC150)

    leetcode原题: char temp ; Stack<Character> stack = new Stack<Character>();//error:Stack< ...

  8. TorgoiseGit配置ssh密钥

    TortoiseGit 使用扩展名为ppk的密钥,而不是ssh-keygen生成的rsa密钥.使用命令ssh-keygen -C "邮箱地址" -t rsa产生的密钥在Tortoi ...

  9. mysql导入导出数据库命令

    1.导出数据库:mysqldump -u 用户名 -p 数据库名 > 导出的文件名 如我输入的命令行: mysqldump -u root -p news > /home/jason/sq ...

  10. zaqar项目介绍

    Zaqar is a multi-tenant cloud messaging and notification service for web and mobile developers. It c ...