实验六 按键防抖动实验

实验原理

若要使用开发板上面的四个SW按键来做计数输入,就需要知道一共按了几下按键。
在这种情况下不能像以前设计电路中,简单地使用输入时钟的上升沿来检测按键是否按
下。因为,如果分频以后的时钟频率是10Hz,按键一下按了1 秒钟,那么如果简单地
以时钟的上升沿来检测按键,程序就会认为实际一共按了十下按键。
我们经常使用的键盘也存在这种情况,这里就需要一部分电路来防止上面情况的出
现。
如果要防抖动,就不能用时钟去检测按键的按下状态,而要去检测按键按下或者抬
起的边沿。例如按键按下的时候就检测与按键连接的FPGA 管脚的下降沿,按键松开
的时候就检测与按键连接的FPGA 管脚的上升沿。这样就可以不用理会按键按下的时
间长度,根据按键按下或者抬起的次数来评定计数。

实验内容

本次实验设计一个防抖动电路,用来检测按键的输入。设置一个计数器,初始数值
为零。用防抖动检测电路来检测SW按键的输入,每检测到一次按键的按下或者抬起,
计数器的数值加一。在数码管显示计数器的数值。

module seg(clk,rst_n,data_in,data_out,data_en);
	input          clk,rst_n                 ;
	input  [3 :0 ] data_in                   ;
	
	output [7 :0 ] data_out                  ;
	output [3 :0 ] data_en                   ;
	
	reg    [7 :0 ] data_out                  ;
	
assign data_en = 4'b1111                   ;

always @ ( posedge clk or negedge rst_n )
	if( !rst_n )
		data_out <= 8'b0000_0000 ;
	else
		begin
			case( data_in )
				4'b0000: data_out <= 8'b1111_1100 ;
				4'b0000: data_out <= 8'b0110_0000 ;
				4'b0000: data_out <= 8'b1101_1010 ;
				4'b0000: data_out <= 8'b1111_0010 ;
				4'b0000: data_out <= 8'b0110_0110 ;
				4'b0000: data_out <= 8'b1011_0110 ;
				4'b0000: data_out <= 8'b1011_1110 ;
				4'b0000: data_out <= 8'b1110_0000 ;
				4'b0000: data_out <= 8'b1111_1110 ;
				4'b0000: data_out <= 8'b1111_0110 ;
			endcase
		end	
endmodule  

 

module counter(
			clk,
			rst_n,
			data_in,
			data_out
			);
	input           clk,rst_n           ;
	input           data_in             ;
	
	output [3 :0 ]  data_out            ;
	
	reg    [3 :0 ]  data_out            ;
	
always @ ( posedge clk or negedge rst_n )
	if( !rst_n )
		data_out <= 4'b0000 ;
	else
		begin
			if( 1'b1 == data_in )
				begin
					if( 4'b1001 <= data_out )
						data_out <= 4'b0000 ;
					else
						data_out <= data_out + 4'b0001 ;
				end
			else
				data_out <= data_out ;
		end
		
endmodule

 

module debounce(
    clk,
    rst_n,
    key_i,
    key_o
    );

input   clk;
input   rst_n;
input   key_i;
output  key_o;

reg   key_o;

wire   key;
wire   clk_slow;    
    //分频电路
reg [22:0]  cnt;
reg [25:0]  cnt_out;
wire     key_o_reg ;
always @ ( posedge clk or negedge rst_n )
  if ( !rst_n ) 
   	cnt <= 23'd0;
  else 
  	cnt <= cnt + 1'b1;
  	
assign  clk_slow = cnt[22];
    
    //防反跳电路       
reg    temp_r  [2:0];
reg    key_r;
integer     i;
always @ ( posedge clk_slow or negedge rst_n )
  if ( !rst_n ) 
  	begin
  	 	for ( i = 0 ; i < 3; i = i+ 1)
        temp_r[i] <= 'd0;
    end
  else 
  	begin
      temp_r[0] <= key_i;
      temp_r[1] <= temp_r[0];
      temp_r[2] <= temp_r[1]; 
    end

assign key = (~temp_r[0]) & temp_r[1] & temp_r[2];
 
always @ ( posedge clk or negedge rst_n )
  if ( !rst_n ) 
    key_r <= 1'b0;
  else 
  	key_r <= key;

assign key_o_reg = key & (~key_r);   
/*
always @ ( posedge clk or negedge rst_n )
	if( !rst_n )
		key_o <= 1'b0 ;
	else
		begin
			if( cnt_out<='d33554432 )
				begin
					if( cnt_out=='d0 )
						begin
							if( key_o_reg )
								begin
									cnt_out <= 'd1 ;
									key_o <= 1'b1 ;
								end
							else
								begin
									cnt_out <= 'd0 ;
									key_o <= 1'b0 ;
								end
						end
					else
						cnt_out <= cnt_out + 'd1 ;
				end
			else
				cnt_out <= 'd0 ;
		end						      
*/
endmodule

 

module top_new(clk, 
           key_i, 
           rst_n, 
           data, 
           en);

    input clk;
    input key_i;
    input rst_n;
   output [7:0] data;
   output [3:0] en;
   
   wire [3:0] XLXN_1;
   wire XLXN_3;
   
   counter XLXI_1 (.clk(clk), 
                   .data_in(XLXN_3), 
                   .rst_n(rst_n), 
                   .data_out(XLXN_1[3:0]));
   debounce XLXI_2 (.clk(clk), 
                    .key_i(key_i), 
                    .rst_n(rst_n), 
                    .key_o(XLXN_3));
   seg XLXI_3 (.clk(clk), 
               .data_in(XLXN_1[3:0]), 
               .rst_n(rst_n), 
               .data_en(en[3:0]), 
               .data_out(data[7:0]));

endmodule

 

你可能感兴趣的:(实验六 按键防抖动实验)