按键检测消抖程序"/>
FPGA实现按键检测消抖程序
这个是黑金的板子提供的原版按键消抖程序
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2020/02/29 10:59:33
// Design Name:
// Module Name: key_detected
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//module key_detected#
( parameter FREQ = 50, //model clock :Mhzparameter MAX_TIME = 20 //ms
)(input clk, input rstn, input button_in,output reg button_posedge,output reg button_negedge
);
---------------- internal constants --------------
localparam N = 32 ; // debounce timer bitwidthlocalparam TIMER_MAX_VAL = MAX_TIME * 1000 * FREQ;
---------------- internal variables ---------------
reg [N-1 : 0] q_reg; // timing regs
reg [N-1 : 0] q_next;
reg DFF1, DFF2; // input flip-flops
wire q_add; // control flags
wire q_reset;
reg button_out_d0;
reg button_out;
------------------------------------------------------contenious assignment for counter control
assign q_reset = (DFF1 ^ DFF2); // xor input flip flops to look for level chage to reset counter
assign q_add = ~(q_reg == TIMER_MAX_VAL); // add to counter when q_reg msb is equal to 0 combo counter to manage q_next
always @ ( q_reset, q_add, q_reg)
begincase( {q_reset , q_add})2'b00 :q_next <= q_reg;2'b01 :q_next <= q_reg + 1;default :q_next <= { N {1'b0} };endcase
end Flip flop inputs and q_reg update
always @ ( posedge clk or negedge rstn)
beginif(!rstn)beginDFF1 <= 1'b0;DFF2 <= 1'b0;q_reg <= { N {1'b0} };endelsebeginDFF1 <= button_in;DFF2 <= DFF1;q_reg <= q_next;end
end counter control
always @ ( posedge clk or negedge rstn)
beginif(!rstn)button_out <= 1'b1;else if(q_reg == TIMER_MAX_VAL)button_out <= DFF2;elsebutton_out <= button_out;
endalways @ ( posedge clk or negedge rstn)
beginif(!rstn)beginbutton_out_d0 <= 1'b1;button_posedge <= 1'b0;button_negedge <= 1'b0;endelsebeginbutton_out_d0 <= button_out;button_posedge <= ~button_out_d0 & button_out;button_negedge <= button_out_d0 & ~button_out;end
end
endmodule
然后自己写了一个key检测的程序
`timescale 1ns / 1psmodule keyscan#
( parameter FREQ = 50, //model clock :Mhzparameter MAX_TIME = 20, //msparameter key_init_voltag=1'b1
)(input clk,input rstn,input key_in,output key_posedge,output key_negedge);
localparam Cnt_bit=32;
localparam TIMER_MAX_VAL = MAX_TIME * 1000 * FREQ;
//---------------------------------------------
reg [Cnt_bit-1:0] Count;
wire Cnt_Clear;
//---------------------------------------------
reg Detect1,Detect2;
assign Cnt_Clear=(Detect1^Detect2);
always@(posedge clk or negedge rstn)if(!rstn)beginDetect1<=1'b0;Detect2<=1'b0; endelse beginDetect1<=key_in; Detect2<=Detect1;end
//---------------------------------------------
always@(posedge clk or negedge rstn)if(!rstn)beginCount<=32'd0; endelse if(Cnt_Clear)Count<=32'd0;else if(Count==TIMER_MAX_VAL)Count<=32'd0;else Count<=Count+1'd1;
//----------------------------------------------
reg sample_voltag;
always@(posedge clk or negedge rstn)if(!rstn)sample_voltag<=key_init_voltag;else if(Count==TIMER_MAX_VAL)sample_voltag<=key_in;elsesample_voltag<=key_init_voltag;//------------------------------------------------
reg Delay1_sample;
reg Delay2_sample;
always@(posedge clk)beginDelay1_sample<=sample_voltag;Delay2_sample<=Delay1_sample;
end
assign key_posedge=(~Delay1_sample&Delay2_sample);
assign key_negedge=(Delay1_sample&~Delay2_sample);
endmodule
大致讲解一下思路:
传统的软件消抖的思路是等待电平稳定后采样,来确定按键是否按下。
我们认为一般抖动一般时间10-20ms范围内。
1.首先我们需要计数器来计时,这个计数器在检测到电平变化时候就清零,否则就一直计数。
2.当计数到20ms时候采样输入的按键电平,当检测到电平变低后,则说明按键被拉低,当依然是高电平,这说明按键还是没有按下。
3.检测采样的电平上升沿,下降沿即可输出检测到按下按键的电平。
更多推荐
FPGA实现按键检测消抖程序
发布评论