FPGA 独立按键消抖

来源:互联网 发布:c语言程序设计编程题库 编辑:程序博客网 时间:2024/05/16 01:03

思路:

状态机的思想,分4个状态:

1.空闲状态,等待按键按下

2.消除抖动状态1,用计数器延时5ms至10ms

3.按键按下

4.消除抖动状态2,用计数器延时5ms至10ms


程序:

module Key_Filter(Clk,Rst_n,Key_in,Key_flag,Key_state);input Clk;input Rst_n;input Key_in;output reg Key_flag;output reg Key_state;reg [3:0] state;reg [19:0] cnt;reg en_cnt;reg cnt_full;reg temp0,temp1;wire pos_edge,neg_edge;localparam IDLE = 4'b0001,FILTER0 = 4'b0010,DOWN= 4'b0100,FILTER1= 4'b1000;always@( posedge Clk or negedge Rst_n )beginif( Rst_n==0 )beginstate <= IDLE;Key_flag <= 0;Key_state <= 1;en_cnt <= 0;endcase ( state )IDLE:beginKey_flag <= 0;if( neg_edge==1 )beginstate <= FILTER0;en_cnt <= 1;endendFILTER0:beginif( cnt_full==1 )beginstate <= DOWN;Key_flag <= 1;Key_state <= 0;en_cnt <= 0;endelse if( pos_edge==1 )beginstate <= IDLE;en_cnt <= 0;endendDOWN:beginKey_flag <= 0;if( pos_edge==1 )beginstate <= FILTER1;en_cnt <= 1;endendFILTER1:beginif( cnt_full==1 )beginstate <= IDLE;Key_flag <= 1;Key_state <= 1;endelse if( neg_edge==1 )beginstate <= DOWN;en_cnt <= 0;endenddefault:beginstate <= IDLE;Key_flag <= 0;Key_state <= 1;en_cnt <= 0;endendcaseendalways@(posedge Clk or negedge Rst_n)if(!Rst_n)begintemp0 <= 1'b0;temp1 <= 1'b0;endelse begintemp0 <= Key_in;temp1 <= temp0;endassign neg_edge = !temp0 & temp1;assign pos_edge = temp0 & (!temp1);always@( posedge Clk or negedge Rst_n )beginif( Rst_n==0 )cnt <= 0;else if( en_cnt==1 )cnt <= cnt+1;elsecnt <= 0;endalways@( posedge Clk or negedge Rst_n )beginif( Rst_n==0 )cnt_full <= 0;else if( cnt==99_999 )cnt_full <= 1;elsecnt_full <= 0;endendmodule 


testbench程序:

`timescale 1ns/1ns`define clk_period 20module Key_Filter_tb;reg Clk;reg Rst_n;reg Key_in;reg [15:0] rand;wire key_flag;wire key_state;Key_Filter Key_Filter0(.Clk(Clk),.Rst_n(Rst_n),.Key_in(Key_in),.Key_flag(key_flag),.Key_state(key_state));initial Clk= 1;always#(`clk_period/2) Clk = ~Clk;initial beginRst_n = 0;#(`clk_period*10);Rst_n = 1;#(`clk_period*10 + 1);press_key;#10000;press_key;#10000;press_key;#10000;$stop;endtask press_key;beginrepeat(20)beginrand = {$random} % 65536 ;#rand;Key_in = ~Key_in;endKey_in = 0;#50_000_000;repeat(20)beginrand = {$random} % 65536 ;#rand;Key_in = ~Key_in;endKey_in = 1;#50_000_000;endendtaskendmodule 

RTL仿真结果:


0 0
原创粉丝点击