今天简单的说说按键消抖,原理特别好理解,其实就是延时,作必定时间的延时后取值一次,就可以获得特定的消抖后的状态了。web
为何要消抖? 见图:
咱们能够看到,但按键按下的那一刻,存在一段时间的抖动,同时在释放按键的一段时间里也是存在抖动的,这就可能致使状态在识别的时候可能检测为屡次的按键,由于运行过程当中普通的检测一次状态key为1就执行一次按键操做。因此咱们在使用按键时每每须要消抖。svg
消抖方式有不少种,这里我提供一种相对而言比较简单容易理解的方式,经过延时来消抖。
咱们知道,抖动时间的长短由按键的机械特性决定,通常为5ms~10ms.学习
你们看原理图,其实咱们要作的就是,但按键按下去后,只在中间稳定的某一个时刻(10ms)取一个真正按键的使能值就行了,详细的见代码:
(鉴于板子通常有四个按键,这里的代码是对四个按键消抖的)code
/*******按键消抖*******/ module key_vibration( input mclk, input rst_n, input [3:0] key, output reg [3:0] key_en ); parameter DURATION = 50_000; //延时10ms reg [15:0] cnt; wire ken_enable; assign ken_enable = key[3] | key[2] | key[1] | key[0]; //只要任意按键被按下,相应的按键进行消抖 always @(posedge mclk or negedge rst_n) begin if(!rst_n) cnt <= 11'd0; else if(ken_enable == 1) begin if(cnt == DURATION) cnt <= cnt; else cnt <= cnt + 1'b1; end else cnt <= 16'b0; end always @(posedge mclk or negedge rst_n) begin if(!rst_n) key_en <= 4'd0; else if(key[0]) key_en[0] <= (cnt == DURATION-1'b1) ? 1'b1 : 1'b0; else if(key[1]) key_en[1] <= (cnt == DURATION-1'b1) ? 1'b1 : 1'b0; else if(key[2]) key_en[2] <= (cnt == DURATION-1'b1) ? 1'b1 : 1'b0; else if(key[3]) key_en[3] <= (cnt == DURATION-1'b1) ? 1'b1 : 1'b0; else key_en <= key_en; end endmodule
其实在写这个模块的时候,我采用了两种方式,对比了一下所占用的资源,这个相对而言跟节省资源些。
这是我上述代码说占用的资源:
下面这个是我在另外一份实现后的资源利用:
为何要比较呢,是由于我最近写一个模块时资源超了,真的就超了。。。
因此提醒你们学习入门初级阶段,就该由意识的节省资源,多用心,就有不同的收获。xml
PS:我开始开心一些了,因此你也要一直保持好心情。blog