按键消抖
由于按键在按下的时候会出现轻微的抖动,一般情况下认为当按下或者抬起状态超过10ms的时候,算是稳定。
如下是源代码:
当key与key_reg状态不同的时候,是发生抖动的时候,或者是按下或者抬起的时候,如果计数超过10ms,则把此时key的状态赋值给key_value,key_flag表示此时的信号是消抖后的信号。
> module xiaodou(clk,rst_n,key,key_value,key_flag);
> input clk,rst_n;
> input key;
> output reg key_value;
> output reg key_flag;
> reg key_reg;
> reg [4:0] cnt;
> always @(posedge clk or negedge rst_n) begin
> if(!rst_n)
> key_reg<=0;
> else
> key_reg<=key;
> end
>
> always @(posedge clk or negedge rst_n) begin
> if(!rst_n)
> cnt <= 0;
> else begin
> if(key!=key_reg)
> cnt <= 20;
> else begin
> if(cnt > 0)
> cnt <= cnt-1;
> else
> cnt <= cnt;
> end
> end
> end
>
> //key_value
> always @(posedge clk or negedge rst_n) begin
> if(!rst_n)
> key_value <= 1;
> else begin
> if(cnt==1)
> key_value<=key;
> else
> key_value<=key_value;
> end
> end
>
> //key_flag
> always @(posedge clk or negedge rst_n) begin
> if(!rst_n)
> key_flag<=0;
> else begin
> if(cnt==1)
> key_flag<=1;
> else
> key_flag<=0;
> end
> end
>
> endmodule
测试文件
> `timescale 1ns/1ns
> module xiaodu_tb;
> reg clk,rst_n;
> reg key;
> wire key_value;
> wire key_flag;
>
> xiaodou inst(
> .clk(clk),
> .rst_n(rst_n),
> .key(key),
> .key_value(key_value),
> .key_flag(key_flag)
> );
> always #10 clk=~clk;
> reg [8:0] time1;
>
> initial
> begin
> clk=0;
> rst_n=0;
> time1=0;
> key=1;
> #100 rst_n=1;
> end
> always #20 //time1的数据宽度为20,产生连续的加法操作
> if(time1==200)
> time1=0;
> else
> time1=time1+1;
> always #20
> if((time1<20)||(time1>80&&time1<100))
> key<={$random};
> else if(time1>100)
> key<=1;
> else
> key<=0;
>
> endmodule