键盘消抖--特权同学代码
2013-12-02 09:10
375 查看
原文地址:键盘消抖--特权同学代码作者:一只大笨鹅
首先将按键值保存两次,以检验按键值的变化。当按键值变后将计数器置0,否则继续加1。当计数器值等于fffff的时候,说明按键是正常按下的,接着保存两次,检测值的变化。若相应位有变化,则将相应的led控制取反。(好像新的代码中键值只检验了一次,不过找不到新代码了。)
`timescale 1ns / 1ps
////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
特权
//
// Create Date:
// Design Name:
// Module Name:
// Project Name:
// Target Device:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 欢迎加入EDN的FPGA/CPLD助学小组一起讨论:http://group.ednchina.com/1375/
////////////////////////////////////////////////////////////////////////////////
//说明:当三个独立按键的某一个被按下后,相应的LED被点亮;
//
再次按下后,LED熄灭,按键控制LED亮灭
module sw_debounce(
clk,rst_n,
sw1_n,sw2_n,sw3_n,
led_d1,led_d2,led_d3
);
input
clk;
//主时钟信号,50MHz
input
rst_n;
//复位信号,低有效
input sw1_n,sw2_n,sw3_n;
//三个独立按键,低表示按下
output
led_d1,led_d2,led_d3;
//发光二极管,分别由按键控制
//---------------------------------------------------------------------------
reg[2:0] key_rst;
always @(posedge clk or negedge rst_n)
if (!rst_n)
key_rst <= 3'b111;
else key_rst
<= {sw3_n,sw2_n,sw1_n};
reg[2:0]
key_rst_r;
//每个时钟周期的上升沿将low_sw信号锁存到low_sw_r中
always @ ( posedge clk or negedge rst_n )
if (!rst_n)
key_rst_r <= 3'b111;
else
key_rst_r <= key_rst;
//当寄存器key_rst由1变为0时,led_an的值变为高,维持一个时钟周期
wire[2:0] key_an = key_rst_r
& ( ~key_rst);
//---------------------------------------------------------------------------
reg[19:0]
cnt;
//计数寄存器
always @ (posedge clk or negedge rst_n)
if (!rst_n)
cnt <= 20'd0;
//异步复位
else
if(key_an) cnt <=20'd0;
else cnt
<= cnt + 1'b1;
reg[2:0] low_sw;
always @(posedge clk or negedge rst_n)
if (!rst_n)
low_sw <= 3'b111;
else if (cnt
== 20'hfffff)
//满20ms,将按键值锁存到寄存器low_sw中
cnt == 20'hfffff
low_sw <= {sw3_n,sw2_n,sw1_n};
//---------------------------------------------------------------------------
reg [2:0]
low_sw_r;
//每个时钟周期的上升沿将low_sw信号锁存到low_sw_r中
always @ ( posedge clk or negedge rst_n )
if (!rst_n)
low_sw_r <= 3'b111;
else
low_sw_r <= low_sw;
//当寄存器low_sw由1变为0时,led_ctrl的值变为高,维持一个时钟周期
wire[2:0] led_ctrl = low_sw_r[2:0] & (
~low_sw[2:0]);
reg d1;
reg d2;
reg d3;
always @ (posedge clk or negedge rst_n)
if (!rst_n)
begin
d1 <= 1'b0;
d2 <= 1'b0;
d3 <= 1'b0;
end
else
begin
//某个按键值变化时,LED将做亮灭翻转
if ( led_ctrl[0] ) d1 <=
~d1;
if ( led_ctrl[1] ) d2 <= ~d2;
if ( led_ctrl[2] ) d3 <= ~d3;
end
assign led_d3 = d1 ? 1'b1 :
1'b0;
//LED翻转输出
assign led_d2 = d2 ? 1'b1 : 1'b0;
assign led_d1 = d3 ? 1'b1 : 1'b0;
endmodule
首先将按键值保存两次,以检验按键值的变化。当按键值变后将计数器置0,否则继续加1。当计数器值等于fffff的时候,说明按键是正常按下的,接着保存两次,检测值的变化。若相应位有变化,则将相应的led控制取反。(好像新的代码中键值只检验了一次,不过找不到新代码了。)
`timescale 1ns / 1ps
////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
特权
//
// Create Date:
// Design Name:
// Module Name:
// Project Name:
// Target Device:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 欢迎加入EDN的FPGA/CPLD助学小组一起讨论:http://group.ednchina.com/1375/
////////////////////////////////////////////////////////////////////////////////
//说明:当三个独立按键的某一个被按下后,相应的LED被点亮;
//
再次按下后,LED熄灭,按键控制LED亮灭
module sw_debounce(
clk,rst_n,
sw1_n,sw2_n,sw3_n,
led_d1,led_d2,led_d3
);
input
clk;
//主时钟信号,50MHz
input
rst_n;
//复位信号,低有效
input sw1_n,sw2_n,sw3_n;
//三个独立按键,低表示按下
output
led_d1,led_d2,led_d3;
//发光二极管,分别由按键控制
//---------------------------------------------------------------------------
reg[2:0] key_rst;
always @(posedge clk or negedge rst_n)
if (!rst_n)
key_rst <= 3'b111;
else key_rst
<= {sw3_n,sw2_n,sw1_n};
reg[2:0]
key_rst_r;
//每个时钟周期的上升沿将low_sw信号锁存到low_sw_r中
always @ ( posedge clk or negedge rst_n )
if (!rst_n)
key_rst_r <= 3'b111;
else
key_rst_r <= key_rst;
//当寄存器key_rst由1变为0时,led_an的值变为高,维持一个时钟周期
wire[2:0] key_an = key_rst_r
& ( ~key_rst);
//---------------------------------------------------------------------------
reg[19:0]
cnt;
//计数寄存器
always @ (posedge clk or negedge rst_n)
if (!rst_n)
cnt <= 20'd0;
//异步复位
else
if(key_an) cnt <=20'd0;
else cnt
<= cnt + 1'b1;
reg[2:0] low_sw;
always @(posedge clk or negedge rst_n)
if (!rst_n)
low_sw <= 3'b111;
else if (cnt
== 20'hfffff)
//满20ms,将按键值锁存到寄存器low_sw中
cnt == 20'hfffff
low_sw <= {sw3_n,sw2_n,sw1_n};
//---------------------------------------------------------------------------
reg [2:0]
low_sw_r;
//每个时钟周期的上升沿将low_sw信号锁存到low_sw_r中
always @ ( posedge clk or negedge rst_n )
if (!rst_n)
low_sw_r <= 3'b111;
else
low_sw_r <= low_sw;
//当寄存器low_sw由1变为0时,led_ctrl的值变为高,维持一个时钟周期
wire[2:0] led_ctrl = low_sw_r[2:0] & (
~low_sw[2:0]);
reg d1;
reg d2;
reg d3;
always @ (posedge clk or negedge rst_n)
if (!rst_n)
begin
d1 <= 1'b0;
d2 <= 1'b0;
d3 <= 1'b0;
end
else
begin
//某个按键值变化时,LED将做亮灭翻转
if ( led_ctrl[0] ) d1 <=
~d1;
if ( led_ctrl[1] ) d2 <= ~d2;
if ( led_ctrl[2] ) d3 <= ~d3;
end
assign led_d3 = d1 ? 1'b1 :
1'b0;
//LED翻转输出
assign led_d2 = d2 ? 1'b1 : 1'b0;
assign led_d1 = d3 ? 1'b1 : 1'b0;
endmodule
相关文章推荐
- S3C6410的启动代码分析 一
- 6410在rvds下编译启动代码报错分析
- 注意:开发环境不同,启动代码不同…
- 键盘消抖--特权同学代码
- Qt中UTF-8转Unicode
- delphi 导出到excel的7种方法
- C#调用C++编译生成的dll文件
- JAVA细节使用20131202
- javabean总结
- matlab中数理统计的一些工具函数
- C++中编译生成dll(动态链接库)文件
- jdk与jre的区别
- Python查询天气预报
- php 二维码
- JDK6和JDK7中String的substring()方法及其差异
- Qt动画效果展示
- AWS Toolkit for Eclipse的安装和一个用户反馈的问题
- 2013级C++第15周项目——二维数组
- A JavaFX based Game Authoring System
- Spring集成Hibernate 理解LocalSessionFactoryBean