FPGA-独立按键的消抖(软件消抖未用状态机)

简介: FPGA-独立按键的消抖(软件消抖未用状态机)

独立按键消抖在单片机和FPGA中都是个不可避免的问题,首先,解释一下什么叫做按键抖动,如图,按键在按下和松开的那个瞬间存在大概20ms的机械抖动:

下面就是本篇的第一个重点 —— 什么时候需要按键消抖设计?如果是像复位按键这样,短时间内可以多次触发,就完全不需要设计消抖,但是如果是要设计按下按键使LED状态翻转,或者按下按键计数一次的话,就必须要设计消抖模块,否则就会带来不可预知的错误,因为在按下按键的那个时刻,可能已经触发了少则几次,多则几十次,可见按键消抖的必要性;

 那么,既然按键消抖如此重要,如何来进行消抖呢?

 1、硬件消抖 —— 0.1uF电容滤波

    这个104的电容就是起高频滤波的作用,在按键不是很多的情况下,可以使用这种设计,但是如果要做项目,会增加大量成本,所以接下来我们讲述如何进行软件消抖;

  2、软件消抖 —— delay

if(key_in==0)
{
deley(2000);
if(key_in==0)
    {
//按键按下,执行相应操作      }   
}

在单片机中用C语言,可以这样设计按键消抖,同样的思路,在FPGA中,我们依然可以采用这种思想,将按键的这20ms抖动“屏蔽”,但是FPGA没有delay(2000),该如何设计呢?

FPGA中控制延时可以采用计数器,因为工作时钟是已知的50M,所以要延时20_000_000ns(20ms),只需要对计数1_000_000个clk就可以,这样延时问题就解决了,按照之前的思路,设计如下:只需要在检测到key_in变为0,启动定时器,定时器时间到,再次检测key_in是否为0,若为0,表明按键按下稳定,关闭计数器并清零,然后等待按键释放,也就是key_in出现上升沿,再次启动定时器,时间到后检测key_in,若为1,则证明按键已释放,一次完整的按键过程结束。

modulekeys(ext_clk_25m,ext_rst_n,led,key_left,key_righ,key_upup,key_down,key_entr    );
inputext_clk_25m;
inputext_rst_n;
inputkey_down,key_entr,key_left,key_righ,key_upup;
outputreg [7:0]led;

抖动判断逻辑

这里用4位是为了和采样频率和基准时钟一致

//按键抖动判断逻辑wirekey;  //所有的按键相与的结果,用于按键触发判断reg[3:0]keyr ; //按键值key的缓冲寄存器assignkey=key_down&key_entr&key_left&key_righ&key_upup;
always@(posedgeext_clk_25mornegedgeext_rst_n)
beginif(!ext_rst_n)
keyr<=4'b1111;elsekeyr<={keyr[2:0],key};
endwirekey_neg=~keyr[2] &keyr [3];//有按键被按下wirekey_pos=keyr[2] &~keyr [3];// 有按键被释放

设置一个计数器定时20ms(这里是40ms)

//定时器计数逻辑,用于对按键的消抖的判断reg [19:0] cnt;
always@(posedgeext_clk_25mornegedgeext_rst_n)
beginif(!ext_rst_n)
cnt<=20'd0;elseif(key_pos||key_neg)
cnt<=20'd0;elseif(cnt<20'd999_999)cnt<=cnt+1'b1;elsecnt<=20'd0;end

采集按键值

//定时采取按键值always@(posedgeext_clk_25mornegedgeext_rst_n)
beginif(!ext_rst_n)
beginkey_value[0] <=5'b11111;key_value[1] <=5'b11111;endelsebeginkey_value[1] <=key_value[0];
if(cnt==20'd999_999)key_value[0] <={key_left,key_righ,key_upup,key_down,key_entr};
else ;
endendwire [4:0]key_press=key_value[1] &~key_value[0];

控制LED

//LED切换控制always@(posedgeext_clk_25mornegedgeext_rst_n)
beginif(!ext_rst_n)
led<=8'hff;elseif(key_press[0])
led[0] <=~led[0];
elseif(key_press[1])
led[1] <=~led[1];
elseif(key_press[2])
led[2] <=~led[2];
elseif(key_press[3])
led[3] <=~led[3];
elseif(key_press[4])
led[4] <=~led[4];
else ;
endendmodule
目录
相关文章
|
异构计算
FPGA新起点V1开发板(十)——按键控制LED
FPGA新起点V1开发板(十)——按键控制LED
382 3
FPGA新起点V1开发板(十)——按键控制LED
|
异构计算
FPGA新起点V1开发板(八-语法篇)——状态机
FPGA新起点V1开发板(八-语法篇)——状态机
393 3
|
异构计算
|
异构计算
FPGA新起点V1开发板(五)——Modelsim软件的使用(联合仿真
FPGA新起点V1开发板(五)——Modelsim软件的使用(联合仿真
431 0
FPGA新起点V1开发板(五)——Modelsim软件的使用(联合仿真
|
异构计算 内存技术
FPGA新起点V1开发板(三)——Quartus II软件的使用(流水灯的烧录以及sof转jic的方法记录)(下)
FPGA新起点V1开发板(三)——Quartus II软件的使用(流水灯的烧录以及sof转jic的方法记录)(下)
820 0
FPGA新起点V1开发板(三)——Quartus II软件的使用(流水灯的烧录以及sof转jic的方法记录)(下)
|
异构计算
FPGA新起点V1开发板(三)——Quartus II软件的使用(流水灯的烧录以及sof转jic的方法记录)(上)
FPGA新起点V1开发板(三)——Quartus II软件的使用(流水灯的烧录以及sof转jic的方法记录)(上)
527 0
FPGA新起点V1开发板(三)——Quartus II软件的使用(流水灯的烧录以及sof转jic的方法记录)(上)
|
异构计算
FPGA新起点V1开发板(二)——Quartus II软件的安装和USB-BLaster驱动安装
FPGA新起点V1开发板(二)——Quartus II软件的安装和USB-BLaster驱动安装
875 0
FPGA新起点V1开发板(二)——Quartus II软件的安装和USB-BLaster驱动安装
|
异构计算
实验二 基于FPGA的分频器的设计(基本任务:设计一个分频器,输入信号50MHz,输出信号频率分别为1KHz、500Hz及1Hz。拓展任务1:用按键或开关控制蜂鸣器的响与不响。拓展任务2:用按键或开)
实验二 基于FPGA的分频器的设计(基本任务:设计一个分频器,输入信号50MHz,输出信号频率分别为1KHz、500Hz及1Hz。拓展任务1:用按键或开关控制蜂鸣器的响与不响。拓展任务2:用按键或开)
2023 0
实验二 基于FPGA的分频器的设计(基本任务:设计一个分频器,输入信号50MHz,输出信号频率分别为1KHz、500Hz及1Hz。拓展任务1:用按键或开关控制蜂鸣器的响与不响。拓展任务2:用按键或开)
|
算法 异构计算
通过状态机方法实现基于FPGA的维特比译码器,包含testbench测试文件
通过状态机方法实现基于FPGA的维特比译码器,包含testbench测试文件
329 0

热门文章

最新文章