EE_FPGA基础教程系列 -- 按键消抖
FPGA按键消抖实验(源码)

modulekey_scan(inputclk,inputrst_n,input [3:0] row, // 矩阵键盘行output reg [3:0] col, // 矩阵键盘列output reg [7:0] key_val // 键盘值);//++++++++++++++++++++++++++++++++++++++// 分频部分开始//++++++++++++++++++++++++++++++++++++++reg [19:0] cnt; // 计数子always @ (posedgeclk, negedgerst_n)if (!rst_n)cnt<= 0;elsecnt<= cnt + 1'b1;wirekey_clk = cnt[19]; // (2^20/50M = 21)ms //--------------------------------------// 分频部分结束//--------------------------------------//++++++++++++++++++++++++++++++++++++++// 状态机部分开始//++++++++++++++++++++++++++++++++++++++// 状态数较少,独热码编码parameter NO_KEY_PRESSED = 6'b000_001; // 没有按键按下parameter SCAN_COL0 = 6'b000_010; // 扫描第0列parameter SCAN_COL1 = 6'b000_100; // 扫描第1列parameter SCAN_COL2 = 6'b001_000; // 扫描第2列parameter SCAN_COL3 = 6'b010_000; // 扫描第3列parameter KEY_PRESSED = 6'b100_000; // 有按键按下reg [5:0] current_state, next_state; // 现态、次态always @ (posedgekey_clk, negedgerst_n)if (!rst_n)current_state<= NO_KEY_PRESSED;elsecurrent_state<= next_state;// 根据条件转移状态always @ *case (current_state)NO_KEY_PRESSED : // 没有按键按下if (row != 4'hF)next_state = SCAN_COL0;elsenext_state = NO_KEY_PRESSED;SCAN_COL0 : // 扫描第0列if (row != 4'hF)next_state = KEY_PRESSED;elsenext_state = SCAN_COL1;SCAN_COL1 : // 扫描第1列if (row != 4'hF)next_state = KEY_PRESSED;elsenext_state = SCAN_COL2;SCAN_COL2 : // 扫描第2列if (row != 4'hF)next_state = KEY_PRESSED;elsenext_state = SCAN_COL3;SCAN_COL3 : // 扫描第3列if (row != 4'hF)next_state = KEY_PRESSED;elsenext_state = NO_KEY_PRESSED;KEY_PRESSED : // 有按键按下if (row != 4'hF)next_state = KEY_PRESSED;elsenext_state = NO_KEY_PRESSED;endcaseregkey_pressed_flag; // 键盘按下标志reg [3:0] col_val, row_val; // 列值、行值// 根据次态,给相应寄存器赋值always @ (posedgekey_clk, negedgerst_n)if (!rst_n)begincol<= 4'h0;key_pressed_flag<= 0;endelsecase (next_state)NO_KEY_PRESSED : // 没有按键按下begincol<= 4'h0;key_pressed_flag<= 0; // 清键盘按下标志endSCAN_COL0 : // 扫描第0列col<= 4'b1110;SCAN_COL1 : // 扫描第1列col<= 4'b1101;SCAN_COL2 : // 扫描第2列col<= 4'b1011;SCAN_COL3 : // 扫描第3列col<= 4'b0111;KEY_PRESSED : // 有按键按下begincol_val<= col; // 锁存列值row_val<= row; // 锁存行值key_pressed_flag<= 1; // 置键盘按下标志endendcase//--------------------------------------// 状态机部分结束//--------------------------------------//++++++++++++++++++++++++++++++++++++++// 扫描行列值部分开始//++++++++++++++++++++++++++++++++++++++always @ (posedgekey_clk, negedgerst_n)if (!rst_n)key_val<= 4'h0;elseif (key_pressed_flag)case ({col_val, row_val})8'b1110_1110 :key_val<= 8'h01;8'b1110_1101 :key_val<= 8'h02;8'b1110_1011 :key_val<= 8'h03;8'b1110_0111 :key_val<= 8'h04;8'b1101_1110 :key_val<= 8'h05;8'b1101_1101 :key_val<= 8'h06;8'b1101_1011 :key_val<= 8'h07;8'b1101_0111 :key_val<= 8'h08;8'b1011_1110 :key_val<= 8'h09;8'b1011_1101 :key_val<= 8'h10;8'b1011_1011 :key_val<= 8'h11;8'b1011_0111 :key_val<= 8'h12;8'b0111_1110 :key_val<= 8'h13;8'b0111_1101 :key_val<= 8'h14;8'b0111_1011 :key_val<= 8'h15;8'b0111_0111 :key_val<= 8'h16; default: key_val=8'h00;endcaseendmodule。
fpgaVeriloghdl按键消抖部分程序讲解

fpgaVeriloghdl按键消抖部分程序讲解module debounce(clk_in,rst_in,key_in,key_pulse,key_state);input clk_in;//system clockinput rst_in;//system resetinput key_in;//button inputoutput key_pulse;//debounce pulse outoutput reg key_state;//debounce state outreg key_reg;//register key_rst,lock key_in to next clk//定义⼀个寄存器对输⼊信号进⾏锁存always @(posedge clk_in or negedge rst_in)beginif(!rst_in) key_reg<=1;else key_reg<=key_in;endwire key_an=(key_reg==key_in)?0:1;reg[18:0] cnt;/******* 计数器count the number of clk when a dege of key_in if occured*******/always @(posedge clk_in or negedge rst_in)beginif(!rst_in) cnt<=0;else if(key_an) cnt<=0;//由此可见当按键按下信号变化key_an变为1,计数cnt清零,然后重新计数,else cnt<=cnt+1; //由此可见这个程序是⼀直计数(相当于⼀直查询,key_an为1或者复位时cnt清零,重新计数)end/*******延时采样******/reg low_sw;//lock the status to register low_sw when cnt count to 19'd500000(即20ms)always @(posedge clk_in or negedge rst_in)beginif(!rst_in) low_sw<=1'b1;//直接写low_sw<=1;⼀样else if(cnt==500000) low_sw<=key_in;end/********下降沿检测********************/reg low_sw_reg;//register low_sw_reg,lock low_sw to next clkalways @(posedge clk_in or negedge rst_in)beginif(!rst_in) low_sw_reg<=1;else low_sw_reg<=low_sw;endwire key_pulse;//detect the negedge of low,generate pulseassign key_pulse=low_sw_reg&(~low_sw);/******脉冲状态输出*****/always @(posedge clk_in or negedge rst_in)beginif(!rst_in)key_state<=1;else if(key_pulse)key_state<=~key_state;else key_state<=key_state;endendmodule。
按键消抖的原理和基于fpga的消抖设计

按键消抖1功能概述按键开关是各种电子设备不可或缺的人机接口,如电脑的键盘等。
实际应用中,按键开关通常为机械式弹性开关。
当机械点断开、闭合时,由于机械触点的弹性作用,一个按键开关在闭合时不会马上稳定接通,断开时也不会马上断开,在闭合和断开的瞬间均伴随有一连串的抖动。
为保证系统及时正确识别,必须对这种情况作出相应处理。
我们称之为按键消抖。
按键消抖可分为硬件消抖和软件消抖。
硬件消抖的原理是在信号输入系统之前消除抖动干扰,在按键较少的情况下比较适宜。
如果按键较多,则使用软件消抖。
软件消抖的实质在于降低键盘输入端口的采样频率,将高频抖动略去。
需要注意的是,软件消抖需要占据一定的系统资源。
尽管硬件消抖和软件消抖能实现按键消抖功能,串行处理的方式都存在一定的局限性,显得不那么完美。
而硬件资源丰富的FPGA系统采用并行处理的模式,利用硬件来减轻软件工作量,通过硬件加速软件消抖处理,即可做到软件消抖并行化,因而在按键消抖处理方面具备非常明显的优势。
优秀的设计程序应该是用最简单的代码(架构、信号)实现功能。
在本例中,我们的只需要用4个信号界定,并用很短的代码即可。
下面我们先来看看功能要求:在系统设计中,消除按键抖动的方法五花八门,无论是硬件电路和软件设计都十分成熟。
在本项目中,我们将用Verilog语言给出具体实现过程,设计一个程序来检查键值,有效滤除按键抖动区间20 ms的毛刺脉冲。
2 设计思路一般按键所用开关为机械弹性开关,由于机械触点的弹性作用,每个按键开关在闭合时不会马上稳定地接通,在断开时也不会一下子断开。
因而在闭合及断开的瞬间均伴随有一连串的抖动,如下图。
抖动时间的长短由按键的机械特性决定,一般为5 ms~10 ms。
1图1 按键抖动过程示意当系统检测出按键闭合后,执行一个延时程序,产生5ms~10ms的延时;前沿抖动消失后,再一次检测键的状态;如果仍保持闭合状态电平,则确认为真正有键按下。
当检测到按键释放后,也要给5ms~10ms的延时,待后沿抖动消失后才能转入该键的处理程序。
fpga消抖模块的作用

fpga消抖模块的作用
在电子设备中,按键是常见的输入设备,用于接收用户操作指令。
然而,按键的机械特性使得它们在按下和释放时容易产生抖动,即按键状态的不稳定。
这种抖动现象会对后续的处理带来困扰,因为它可能会导致设备对单次按键行为产生误判,认为是一次或多次的按键动作。
为了解决这一问题,FPGA(现场可编程门阵列)中的消抖模块应运而生。
FPGA消抖模块的主要作用是消除按键抖动。
当按键被按下或释放时,由于机械触点的弹性作用,可能会产生一连串的抖动。
这些抖动可能非常短暂,一般都在10ms以内,但对于系统来说,却可能导致误判。
为了确保系统能够正确识别按键的开关状态,FPGA消抖模块通过特定的算法和逻辑处理,对按键的通断状态进行检测和过滤,消除这些短暂的抖动,从而确保按键状态识别的准确性。
在FPGA中实现消抖功能可以有多种方式。
其中一种是采用硬件消抖的方式,即在FPGA上配置相应的硬件电路来直接处理按键信号。
另一种方式是通过软件算法来实现消抖功能。
无论采用哪种方式,其核心目的都是确保系统能够准确识别
按键状态,避免因按键抖动而产生的误操作。
FPGA消抖模块的作用是消除按键在按下和释放过程中产生的抖动,确保系统能够准确识别按键状态,从而提高设备的可靠性和用户体验。
【豆丁-精品】-基于FPGA的按键消抖动设计

2009年11月吉林师范大学学报(自然科学版)№.4第4期Journal of Jilin Normal University (Natural Science Edition )Nov.2009收稿日期:2009209222 基金项目:吉林省信息产业厅专项发展基金项目(2007042)作者简介:许德成(19772),男,吉林省辽源市人,现为吉林师范大学信息技术学院讲师,硕士.研究方向:基础电子技术,单片机及可编程逻辑器件技术.基于FPG A 的按键消抖动设计许德成(吉林师范大学信息技术学院,吉林四平136000)摘 要:在研制测量仪表、电子仪器及电子设计的过程中,按键是常用器件,而按键的弹跳现象是数字系统设计中存在的客观问题.这就要求电路具有消抖措施,即对于由于机械弹跳产生的噪声信号经过消抖电路滤除,保证电路能够正确的响应.本文介绍了基于FPG A 的两种消除按键抖动的方法,并给出了相应的VH D L 代码以及仿真图形,从而解决了按键的机械抖动影响,保证电路稳定工作.关键词:机械抖动;仿真图形;电路中图分类号:T N912 文献标识码:A 文章编号:1674238732(2009)04201542030 引言我们通常所用的按键都为机械触点开关.由于机械触点存在弹性作用,当我们按下按键或松开按键时,都不可避免的要在触点闭合及断开的瞬间产生有一连串的键抖动.其按键信号的实际波形如图1所示.图1 按键信号的实际波形 由图1可见,在按键闭合和断开时产生了多个边沿.而在实际中每按一次键,我们只需要一组稳定的上升或下降边沿.所以对于电路中的按键信号,如果我们不滤除抖动的话,还是简单的读取信号的边沿,会引起一次按键被误读多次.这样就会引起电路的误动作.为了保证按一次键电路只有一次正确的响应,即在键闭合稳定时读取键的状态,就要求电路中必须采取滤除抖动的措施.消除案件抖动的方法一般有硬件和软件两种方式.对于硬件方式一般可用RS 触发器作为常用的消抖电路,从根本上解决按键抖动问题.但对于按键较多且从节省硬件资源和易于修改的角度考虑,我们常应用软件滤抖.1 基于计数器模式消抖电路的设计方法应用计数器实现,即采用延时的方法.先正确设定计数的时钟脉冲.当判断到按键按下时计数器开始计数,等计数器计满后再一次判断键的状态.如果仍为按下状态,则认为是按键稳定闭合.这时再针对具体按键信号做相应的处理,否则认为是抖动信号,电路不做任何处理.应用这种方法消除按键抖动,其计数器模值的确定和计数时钟的频率是按键抖动消除的关键问题,因为它们共同决定了延时的时间.如果延时时间过长,就会使正确的按键信号得不到处理;如果延时时间过短,则会将抖动误认为是输入信号,从而导致后电路做出错误处理.一般人按键的时间大于100ms ,抖动时间一般·451·为5ms ~10ms.按这种常规处理,我们一般认为接收到的按键信号持续时间如果小于40ms 则其为抖动信号,如果时间大于40ms 则为正确的按键信号.即让计数器的模值和计数时钟周期的乘积略大于40ms 即可.这样就可以把按下的时间小于40ms 的抖动信号滤掉.其VH D L 代码为:library ieee ;use ieee.std -logic -1164.all ;entity anjian is port (clk ,input :in std -logic ;output :out std -logic );end anjian ;architecture one of anjian is signal a :std -logic ;signal count :integer range 0to 9;beginprocess (clk )beginif input =′0′then count <=0;elsif clk ’event and clk =′1′thenif count =9then count <=count ;else count <=count +1;end if ;end if ;if count =8then a <=′1′;else a <=′0′;end if ;end process ;output <=a ;end one; 由上仿真图可以看出:当信号维持时间小于八个计数时钟周期的时候,认为这时的信号是短时间的抖动信号,所以电路输出不做任何反应.保持原电平不变,后续电路也无需处理.当信号维持时间超过八个计数时钟周期,认为这时定稳定的按键信号,即键稳定的闭合.所以输出一个按键脉冲,以供后续电路处理.2 基于RS 触发器模式的消抖动电路设计在设计中用时钟信号进行采样.对于按键输入信号,当两次采样信号相同时,这是判定已经稳定的按下或放开了按键.触发器相应的被置成0态或1态.如两次采样结果不相同.则触发器维持原输出信号不变.由于直接由触发器输出的信号时间宽度可能过长,所以在触发器后再接一级同步化电路,保证每次输出的信号只占有一个时钟周期的宽度.应用这种方法去滤除抖动,关键是确定采样时钟的频率.保证两次采样的时间间隔能够大于按键的抖动时间,且小于正常按键时的按键稳定闭合时间.其VH D L 代码和仿真如下:library ieee ;use ieee.std -logic -1164.all ;entity dou is port (din ,clk :in std -logic ;dout :out std -logic );end entity dou ;architecture one of dou issignal clr0,clr1,q0,q1,d1,d0:std -logic ;beginclr0<=din ;clr1<=q0;process (clk ,clr0,clr1)beginif clr0=′0′then q0<=′0′;elsif clk ′event and clk =′1′thenq0<=′1′;end if ;if clr1=′0′then q1<=′0′;elsif clk ′event and clk =′1′thenq1<=′1′;end if ;end process ;process (clk )beginif clk ′event and clk =′1′thend0<=q1;d1<=d0;end if ;end process ;dout <=d0and (not d1);end ;·551· 由上仿真图形可以看出:当两次的采样信号结果相同时,这时输出信号才可能发生变化,对应的按键的稳定闭合或断开,当两次的采样信号结果不同时,认为输入的信号定抖动信号.这时电路输出维持原状态不变,同时由于有同步化的处理,输出信号的高电平宽度只为采样时钟的一个周期.3 结束语通过以上的仿真图形可以看出,对于带有机械抖动的按键信号,当它经过消抖电路处理后其输出信号已经将抖动滤除,且输出信号只占有一个时钟信号的周期,从而能使后续电路能够正确的读取键值,做相应的响应,有效的避免了误动作.因此该设计有很大的实际应用意义.参 考 文 献[1]潘 松,黄继业.E DA 技术实用教程[M].北京:科学出版社,20051[2]谭会生,瞿遂春.E DA 技术综合应用实例与分析[M].西安:西安电子科技大学出版社,2004.[3]林明权等.VH D L 数字控制系统设计范例[M].北京:电子工业出版社,2003.[4]方 龙,肖献保,李 威.关于消除按键机械抖动的研究[J ].广西轻工业,2008,1:92.[5]潘永雄,泌河,刘向阳.电子线路CAD 实用教程[M].西安:西安电子科技大学出版社,2004.[6]杨 恒,李爱国,王辉,王新安.FPG A/CP LD 最新实用技术指南[M].北京:清华大学出版社,2005.[7][美]沃尔夫(W olr.w )基于FPG A 的系统设计(英语版)[M].北京:机械工业出版社,2005.[8]王强,曾繁泰,励娜.EPA 工程的理论与实践—S OC 系统蕊片设计[M].北京:电子工业出版社,2004.[9]李国洪,胡辉,沈阳山等.E DA 技术与实验[M].北京:电子工业出版社,2005.Shaking R elease Design on the K eys of FPGAXU De 2cheng(C ollege of In formation T echnology ,Jilin N ormal University ,S iping 136000,China )Abstract :K eys were the comm on elements during the research of measure instrument ,electronic apparatus ,and design of the electronic.The bounce phenomenon of keys was the objective problem in the digital system design.Therefore ,the shaking release measurement was necessary.That is to rem ove the noise signal at the engine bounce through the elimi 2nating the shaking circuit in order to ensure the right response of the circuit.The paper introduced tw o methods of elim 2inating shaking on FPG A and gave the relative VH D L code and the imitating picture.It res olved the in fluence of engine shaking on keys and ensurd the steady w orking of the circuit.K ey w ords :engine shaking ;imitating picture ;circuit·651·。
按键消抖

在使用单片机搭建有人机交互的系统时需要用到键盘,因为单片机工作时间都是纳秒与毫秒级别,但是我们人体的反应时间最少要0.2秒,之间差距很大,现实过程中也会不小心碰到按键,正常的按下按键应该是持续数十秒的稳定。
一、按键电路常用的非编码键盘,每个在使用单片机搭建有人机交互的系统时需要用到键盘,因为单片机工作时间都是纳秒与毫秒级别,但是我们人体的反应时间最少要0.2秒,之间差距很大,现实过程中也会不小心碰到按键,正常的按下按键应该是持续数十秒的稳定。
一、按键电路常用的非编码键盘,每个键都是一个常开开关电路。
计数器输入脉冲最好不要直接接普通的按键开关,因为记数器的记数速度非常快,按键、触点等接触时会有多次接通和断开的现象。
我们感觉不到,可是记数器却都记录了下来。
例如,虽然只按了1下,记数器可能记了3下。
因此,使用按键的记数电路都会增加单稳态电路避免记数错误。
二、按键消抖通常的按键所用开关为机械弹性开关,当机械触点断开、闭合时,电压信号小型如下图。
由于机械触点的弹性作用,一个按键开关在闭合时不会马上稳定地接通,在断开时也不会一下子断开。
因而在闭合及断开的瞬间均伴随有一连串的抖动,如下图。
抖动时间的长短由按键的机械特性决定,一般为5ms~10ms。
这是一个很重要的时间参数,在很多场合都要用到。
按键稳定闭合时间的长短则是由操作人员的按键动作决定的,一般为零点几秒至数秒。
键抖动会引起一次按键被误读多次。
为确保CPU对键的一次闭合仅作一次处理,必须去除键抖动。
在键闭合稳定时读取键的状态,并且必须判别到键释放稳定后再作处理。
按键的抖动,可用硬件或软件两种方法。
三、硬件消抖在键数较少时可用硬件方法消除键抖动。
下图所示的RS触发器为常用的硬件去抖。
消抖电路如下图中两个“与非”门构成一个RS触发器。
当按键未按下时,输出为1;当键按下时,输出为0。
此时即使用按键的机械性能,使按键因弹性抖动而产生瞬时断开(抖动跳开B),中要按键不返回原始状态A,双稳态电路的状态不改变,输出保持为0,不会产生抖动的波形。
FPGA学习按键消抖实验Verilog代码

FPGA学习按键消抖实验Verilog代码modulesw_de(clk,rst_n,sw1_n,sw2_n,sw3_n,led_d1,led_d2,led_d3);input clk; //主时钟信号 50MHzinput 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)/*always块clk时钟的上升沿和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中20'hfffff='d1048575 t=1/48000000*1048575=0.021s*/ low_sw<={sw3_n,sw2_n,sw1_n};/*将按键sw3_n,sw2_n,sw1_n,用位拼接符{}拼接为一个三位的数传给low_sw*///-----------------------------------------------------------reg[2:0] low_sw_r; //每个时钟周期的上升沿将low_sw信号锁存到low_sw_ralways @ (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_ctr1的值变为高,维持一个时钟周期wire[2:0] led_ctr1=low_sw_r[2:0]&(~low_sw[2:0]);//找出变化的键存到led_ctr1中reg d1;reg d2;reg d3;always @ (posedge clk or negedge rst_n)if (!rst_n)begind1<=1'b0;d2<=1'b0;d3<=1'b0;endelse begin //某个按键值变化时,LED将亮灭翻转 if (led_ctrl[0]) d1<=~d1;if (led_ctrl[1]) d2<=~d2;if (led_ctrl[2]) d3<=~d3;endassign led_d3=d1?1'b1:1'b0; assign led_d2=d2?1'b1:1'b0; assign led_d1=d3?1'b1:1'b0; endmodule。
按键去抖说明

(r>O v« O-按键去抖说明由于机械触点的弹性振动,按键在按下时不会马上稳定地接通而在弹起时也不能一下子完 全地断开,因而在按键闭合和断开的瞬间均会出现一连串的抖动,这称为按键的扌耳动干扰, 其产生的渡形如图5.3.1所示,当按键按下时•会产生前沿抖动,当按键弹起时会产生后沿抖 动。
这是所有机械蝕点武按键在状态输出时的共性问题,抖动的时间长短取决于按键的机械 特性与操作状态,一般为10~L00ms,此为键处理设计时要考虑的一个重要参数。
取按键状态,必须在按键囲合或斷开时,消除产生的前沿或后沿抖动,去抖动的方法有硬件 方法和软件方法两种。
1.硬件方法硬件方法是设计一个滤波延时电路或单稳态电路尊硬件电路来遥开按键的抖动时间。
图>3. 2是由R2和C 组成的滤波延时消抖电路,设豈在按键S 与CPU 数据线Di 之 间。
按键S 未按下时•,电容两端电压为0,即与非门输入丙为0,输出卩o 为1。
当S 按下 时,由于C 两端电压不能突变,充电电压丙在充电时间内未达到与非门的开启电压,门的瑜 出心将不会改变,亘到充电电压巧丈于门的开启电压时,与非门的输出X )才变为0,这 段充电延迟时间取决于Rl 、R2和C 值的大小,电路设计时只要使之大于或等于10 0 ms 即可避开按键抖动的彫响。
同理,按键S 断开时,即使出现押动,由于C 的放电延迟 过程,也会消除按键抖动的彫响-4-5 VR-1按键去抖说明^2是施帕滤波电路后消除抖动的波形"2.软件方法软件方法是指编制一段时间大^lOOms的延时程序,在第一次检测到有键按下时,执行这段延时子程序使键的前沿抖动消失后再检测该键状态,如果该键仍保持闭台伏态电平,则确认为该钳已稳定按F 否则无镇按兀从而消除了料动的影响’同理,在检测到按键释放后,也同样要延迟一段时间,以消除后沿抖动,然后转入对该按键的处理。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
电子工程世界
EE_FPGA 基础教程系列
我们画一张时序图来解释这个问题就非常好理解了。我们假设按键 key1 输
if (!rst_n)
reg1_low <= 1'b1;
else
reg1_low <= reg_low;
end
//---------------------------------------------------------------------------
//当寄存器 reg_low 由 1 变为 0 时,key_low 的值变为高,维持一个时钟周期 wire key_low = reg1_low & ( ~reg_low);
else if(cnt
reg_low <= key1;
// cnt == 20'hfffff 约 20ms
reg1_low <= reg_low;
if (!rst_n) cnt_key <= 20'd0; //复位 else if(key_an) cnt_key <=20'd0; else cnt_key <= cnt_key + 1'b1; end
reg reg_low;
reg reg1_low;
always @(posedge clk or negedge rst_n) begin
//当寄存器 key1 由 1 变为 0 时,led_an 的值变为高,维持一个时钟周期 wire key_an; assign key_an = reg1_key & ( ~reg0_key); //-------------------------------启动延时-------------------------------------------reg[19:0] cnt_key; //计数寄存器 always @ (posedge clk or negedge rst_n) begin
程序设计的基本思路是: 1、检测管脚电平是否拉低 2、若检测到低电平,启动计数器,延时 20ms 左右的时间 3、再次检测管脚是否低电平 4、若还是低电平,确定按键被按下。输出控制信号
2.4 按键消抖程序
input clk; //主时钟信号,50MHz input rst_n; //复位信号,低有效 input key1; //按键 1 //--------------------------------------------------------------------------reg reg0_key; reg reg1_key; always @(posedge clk or negedge rst_n) begin
Revision History
Description
EE_FPGA 基础教程---- 按键消抖
Date
Keywords:
Abstract: 本文分析按键消抖的 verilog 程序。学习非阻塞赋值和脉冲边沿检测的原
理。
电子工程世界
EE_FPGA 基础教程系列
测上升沿的典型语句。不信你画个时序图看看。顺便多说一句,做数字电路,画
时序图是解决问题的一个很好的方法哦。
理解了以上两个知识点,那这个按键消抖的程序就很好懂了。如果管脚检测
到下降沿,我们用 key_an 作为标志信号启动计数器,当计数器计到 20’hfffff 的
时候,(即约 10 万个 clk 周期,20ms)。再次存入键值,
2.2 何为按键消抖
如果仅仅是按上面所说,那这个是否太简单了一点呢?是滴,你一定会想到
电子工程世界
EE_FPGA 基础教程系列
按键消抖的问题。似乎不管是学单片机还是 DSP 的时候,凡是涉及到按键的都 会提到按键消抖。正好,网上找到一张关于按键抖动的图。
抖动时间 t1、t3 一般在 20ms 左右。从理论上讲,在抖动时间内,会产生多 个脉冲信号,如果不进行任何处理,则按一次按键,程序会认为按了多次,从而 产生错误。
2.5 程序分析
这段短短的程序,其实有着两个非常重要的知识点值得我们学习。 首先,大家了解下复位语句,if (!rst_n) begin *** end 起到异步复位作用, 就是对程序设置一个初始值,这样的语句大家只要了解初始值是多少就可以。 对于蓝色标注的两段程序,有个重要的知识点。在介绍这个知识点之前,大 家还必须对非阻塞赋值和阻塞赋值有个清楚的了解。这里就利用了非阻塞赋值的
if(!rst_n) begin reg0_key <= 1'b1; reg1_key <= 1'b1;
end else begin
电子工程世界
EE_FPGA 基础教程系列
reg0_key <= key1; reg1_key <= reg0_key; end end
if (!rst_n) begin
reg_low <= 1'b1;
end
else if(cnt_key == 20'hfffff) begin
reg_low <= key1;
// cnt == 20'hfffff 约 20ms
end
end
always @(posedge clk or negedge rst_n) begin
电子工程世界
EE_FPGA 基础教程系列
1. 回顾
这次我们继续给玩转 LED 加入些新元素,使用按键控制 LED。点亮 LED 是 利用了 FPGA 输出电平,这次对按键进行操作则是对 FPGA 进行输入了。
2. 按键消抖
2.1 按键输入原理
首先,我们得打开 EE_FPGA 的硬件手册,找到按键部分的原理图。 如下图所示,这会大家就可以利用在 LED 中学到的知识进行分析了,当按 键没有被按下的时候,管脚连接的是 VDD3.3V 的高电平;当按键被按下时,管 脚接地。 所以我们只要检测这几个管脚是否是低电平,就可以判断是否有按键被按下 啦。
入上图这样一段时序序列。经过 reg0_key 和 reg1_key 的移位操作,以及 reg0_key
的取反。最后寄存器 key_an 被拉高一个时钟周期,清楚地显示了下降沿的位置。
这段程序是用来检测下降沿的典型程序。这里,我提醒下,我们只要把取反
的寄存器换一下,改成 assign key_an = reg0_key & ( ~reg1_key);就变成了一段检
电子工程世界
EE_FPGA 基础教程系列
EE_FPGA 基础教程系列
按键消抖
V1.0
作者:xieqiang
整理: chenzhufly QQ: 36886052 2011-3-22
电子工程世界
Version
1.0
Author
chenzhufly
EE_FPGA 基础教程系列
那不消抖可不可以的呢,也许有些地方是没什么问题的。上次还在论坛上看 到一位朋友一定要找出一种能说明按键不消抖有问题的例子。我想,这样没必要, 设计的时候根据实际情况自然就知道需不需要消抖了。这里,我们是学习这个知 识点。
2.3 按键消抖思路
关于 FPGA 的按键消抖,我在网上找了一个经典的程序,稍加修改,便于大 家学习和理解。
2.1 按键输入原理........................................................................................................4 2.2 何为按键消抖........................................................................................................4 2.3 按键消抖思路........................................................................................................5 2.4 按键消抖程序........................................................................................................5 2.5 程序分析 ...............................................................................................................6 2.6 整体程序 ...............................................................................................................8 3. 实验结果 ........................................................................................................................10 4. 总结................................................................................................................................11
Table of Contents