欢迎来到天天文库
浏览记录
ID:1677149
大小:66.00 KB
页数:4页
时间:2017-11-13
《按键去抖fpga设计 改良版-》由会员上传分享,免费在线阅读,更多相关内容在行业资料-天天文库。
1、按键消抖sw_debounce 什么是debounce,为什么要debounce? 當按下按鈕時,表面上只按了一下。但是訊號的傳遞並不是很單純的由’1’直接跳到’0’。實際上的訊號會如上圖所示,當我們按下按鈕後,訊號會在高低電位之間彈跳(bounce)。則電路所收到的訊號可能會像111110110110000000,會和我們所預期的111111111000000000不同。如此一來,雖然我們只按了一下按鈕,電路可能會解讀成按了好幾下按鈕。debounce的目的就是為了要除去訊號在高低電位之間彈跳所造成的不正確輸入。具体原理
2、:通常,按键抖动会产生10--20MS的毛刺,因此要做的实际上就是在20MS中采样一次,当检测到按键突变的时候,就认定按下,其他状态忽略。采用50MHz晶振,时钟周期是20ns,消除按键消抖的关键在于,在检测到按键电平发生跳变后的20ms内,不对按键电平进行判定。这就需要引入脉冲边沿检测法。脉冲边沿检测法,个人觉得,在FPGA里的应用实在是太多了,几乎所有的程序都要用到,作用无非是防止竞争冒险,将一个信号延迟一个时钟周期,原来的信号取反,2个信号与一下,从而产生一个宽度为一个时钟周期(20ns)的脉冲,然后将这个脉冲作为控制信号去控制别的进程。。。 下面是之前开发板的一个按键程序:modu
3、lesw_debounce(clk,rst_n,sw1_n,sw2_n,sw3_n,//outputled_d1,//led1--off,0--onled_d2,led_d3);inputclk;inputrst_n;inputsw1_n,sw2_n,sw3_n;//Activelow低电平有效outputled_d1;outputled_d2;outputled_d3;//脉冲边沿检测法(当按键电平发生突变时产生一个时钟周期的高电平,用这个高电平控制计数器的工作)reg[2:0]key_rst;always@(posedgeclkornegedgerst_n)if(!rst_n)key_rs
4、t<=3'b111;elsekey_rst<={sw3_n,sw2_n,sw1_n};reg[2:0]key_rst_r;always@(posedgeclkornegedgerst_n)if(!rst_n)key_rst_r<=3'b111;elsekey_rst_r<=key_rst;wire[2:0]key_an=key_rst_r[2:0]&(~key_rst[2:0]);//---------------------------------------------------------------------------reg[19:0]cnt;//时钟频率50MHz,周期20ns
5、,所以20ms对应的需要10的6次方个周期,需要一个20位计数器计数。always@(posedgeclkornegedgerst_n)if(!rst_n)cnt<=20'd0;elseif(key_an)//利用脉冲边沿检测法控制计数器计数cnt<=20'd0;elsecnt<=cnt+1'b1;reg[2:0]low_sw;always@(posedgeclkornegedgerst_n)if(!rst_n)low_sw<=3'b111;elseif(cnt==20'hfffff)//每隔20MS检测一次按键low_sw<={sw3_n,sw2_n,sw1_n};//-----------
6、----------------------------------------------------------------//---------------------------------------------------------------------------reg[2:0]low_sw_r;//将low_sw信号锁存一个时钟周期,延时不是真的“锁存”always@(posedgeclkornegedgerst_n)if(!rst_n)low_sw_r<=3'b111;elselow_sw_r<=low_sw;wire[2:0]led_ctrl=low_sw_r[2:0]
7、&(~low_sw[2:0]);//当检测到按键有下降沿变化时,代表该按键被按下,按键有效regd1;regd2;regd3;always@(posedgeclkornegedgerst_n)if(!rst_n)begind1<=1'b0;d2<=1'b0;d3<=1'b0;endelsebeginif(led_ctrl[0])d1<=~d1;if(led_ctrl[1])d2<=~d2;if(l
此文档下载收益归作者所有