注:key_in 默认为高电平,按键按下为低电平
其实只要检测到20ms内有持续为低电平,就可以认为按键有被按下,如下时序图
在抖动阶段,有检测到高电平的,计数器停止计数add_cnt = 0,计数器cnt清0 ,便于下一次重新计时。
module key_module( clk , rst_n , key_in , key_vld ); parameter DATA_W = 20 ; parameter KEY_W = 4 ; parameter TIME_20MS = 500_000 ; input clk ; input rst_n ; input key_in ; output key_vld ; reg key_vld ; reg [DATA_W-1:0] cnt ; wire add_cnt ; wire end_cnt ; reg flag ; reg key_in_ff1 ; reg key_in_ff0 ; //检测20ms内持续为低电平,就被认为有按键被按下 always @(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin cnt <= 20'b0; end else if(add_cnt)begin if(end_cnt) cnt <= 20'b0; else cnt <= cnt + 1'b1; end else begin cnt <= 0; end end assign add_cnt = flag==1'b0 && (key_in_ff1 != 1'b1); //检测到有抖动,也就是检测有高的脉冲,计数器停止,cnt清0,便于下次重新计数 assign end_cnt = add_cnt && cnt == TIME_20MS - 1; always @(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin flag <= 1'b0; end else if(end_cnt)begin //能够完整的计数到20ms结束, 说明已经检测到了按键有被按下 flag <= 1'b1; end else if(key_in_ff1 == 1'b1)begin //按键释放后,flag 置0 ,方便下次检测 flag <= 1'b0; end end //打两拍,消除亚稳态 always @(posedge clk)begin if(rst_n==1'b0)begin key_in_ff0 <= 0; key_in_ff1 <= 0; end else begin key_in_ff0 <= key_in ; key_in_ff1 <= key_in_ff0; end end always @(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin key_vld <= 0; end else if(end_cnt)begin key_vld <= ~key_in_ff1; end else begin key_vld <= 0; end end endmoduleView Code
标签:cnt,检测,低电平,key,按键,rst,reg From: https://www.cnblogs.com/wen2376/p/17703703.html