首页 > 其他分享 >FPGA按键消抖

FPGA按键消抖

时间:2023-07-29 11:36:14浏览次数:48  
标签:FPGA 消抖 sys key 按键 rst input

简介

按键

按键是输入设备,一般来说,按键在没有按下的时候是高电平;当按键按下的时候,为低电平。

DE2-70 User Manual

Each switch provides a high logic level (3.3 volts) when it is not pressed, and provides a low logic level (0 volts) when depressed. Since the pushbutton switches are debounced, they are appropriate for use as clock or reset inputs in a circuit.

这里介绍到了按键抖动(Button Bouncing)和按键消抖(Button Debouncing)。

按键消抖

按键消抖通常的按键所用开关为机械弹性开关,当机械触点断开、闭合时,由于机械触点的弹性作用,一个按键开关在闭合时不会马上稳定地接通,在断开时也不会一下子断开。因而在闭合及断开的瞬间均伴随有一连串的抖动,为了不产生这种现象而作的措施就是按键消抖。

上图描述的是硬件的按键消抖。可见,消抖后,一次按键,只产生了一次电平变化。

这对我们接下来利用按键意义重大。

物理消抖

简单介绍下实现上图的消抖。

电容滤波

将电容并联在按键的两端,利用电容的放电的延时特性。将产生抖动的电平通过电容吸收掉。从而达到消抖的作用。

RS触发器

利用RS触发器来吸收按键的抖动。一旦有键按下,触发器立即翻转,触电的抖动便不会再对输出产生影响。

程序消抖

按键在FPGA中必不可少,我们需要利用按键对一些变量进行累加或累减。比如频率、分数等。

未消抖

在一开始的学习中,我们可能只用到了开关(switch),编写开关控制的程序类似于将开关当作一个布尔(Boolean)变量。

但是按键与开关不同,以下面这段代码为例,期望作用是 按键按下后,LED灯状态改变

