硬件消抖
友晶科技很多板子的按键其实是已经有硬件消抖电路的, 这样的板子的按键的值 直接input 进来后 直接用就可以。
比如DE2-115 DE1-SOC DE10-Standard 等等。这里用74HC245芯片来消抖:
软件消抖
如果没有硬件上的消抖,我们可以手写Verilog代码替代消抖电路。
软件消抖的原理主要为按键按下或松开后延时 5ms—20ms 采样。
按键去抖的思路是检测到按下时延时 20ms,再检测,如果状态仍为按下,则确认是按下的;如果状态为弹起的,则确认是干扰,无按键按下。
模板1:
module key //按键消抖模块 ( input clk, //系统时钟 input rst_n, //系统复位 input key[0], //按键输入 output reg key_value, //有效的按键值 ); reg [31:0]cnt;//计数器 reg value;//中间寄存器 always@(posedge clk or negedge rst_n) begin if(!rst_n) begin cnt <= 0; //初始状态下寄存器清零 key_value <= 0; //有效按键值清零 value <= 0; //中间寄存器清零 end else begin if(cnt == 50000) begin cnt <= 0;//每隔0.001秒检测一次 将key的值寄存到value寄存器当中(如果系统时钟是50MHz) value <= key[0]; if(value == 1 && key[0] == 0) //按键按下为0,平时为1 key_value <= 1; end else begin cnt <= cnt + 1; key_value <= 0; end end end endmodule
第二个按键消抖模板:
//按键平时为0,按下为1 module Key( input clk,//系统时钟 input rst_n,//系统复位 input key[0],//按键输入 output reg key_value//有效的按键值输出 ); reg [31:0] cnt;//计数器 reg cnt_en; reg value;//中间寄存器 parameter interval=1_000_000;//计数器的最大值 代表0.02秒 如果系统时钟的50MHz always @(posedge clk or negedge rst_n) begin if (~rst_n) value<=1'b0;//复位的时候中间寄存器清零 else if (cnt==interval-1) //每次按键的值和中间寄存器的值不一样并保持了0.02秒时,将key[0]的值赋值给中间寄存器 value<=key[0]; end always @(posedge clk or negedge rst_n) begin if (~rst_n) key_value<=1'b0;//复位的时候有效的按键值输出寄存器清零 else if (cnt==interval-1 && key[0]) key_calue<=1'b1; else if (key_value) key_value<=1'b0; end always @(posedge clk or negedge rst_n) begin if (~rst_n) cnt_en<=1'b0; else if (key[0] != value) //当中间寄存器的值和当前keu[0]的值不同的时候 计数器自增1 cnt_en<=1'b1; else cnt_en<=1'b0; end always @(posedge clk or negedge rst_n) begin if (~rst_n) cnt<=32'b0;//复位的时候计数器清零 else if (cnt_en) cnt<=cnt+32'b1; else cnt<=32'b0; end endmodule
无