打印

新手疑问:三种键盘消抖比较!!!

[复制链接]
2002|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
yqyq31601099|  楼主 | 2011-10-13 20:11 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
学习fpga一个月了,一个月中断断续续的看书弄实验箱,中间因实验箱的芯片有点老,资料少,又买了黑金的开发板,这两天才开始系统的学习,看到黑金配套的verilog那些事 中消抖的那块,突然想起以前看特权的视频中的消抖和实验箱配套的周立功出版的书上的消抖模块,现在列出下面三种消抖的代码请教这三种的哪种最实用,各自的思想好处,或者有其他更好更实用的消抖方法么?以后用到消抖该采用哪种呢??
特权同学
module sw_debounce(
      clk,rst_n,
   sw1_n,sw2_n,sw3_n,
      led_d1,led_d2,led_d3
      );
input   clk; //Ö÷ʱÖÓÐźţ¬50MHz
input   rst_n; //¸´Î»Ðźţ¬µÍÓÐЧ
input   sw1_n,sw2_n,sw3_n;  //Èý¸ö¶ÀÁ¢°´¼ü£¬µÍ±íʾ°´ÏÂ
output  led_d1,led_d2,led_d3; //·¢¹â¶þ¼«¹Ü£¬·Ö±ðÓÉ°´¼ü¿ØÖÆ
//---------------------------------------------------------------------------
reg[2:0] key_rst;  
always @(posedge clk  or negedge rst_n)
    if (!rst_n) key_rst <= 3'b111;
    else key_rst <= {sw3_n,sw2_n,sw1_n};
reg[2:0] key_rst_r;       //ÿ¸öʱÖÓÖÜÆÚµÄÉÏÉýÑؽ«low_swÐźÅËø´æµ½low_sw_rÖÐ
always @ ( posedge clk  or negedge rst_n )
    if (!rst_n) key_rst_r <= 3'b111;
    else key_rst_r <= key_rst;
   
//µ±¼Ä´æÆ÷key_rstÓÉ1±äΪ0ʱ£¬led_anµÄÖµ±äΪ¸ß£¬Î¬³ÖÒ»¸öʱÖÓÖÜÆÚ
wire[2:0] key_an = key_rst_r & ( ~key_rst);
//---------------------------------------------------------------------------
reg[19:0]  cnt; //¼ÆÊý¼Ä´æÆ÷
always @ (posedge clk  or negedge rst_n)
    if (!rst_n) cnt <= 20'd0; //Òì²½¸´Î»
else if(key_an) cnt <=20'd0;
    else cnt <= cnt + 1'b1;
  