module Test(
    input       sys_clk,
    input       rst_n,
    input       key,
    output  reg led
);
    always@(posedge sys_clk or negedge rst_n)
    begin
        if(rst_n == 1'b0) 
            led <= 1'b0;
        else if(key == 1'b0)
            led <= ~led;
        else
            led <= led;
    end
endmodule

然而,上板测试发现,LED状态灯一直处于不亮的状态。

假设,我们的时钟频率是50MHz,那么它的周期就是20ns

那么,在你按按钮的全过程中,按下的状态持续了多长时间呢?

显然,远大于20ns,所以LED会多次取反。所以这种简单粗暴的方法是不适合按键的。

消抖

我们刚刚的问题是,短时间内重复检测,从而多次执行了按键后的行为。

可以想到,给这个按键定个时:当有按键按下,计数器不断自增,若因为抖动,则计数器会清空,重新计数,当不抖动的时候,就会计满,此时才会判定为按键按下。

代码

// 定时器消除抖动
module key_filter(
    input	wire            sys_clk,          // 50M时钟
    input   wire         	sys_rst_n,        // 复位信号,低电平有效
    input   wire      		key,              // 按键输入

    output 	reg       		key_flag,         // 按键信号有效信号
	output 	reg       		key_value         // 消抖后的按键信号  
   );
 
    reg [31:0] delay_cnt;	// 32位定时器
	reg        key_reg; 

always @(posedge sys_clk or negedge sys_rst_n) begin 
    if (!sys_rst_n) begin 
        key_reg   <= 1'b1;
        delay_cnt <= 32'd0;
    end
    else begin
        key_reg <= key;
        if(key_reg != key)             // 检测到按键状态发生变化(按下 或 释放)
            delay_cnt <= 32'd1000000;  // 计数器装载初始值(计数时间为20ms)
        else if(key_reg == key) begin  // 按键状态稳定时,计数器递减,开始20ms倒计时
            if(delay_cnt > 32'd0) 	   // 不稳定时,重新计时
                     delay_cnt <= delay_cnt - 1'b1;
                 else
                     delay_cnt <= delay_cnt;
             end           
    end   
end

always @(posedge sys_clk or negedge sys_rst_n) begin 
    if (!sys_rst_n) begin 			   // 复位
        key_flag  <= 1'b0;			   // 无效
        key_value <= 1'b1;             // 高电平为未按下
    end
    else begin
        if(delay_cnt == 32'd1) begin   // 按键稳定状态维持了20ms
            key_flag  <= 1'b1;         // 此时消抖过程结束,信号有效
            key_value <= key;          // 保存此时按键信号
        end							   
        else begin
            key_flag  <= 1'b0;
            key_value <= key_value; 
        end  
    end   
end
    
endmodule 

如此,我们再重新写下刚刚的未消抖程序。

module Test(
      input   	    	sys_clk,     // 系统时钟
      input   	    	rst_n,       // 复位信号,低电平有效
      input       	    key,	     // 按键信号       
	  output    reg     led			 // LED灯
  );
  
wire key_value;
wire key_flag;
// 例化
key_filter	key_filter_inst(
    .sys_clk		(sys_clk),     // 50M时钟
    .sys_rst_n		(sys_rst_n),   // 复位信号,低电平有效
    .key            (key),         // 按键输入)

    .key_flag		(key_flag),    // 按键信号有效信号
    .key_value      (key_value)    // 按键消抖后的数据  
);
always @ (posedge sys_clk or negedge sys_rst_n) begin
    if(!sys_rst_n)	
	begin
		led <= 1'b0;
	end
    else if(key_flag && (~key_value))  // 按键是否有效按下
	begin						
		 led  <= ~led;
	end
    else
    begin
        led <= led;
    end
end
endmodule 

成功,按键可以控制LED灯亮与熄灭。仿真略。

这是简单的计时消抖,读者有兴趣可阅读学习状态机的方法

参考文献

[1] 按键的硬件消抖电路原理详解

[2] FPGA要按键实现四个数码管加减计数怎么搞?

[3] FPGA学习—按键控制

[4] DE2-70 User Manual

标签:FPGA,消抖,sys,key,按键,rst,input
From: https://www.cnblogs.com/Az1r/p/17589520.html

相关文章

  • m基于FPGA的256点FFT傅里叶变换verilog实现,含testbench,不使用IP核
    1.算法仿真效果本系统进行了Vivado2019.2平台的开发,其中Vivado2019.2仿真结果如下:2.算法涉及理论知识概要傅里叶变换(FourierTransform)是一种重要的信号处理技术,用于将一个时域信号转换为频域表示,分析信号的频率成分。FFT(FastFourierTransform)是一种高效的傅里叶变换算法,可以......
  • m基于FPGA的256点FFT傅里叶变换verilog实现,含testbench,不使用IP核
    1.算法仿真效果 本系统进行了Vivado2019.2平台的开发,其中Vivado2019.2仿真结果如下:      2.算法涉及理论知识概要       傅里叶变换(FourierTransform)是一种重要的信号处理技术,用于将一个时域信号转换为频域表示,分析信号的频率成分。FFT(FastFourierT......
  • FPGA vivado quartus 设置外挂 编辑器
     1.vivado   tools->settings->editor ->customeditor... C:\\pg\\MicrosoftVSCodeInsiders\\Code-Insiders.exe[filename]  2.quartus tools->options->preferredtexteditortexteditor:custom command-line:"C:\pg\M......
  • Android shell模拟物理按键
    Androidshell模拟物理按键在Android开发中,有时候我们需要模拟物理按键的操作,例如模拟点击返回键、Home键等。Android提供了一个能够在命令行中模拟按键操作的工具——input。input命令简介input命令是Android系统中的一个工具,用于模拟按键事件。通过使用不同的参数,我们可以模拟......
  • 防干扰/抗电压波动单按键/1路触摸触控芯片VK36N1D SOT23-6 适用于厨房秤/温控器/加湿
    触摸芯片是一种可感应人体触摸的微处理器,其工作原理是通过感应人体触摸带来的电容变化而实现的;当人体接近触摸屏幕表面时,会引起触摸屏与人体间的电容改变,并且形成了一个新的电场分布,芯片会根据这个电容改变来计算出具体的触摸位置和操作手势。目前触摸芯片应用涉及于消费类电子、......
  • 按键消抖电路如何实现?
    请设计一个按键消抖电路?按键消抖:按键消抖_百度百科(baidu.com)modulekey_debounce(inputsys_clk,//20nsinputsys_rst_n,inputkey,//outputregkey_flag,//正点原子中将表示信号作为一路输出信号使......
  • FPGA移位加三法
    介绍BCD码BCD码的英文全称是Binary-CodedDecimal‎,简称BCD,按字面解释是二进制十进制代码,是一种二进制的数字编码形式。常见的BCD码有8421BCD码,2421BCD码,5421BCD码,余3码以及格雷码等等。在本文中,我们所采用的BCD码为8421BCD码。8421码,即从左到右的二进制位权重分别为8、4、2......
  • m基于FPGA的16QAM软解调verilog实现,含testbench
    1.算法仿真效果 本系统进行了两个平台的开发,分别是: Vivado2019.2 Quartusii18.0+ModelSim-Altera6.6d StarterEdition 其中Vivado2019.2仿真结果如下:     Quartusii18.0+ModelSim-Altera6.6d StarterEdition的测试结果如下:   2.算法涉及......
  • 永嘉微电/VINKA:电容式超强抗干扰 1按键/单通道/单键触摸触控芯片VK36N1D SOT23-6,该芯
    概述.VK36N1D具有1个触摸按键,可用来检测外部触摸按键上人手的触摸动作。该芯片具有较高的集成度,仅需极少的外部组件便可实现触摸按键的检测。提供了1个1对1输出脚,可通过IO脚选择上电输出电平,有直接输出和锁存输出2个型号可选。芯片内部采用特殊的集成电路,具有高电源电压抑制比......
  • 5模型机整体的联调【FPGA模型机课程设计】
    5模型机整体的联调【FPGA模型机课程设计】前言推荐5模型机整体的联调安排MIPS基本整数指令集MIPS扩展整数指令集测试与结果1FPGA模型计算机整体方案设计掌握MIPS指令集的相关设计2模型计算机各功能电路设计初始化数据I型指令测试R型指令测试J型指令测试访存指令测试3模型机指令......