`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被点亮;
//
module sw_debounce(
input
input
input
output
//---------------------------------------------------------------------------
reg[2:0] key_rst;
always @(posedge clk
reg[2:0] key_rst_r;
always @ ( posedge clk
//当寄存器key_rst由1变为0时,led_an的值变为高,维持一个时钟周期
wire[2:0] key_an = key_rst_r & ( ~key_rst);
//---------------------------------------------------------------------------
reg[19:0]
always @ (posedge clk
reg[2:0] low_sw;
always @(posedge clk
//---------------------------------------------------------------------------
reg
always @ ( posedge clk
//当寄存器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)
assign led_d3 = d1 ? 1'b1 : 1'b0;
assign led_d2 = d2 ? 1'b1 : 1'b0;
assign led_d1 = d3 ? 1'b1 : 1'b0;
endmodule
程序功能:具有松手检测功能的按键消抖程序
程序说明:
脉冲检测法:即在按键按下时产生一个周期的脉冲信号,按键松开是也产生一个周期的脉冲信号。
主要设计思路:检测到按键按下时,延时20ms,然后再检测是否真的被按下,确实被按下时使能松手检测信号,检测松手,当第一次检测到松手时,延时20ms,再次检测松手,确实松手时led控制信号翻转。
Module debounce(rst_n,clk,pin_in,pin_out);
input rst_n; //复位信号,低电平有效
input clk; //时钟信号,50M
input pin_in; //按键信号,输入0表示被按下
output pin_out; //输出信号
reg rpin_out;
reg en; //松手检测使能信号
parameter T1ms=16’hc350; //1ms计数值
parameter n=8’d20; //20个1ms 即20ms
//第一次检测:
reg key1_HtoL,key2_HtoL;
reg key1_LtoH,key2_LtoH;
wire key_fall,key_rise;
always @(posedge clk or negedge rst_n)
if(!rst_n)
begin
key1_HtoL<=1’b1;
key2_HtoL<=1’b1;
key1_LtoH<=1’b0;
key2_LtoH<=1’b0;
end
else
begin
key1_HtoL<=pin_in;
key2_HtoL<=key1_HtoL;
if(en)
begin
key1_LtoH<=pin_in;
key2_LtoH<=key1_LtoH;
end
end
assign key_fall=key2_HtoL&(~key1_HtoL);
assign key_rise=(~key2_LtoH)&key1_LtoH;
//通过以上算法,一旦检测到按键按下,key_fall拉高一个时钟周期,同理,在en=1的情况下,一旦检测到按键松手了,key_rise也将拉高一个时钟周期。
延时20ms,key_fall或key_rise为1时,清零count和num,开始计时
reg[15:0] count;
reg[7:0] num;
always @(posedge clk or negedge rst_n)
if(!rst_n)count<=0;
elseif(key_fall|key_rise) count<=0;
elsecount<=count+1’b1;
always @(posedge clk or negedge rst_n)
if(!rst_n)num<=0;
elseif(key_fall|key_rise) num<=0;
elseif(count==T1ms) num<=num+1’b1’
//第二次检测:
reg sw1_HtoL,sw2_HtoL;
reg sw1_LtoH,sw2_LtoH;
wire sw_fall,sw_rise;
always @(posedge clk or negedge rst_n)
if(!rst_n)
begin
sw1_HtoL<=1’b1;
sw2_HtoL<=1’b1;
sw1_LtoH<=1’b0;
sw2_LtoH<=1’b0;
end
elseif(num>=n)
begin
sw1_HtoL<=pin_in;
sw2_HtoL<=sw1_HtoL;
if(en)
begin
sw1_LtoH<=pin_in;
sw2_LtoH<=sw1_LtoH;
end
end
assign sw_fall=sw2_HtoL&(~sw1_HtoL);
assign sw_rise=(~sw2_LtoH)&sw1_LtoH;
always @(posedge clk or negedge rst_n)
if(!rst_n) en<=1’b0;
elseif(sw_fall) en<=1’b1; //按键按下时使能松手检测
always @(posedge clk or negedge rst_n)
if(!rst_n) rpin_out<=1’b0;
elseif(sw_rise) rpin_out<=~rpin_out; //松手是翻转
assign pin_out=rpin_out?1’b1:1’b0;
endmodule