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
仿真的时候,可以适当减少计数长度哦
不忘初心:写博客最初目的就是记录自己容易忘记的东西,而不是像写书那样专门写给别人看的。所以,除禁止转载的博文外,其他博文可以转载。
尽自己的努力,做到更好!
浙公网安备 33010602011771号