reg[2:0] low_sw;
always @(posedge clk  or negedge rst_n)
    if (!rst_n) low_sw <= 3'b111;
    else if (cnt == 20'hfffff)  //Âú20ms£¬½«°´¼üÖµËø´æµ½¼Ä´æÆ÷low_swÖР cnt == 20'hfffff
      low_sw <= {sw3_n,sw2_n,sw1_n};
      
//---------------------------------------------------------------------------
reg  [2:0] low_sw_r;       //ÿ¸öʱÖÓÖÜÆÚµÄÉÏÉýÑؽ«low_swÐźÅËø´æµ½low_sw_rÖÐ
always @ ( posedge clk  or negedge rst_n )
    if (!rst_n) low_sw_r <= 3'b111;
    else low_sw_r <= low_sw;
   
//µ±¼Ä´æÆ÷low_swÓÉ1±äΪ0ʱ£¬led_ctrlµÄÖµ±äΪ¸ß£¬Î¬³ÖÒ»¸öʱÖÓÖÜÆÚ
wire[2:0] led_ctrl = low_sw_r[2:0] & ( ~low_sw[2:0]);
reg d1;
reg d2;
reg d3;
  
always @ (posedge clk or negedge rst_n)
    if (!rst_n) begin
        d1 <= 1'b0;
        d2 <= 1'b0;
        d3 <= 1'b0;
      end
    else begin  //ij¸ö°´¼üÖµ±ä»¯Ê±£¬LED½«×öÁÁÃð· ת
        if ( led_ctrl[0] ) d1 <= ~d1;
        if ( led_ctrl[1] ) d2 <= ~d2;
        if ( led_ctrl[2] ) d3 <= ~d3;
      end
assign led_d3 = d1 ? 1'b1 : 1'b0;  //LED· תÊä³ö
assign led_d2 = d2 ? 1'b1 : 1'b0;
assign led_d1 = d3 ? 1'b1 : 1'b0;
  
endmodule
周立功配套实验书
module debounce(clk,key_in,key_out);  //按键消抖模块
input clk;         //系统时钟输入
input[KEY_WIDTH-1:0] key_in;    //外部按键输入
output[KEY_WIDTH-1:0]key_out;    //按键消抖输出
reg[KEY_WIDTH-1:0]dout1,dout2,dout3;  //寄存器  
parameter KEY_WIDTH = 8;     //参数
assign key_out = (dout1 | dout2 | dout3); //按键消抖输出
always @(posedge clk)
begin
dout1 <= key_in;
dout2 <= dout1;
dout3 <= dout2;
end
endmodule
黑金配套资料
分三个部分
顶层文件
module debounce_module
(
    CLK, RSTn, Pin_In, Pin_Out
);
   
  input CLK;
  input RSTn;
  input Pin_In;
  output Pin_Out;
  
  /**************************/
  
  wire H2L_Sig;
  wire L2H_Sig;
  
  detect_module U1
  (
      .CLK( CLK ),
    .RSTn( RSTn ),
    .Pin_In( Pin_In ),   // input - from top
    .H2L_Sig( H2L_Sig ), // output - to U2
    .L2H_Sig( L2H_Sig )  // output - to U2
  );
  
  /**************************/
  
  delay_module U2
  (
      .CLK( CLK ),
    .RSTn( RSTn ),
    .H2L_Sig( H2L_Sig ), // input - from U1
    .L2H_Sig( L2H_Sig ), // input - from U1
    .Pin_Out( Pin_Out )  // output - to top
  );
  
  /*******************************/
endmodule
电平检测模块
module detect_module(clk,rst,pin_in,h2l_sig,l2h_sig);
input clk;
input rst;
input pin_in;
output h2l_sig;
output l2h_sig;
parameter T100US=11'd1999;
reg[10:0]cnt;
reg isen;
[email=always@(posedge]always@(posedge[/email] clk or negedge rst)
begin
if(!rst)
    begin
       cnt<=11'd0;
       isen<=1'b0;
    end
else if(cnt==T100US)
    isen<=1'b1;
else
    cnt<=cnt+1;
end   
reg h2l_f1;
reg h2l_f2;
reg l2h_f1;
reg l2h_f2;
always @(posedge clk or negedge rst)
begin
if(!rst)
    begin
       h2l_f1<=1'b1;
       h2l_f2<=1'b1;
       l2h_f1<=1'b0;
       l2h_f2<=1'b0;
    end
else
    begin
       h2l_f1<=pin_in;
       h2l_f2<=h2l_f1;
       l2h_f1<=pin_in;
       l2h_f2<=l2h_f1;
    end   
end
assign h2l_sig = isen ? ( h2l_f2 & !h2l_f1 ) : 1'b0;
assign l2h_sig = isen ? ( !l2h_f2 & l2h_f1 ) : 1'b0;
endmodule
10ms延迟模块
module delay_module
(
    CLK, RSTn, H2L_Sig, L2H_Sig, Pin_Out
);
    input CLK;
  input RSTn;
  input H2L_Sig;
  input L2H_Sig;
  output Pin_Out;
  
  /****************************************/
  
  parameter T1MS = 16'd19_999;
  
  /***************************************/
  
  reg [15:0]Count1;
  always @ ( posedge CLK or negedge RSTn )
      if( !RSTn )
        Count1 <= 16'd0;
    else if( isCount && Count1 == T1MS )
        Count1 <= 16'd0;
    else if( isCount )
        Count1 <= Count1 + 1'b1;
    else if( !isCount )
        Count1 <= 16'd0;

    /****************************************/
   
    reg [3:0]Count_MS;
     
  always @ ( posedge CLK or negedge RSTn )
        if( !RSTn )
        Count_MS <= 4'd0;
    else if( isCount && Count1 == T1MS )
        Count_MS <= Count_MS + 1'b1;
    else if( !isCount )
        Count_MS <= 4'd0;

/******************************************/

reg isCount;
reg rPin_Out;
reg [1:0]i;

always @ ( posedge CLK or negedge RSTn )
     if( !RSTn )
       begin
           isCount <= 1'b0;
     rPin_Out <= 1'b0;
     i <= 2'd0;
     end
   else
        case ( i )
   
        2'd0 :
      if( H2L_Sig ) i <= 2'd1;
      else if( L2H_Sig ) i <= 2'd2;
     
        2'd1 :
      if( Count_MS == 4'd10 ) begin isCount <= 1'b0; rPin_Out <= 1'b1; i <= 2'd0; end
        else isCount <= 1'b1;
      
      2'd2 :
      if( Count_MS == 4'd10 ) begin isCount <= 1'b0; rPin_Out <= 1'b0; i <= 2'd0; end
        else isCount <= 1'b1;
        
   
    endcase
   
    /********************************************/
  
  assign Pin_Out = rPin_Out;
  
  /********************************************/
        

endmodule
  我知道特权和黑金的代码是软件仿真就是10ms检测,而周立功的是硬件消抖,建立DFF来消抖,你们这三种方法那个最好呢?

相关帖子

沙发
yxftr2010| | 2011-10-17 11:05 | 只看该作者
这代码写的这么不规范,J B开发板害人不浅!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

143

帖子

1

粉丝