1 /*
 2 //按键消抖模块:
 3 //功能:输入有抖动的按键信号,输入无抖动的按键信号。
 4 //原理:抖动时间往往小于20ms,因此当检测到按键输入变化(按下或者松开)时,
 5 //    每隔20ms将输入采样给输出,这样就可以滤除抖动了
 6 //工作过程:需要定义两个中间寄存器,一个是按键变化的标志寄存器,按键按下或者松开时,
 7 //    该标志寄存器跳变为1,否则为0。另外一个是延时/采样计数器,在按键变化后,开始进行20ms的延时,延时结束后
 8 //    将按键输入赋值给输出,完成采样。
 9 //注意事项:1.输入的时钟不一样,因此20ms需要的计数长度也不一样,本模块的输入时钟是100MHz,因此计数时长为2000000.
10            2.复位时的按键输出,需要根据外设情况而定。如果按键没有按下时为1,则复位时的按键输出也应该为1.
11 */
12 module key_jitter(
13         input       clk    ,
14         input       key_in      ,
15         input       rst_n       ,
16         output reg  key_out      
17 );
18 //-------------------------------key jitter-----------------------------------
19 
20 // 20ms parameter
21 localparam TIME_20MS = 2_000_000;       // 20ms is 50Hz,100M/50 = 2M = 2_000_000
22 
23 // variable
24 reg [20:0] cnt;
25 reg key_cnt_en;
26 
27 // debounce time passed, refresh key state
28 always @(posedge clk or negedge rst_n) begin
29     if(rst_n == 1'b0)
30         key_out <= 1'b1;//没有按下按键的时候为高电平(不同的外设不一样,有的外设外设按键没有按下时为0,需要修改)
31     else if(cnt == TIME_20MS )//每隔20ms就将输入赋值给输出,其实相当于以20ms的频率对按键信号进行采样
32         key_out <= key_in;//由于抖动时间往往小于20ms,因此就过滤掉抖动了
33 end
34 
35 // while in debounce state, count, otherwise 0
36 always @(posedge clk or negedge rst_n) begin
37     if(rst_n == 1'b0)
38         cnt <= 21'd0;
39     else if(key_cnt_en)//在按键按下的时候才进行计数,计数经过20ms就输出
40         cnt <= cnt + 1'b1;
41     else
42         cnt <= 21'd0; 
43 end
44  
45  // enable count
46 always @(posedge clk or negedge rst_n) begin//按键有变化,允许计数
47         if(rst_n == 1'b0)
48             key_cnt_en <= 1'b0;
49         else if(key_cnt_en == 1'b0 && key_in != key_out)//key_in 不等于 key_out意味着按键变化,可以开始进行计数
50             key_cnt_en <= 1'b1;
51         else if(cnt == TIME_20MS )//计数到20ms以后,进行清零
52             key_cnt_en <= 1'b0;
53 end
54 
55 //=================================================================================
56 
57 
58 endmodule 

 

 

仿真的时候,可以适当减少计数长度哦

 

posted on 2019-08-22 12:59  IC_learner  阅读(1482)  评论(0)    收藏  举报