10_基于FPGA进行按键消抖

10_基于FPGA进行按键消抖    

实验原理

计数器型消抖电路:

计数器型消抖电路()

  计数器型消抖电路()是设置一个模值为(N+1)的控制计数器,clk在上升沿时,如果按键开关key_in='1',计数器加1key_in='0'时,计数器清零。当计数器值为2时,key_out输出才为1,其他值为0时。计数器值为N时处于保持状态。因此按键key_in持续时间大于Nclk时钟周期时,计数器输出一个单脉冲,否则没有脉冲输出。如果按键开关抖动产生的毛刺宽度小于N个时钟周期,因而毛刺作用不可能使计数器有输出,防抖动目的得以实现。clk的时钟周期与N的值可以根据按键抖动时间由设计者自行设定。

下图为N3的波形仿真图,当按键持续时间大于3个时钟周期,计数器输出一个单脉冲,其宽度为1个时钟周期,小于3个时钟周期的窄脉冲用作模拟抖动干扰,从图1可以看出,抖动不能干扰正常的单脉冲输出。

该方法的特点是能很好消除按键抖动产生的窄脉冲,还可以滤去干扰、噪音等其他尖峰波,但遇到脉宽大于NTclk时钟周期的干扰、噪音等时会有输出从而产生误操作,而对于按键操作要求按键时间必须大于NTclk时钟周期,否则按键操作也没有输出。

计数器型消抖电路()

  计数器型消抖电路()是控制计数器工作一个循环周期(N+1个状态),且仅在计数器为0时输出为"1"。电路设计了连锁控制设施。在计数器处于状态0时,此时若有按键操作,则计数器进入状态1,同时输出单脉冲(其宽度等于时钟周期)。计数器处于其他状态,都没有单脉冲输出。计数器处于状态N时,控制en='0',导致计数器退出状态N,进入状态0。计数器能否保持状态0,取决于人工按键操作,若按键key_in='1',控制en='1'(计数器能正常工作)key_in='0',计数器状态保持。显见计数器处于状态0,人工不按键,则计数器保持状态0

下图是N7的波形仿真图。在计数器状态为0时,key_in有按键操作,计数器开始连续计数直到计数器状态为0;计数器状态为1-7时,key_in任何操作对计数器工作无影响,计数器在状态为1时,输出一个单脉冲,脉冲宽度为1个时钟周期。

该设计方法的特点是能很好消除按键抖动产生的连续脉冲,对按键时间没有要求,缺点是在计数器状态为0时,遇到干扰、噪音等时会有输出,从而产生误操作。

状态机型消抖电路

状态机型消抖电路采用有限状态机的设计方法来描述与实现,状态机有S0S1S2三种状态,在S0状态下key_out输出为低电平,并以clk时钟信号的频率采样按键输入信号,如果key_in='0',则保持在S0状态,并继续采样按键输入信号的状态,如果key_in='1',则转入S1状态;在S1状态下key_out输出仍为低电平,继续采样按键输入信号的状态,如果key_in='1',则转入S2状态,如果key_in='0'则转入S0状态;在S2状态下继续采样按键输入信号的状态,如果key_in='1',则保持在S2状态,key_out输出正脉冲,如果key_in='0',则转入S0状态,key_out输出低电平。

下图为状态机型消抖电路波形仿真图

硬件原理图

实验代码

计数器型消抖电路()程序:

/********************************版权声明**************************************

** 大西瓜团队

**

**----------------------------文件信息--------------------------

** 文件名称: key.v

** 创建日期:

** 功能描述:按键控制led的亮灭

** 硬件平台:大西瓜第三代开发板,http://daxiguafpga.taobao.com

** 版权声明:本代码属个人知识产权,本代码仅供交流学习.

**---------------------------修改文件的相关信息----------------

** 修改人:

** 修改日期:    

** 修改内容:

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

module key(clk,key,led);

input clk,key;//按键与时钟输入

output led;

 

wire clk,key;

 

reg led;

reg [2:0] clk_counter;//时钟计数

reg [14:0] div_counter;//分频计数

reg key_out;

reg clk_div;

always @(posedge clk)

begin

if(div_counter==15'd25000)

begin

clk_div<=~clk_div;

div_counter<=15'd0;

end

else

div_counter<=div_counter+15'd1;

end

 

always @(posedge clk_div )

begin

if(key==1'b0)//判断按键是否按下

begin

if(clk_counter==3'b111)//计数到7

begin

clk_counter<=3'b000;

key_out<=1'b1;

end

else

             begin

                 clk_counter<=clk_counter+1'b1;

             if(clk_counter==3'b110)//判断是否计到6

                 key_out<=1'b0;

             else

                 key_out<=1'b1;

             end

end

else

clk_counter<=3'b000;

end

always @(negedge key_out)//对消抖后的按键信号进行判断

begin

if(!key_out)//判断按键是否按下

begin

led<=~led;//led灯状态反转

end

else

led<=led;

end

endmodule

 

状态机型消抖电路程序:

/********************************版权声明**************************************

** 大西瓜团队

**

**----------------------------文件信息--------------------------

** 文件名称: key.v

** 创建日期:

** 功能描述:按键控制led的亮灭

** 硬件平台:大西瓜第三代开发板,http://daxiguafpga.taobao.com

** 版权声明:本代码属个人知识产权,本代码仅供交流学习.

**---------------------------修改文件的相关信息----------------

** 修改人:

** 修改日期:    

** 修改内容:

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

module key(clk,led,key);

input clk,key;

output [7:0] led;

 

wire clk;

wire key;

 

reg [7:0] led_temp;

reg key_out;

parameter s0=2'b00,s1=2'b01,s2=2'b10,s3=2'b11;

reg [1:0] state;

 

always @(posedge clk)

begin

case (state)

s0:

begin

key_out<=1'b1;

     if(key==1'b0)

         state<=s1;

     else

     state<=s0;

     end

     s1:

     begin

     if(key==1'b0)

         state<=s2;

     else

     state<=s0;

     end

     s2:

     begin

     if(key==1'b0)

         state<=s3;

     else

     state<=s0;

     end

     s3:

     begin

     if(key==1'b0)

     begin

         key_out<=1'b0;

         state<=s3;

         end

        else

         begin

         key_out<=1'b1;

         state<=s0;

     end

     end

     default:

     state<=s0;

endcase

end

 

always @(negedge key_out)

begin

if(!key_out)//判断按键是否按下

begin

if(led_temp==8'b1111_1111)

led_temp<=8'b0;

else

led_temp<=led_temp+1'b1;

end

end

assign led=~led_temp;

endmodule

实验操作

实验效果

 

 

 

大西瓜FPGA-->https://daxiguafpga.taobao.com

配套开发板:https://item.taobao.com/item.htm?spm=a1z10.1-c.w4004-24211932856.3.489d7241aCjspB&id=633897209972

博客资料、代码、图片、文字等属大西瓜FPGA所有,切勿用于商业! 若引用资料、代码、图片、文字等等请注明出处,谢谢!

   

每日推送不同科技解读,原创深耕解读当下科技,敬请关注微信公众号"科乎"。

posted @ 2022-02-20 17:17  logic3  阅读(744)  评论(0编辑  收藏  举报