打印
[verilog]

Verilog的按键消抖与松手检测如何做到,求给个思路

[复制链接]
3090|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
a2582006460|  楼主 | 2014-6-24 17:14 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
1.按键消抖 我在网上查了一下,已经用了了一种采用较低的频率对按键进行采用来消除抖动,不知还有没有别的什么方法
2求教一种解决松手检测的方案思路

相关帖子

沙发
pianran| | 2014-6-26 10:21 | 只看该作者
module remove
(
    input rst_n,
    input clk,//64KHz
    input in,
    output reg out
);
    parameter CNT_WITDH = 8;
    parameter THRESHOLD = 192;

    reg [CNT_WITDH:0] cnt;
    reg state;
            
    always @( posedge clk or negedge rst_n )
        if ( !rst_n )
        begin
            state <= 1'b0;
            cnt <= 0;
        end
        else
            case(state)
            1'b0:begin
                      if(in==0)
                      begin
                          state <= 1'b1;
                          cnt <= 0;
                      end
                      else
                      begin
                          state <= 1'b0;
                          if(cnt<THRESHOLD)cnt <= cnt+1;
                      end
                 end
            1'b1:begin
                      if(in==0)
                      begin
                          state <= 1'b1;
                          if(cnt<THRESHOLD) cnt <= cnt+1;
                      end
                      else
                      begin
                          state <= 1'b0;
                          cnt <= 0;
                      end
                  end
            endcase           

   always @( posedge clk or negedge rst_n )
      if ( !rst_n )
         out <= 1;
      else if (cnt==THRESHOLD-1)
         out <= in;
endmodule

使用特权

评论回复
板凳
pianran| | 2014-6-26 10:24 | 只看该作者
上面就是一个简单的去抖动程序。
时钟的频率和去除抖动的时间自己根据产品实际确定。
程序的思路简而言之,如果输入电平改变,就开始计数器计数,只有到达一定时间才认为是真正的变化,这时候输出才随之变化;否则就认为是抖动,输出保持不变。

使用特权

评论回复
地板
jomanliang| | 2014-6-26 11:19 | 只看该作者
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, RSTn, Pin_In, H2L_Sig, L2H_Sig
);

    input CLK;
         input RSTn;
         input Pin_In;
         output H2L_Sig;
         output L2H_Sig;
         
         /**********************************/
         
         parameter T100US = 11'd1999;
         
         /**********************************/
         
         reg [10:0]Count1;
         reg isEn;
         
         always @ ( posedge CLK or negedge RSTn )
             if( !RSTn )
                      begin
                          Count1 <= 11'd0;
                          isEn <= 1'b0;
                                end
             else if( Count1 == T100US )
                                isEn <= 1'b1;
                  else
                      Count1 <= Count1 + 1'b1;
                               
    /********************************************/
         
         reg H2L_F1;
         reg H2L_F2;
         reg L2H_F1;
         reg L2H_F2;
         
         always @ ( posedge CLK or negedge RSTn )
             if( !RSTn )
                      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
                               
    /***********************************/
         

         assign H2L_Sig = isEn ? ( H2L_F2 & !H2L_F1 ) : 1'b0;
         assign L2H_Sig = isEn ? ( !L2H_F2 & L2H_F1 ) : 1'b0;

         
         /***********************************/
         
endmodule

     
         
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

检测按键,延时消抖,程序思路跟C很像,容易理解
         

使用特权

评论回复
5
a2582006460|  楼主 | 2014-6-26 16:48 | 只看该作者
pianran 发表于 2014-6-26 10:24
上面就是一个简单的去抖动程序。
时钟的频率和去除抖动的时间自己根据产品实际确定。
程序的思路简而言之, ...

咱能说说思路吗?您这一堆代码一上来,让我很是头疼啊

使用特权

评论回复
6
a2582006460|  楼主 | 2014-6-26 16:59 | 只看该作者
本帖最后由 a2582006460 于 2014-6-26 17:05 编辑
pianran 发表于 2014-6-26 10:21
module remove
(
    input rst_n,

了解,就是连续检测192次都是低电平则是按下。消除抖动


一开始还没反应过来、。。。

使用特权

评论回复
7
a2582006460|  楼主 | 2014-6-26 17:09 | 只看该作者
jomanliang 发表于 2014-6-26 11:19
module debounce_module
(
    CLK, RSTn, Pin_In, Pin_Out

亲,您的代码可以再简单点吗?给个思路就行啊!这代码看的有点头疼,太多变量。
这好像也只是个消抖的程序吧?
我主要想了解一下怎么达到松手检测的目的。
也就是按下一次按键,只执行一次按键功能的目的。

使用特权

评论回复
8
pianran| | 2014-6-27 15:10 | 只看该作者
松手我那个程序里也有啊,既有从高到低,也有从低到高的检测。

使用特权

评论回复
9
jomanliang| | 2014-6-30 09:03 | 只看该作者
module detect_module 按下检测H2L_Sig,松手检测 L2H_Sig

使用特权

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

本版积分规则

28

主题

150

帖子

0

粉丝