三十而立学FPGA之按键消抖

1.简介

按键为何消抖,原因是当按键按下和松开时,由于弹片回弹抖动,而导致按键对应管脚误判为多次按下和松开。

从以下动图对比可以看出:

按键消抖.avi

2.原理

三十而立学FPGA之按键消抖_第1张图片

如图,我们认为的按键波形是理想的,然而其实正真的实际波形是每次按下和弹起都是由回弹的,如图实际波形其实也是理想化的,为了方便理解。

既然有回弹,那么怎么避免呢?一般采用方式为延时法。C语言最直接直接一个delay就完事了,简单粗暴。在FPGA里,使用延时+判断的方式,既延时完后再次判断是否已经稳定。

3.源代码

3.1状态机转移图

三十而立学FPGA之按键消抖_第2张图片

3.2实现
3.2.1延时模块
//计数延迟5ms
	always@(posedge clk or negedge rst_n)
	begin
		if(rst_n == 1'b0)	
			delay_cnt <= 20'd0;
		else if(cnt_start == 1'b1)
			delay_cnt <= delay_cnt + 20'd1;
		else
			delay_cnt <= 20'd0;
	end
	
	always@(posedge clk or negedge rst_n)
	begin
		if(rst_n == 1'b0)	
			cnt_finish <= 1'b0;
		else if(delay_cnt == 20'd499999)
			cnt_finish <= 1'b1;
		else
			cnt_finish <= 1'b0;
	end
3.2.2状态机实现
//FSM for the key
	always@(posedge clk or negedge rst_n)
	begin
		if(rst_n == 1'b0)
		begin
			state <= IDLE;
			cnt_start <= 1'b0;
			key_o_r <= 1'b1;
		end
		else 
			case(state)
				IDLE	:begin
					if(key_neg == 1'b1)
					begin
						cnt_start <= 1'b1;
						state <= FILTER0;
					end
					else
						state <= IDLE;
				end
				FILTER0	:begin
					if(cnt_finish == 1'b1)
					begin
						cnt_start <= 1'b0;
						key_o_r <= 1'b0;					
						state <= DOWN;
					end
					else if(key_pos == 1'b1)
					begin
						state <= IDLE;
						cnt_start <= 1'b0;						
					end
					else 
					begin
						state <=  FILTER0;
					end		
				end
				DOWN	:begin
					if(key_pos == 1'b1)
					begin
						state <= FILTER1;
						cnt_start <= 1'b1;
					end
					else 
					begin
						state <= DOWN;
					end
				end
				FILTER1	:begin
					if(cnt_finish == 1'b1)
					begin
						cnt_start <= 1'b0;
						state <= IDLE;
						key_o_r <= 1'b1;
					end
					else if(key_neg == 1'b1)
					begin
						state <= DOWN;
						cnt_start <= 1'b0;
					end
					else 
					begin
						state <=  FILTER1;
					end			
				end
				default	:begin
					state <= IDLE;
					key_o_r <= 1'b1;
					cnt_start <= 1'b0;
				end
			endcase
	end

你可能感兴趣的:(FPGA,fpga开发,按键消抖)