欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 手游 > 18.按键消抖模块设计(使用状态机,独热码编码)

18.按键消抖模块设计(使用状态机,独热码编码)

2024/10/24 8:33:00 来源:https://blog.csdn.net/2301_80417284/article/details/140178343  浏览:    关键词:18.按键消抖模块设计(使用状态机,独热码编码)

(1)设计意义:按键消抖主要针对的时机械弹性开关,当机械触点断开、闭合时,由于机械触点的弹性作用,一个按键开关在闭合时不会马上稳定地接通,在断开时也不会一下子就断开。因而在闭合以及断开的瞬间会伴随有一连串的抖动,为了保证系统正确的识别到按键的开关,就必须对按键的抖动进行处理,这就是按键消抖。

(2)Verilog实现代码:

module key_filter(clk,reset_n,key_in,key_p_flag,key_r_flag,key_state);input clk;input reset_n;input key_in;output reg key_p_flag;output reg key_r_flag;output reg key_state;reg key_in1;reg key_in2;reg key_in3;reg [3:0]STATE;
//抖动时间往往小于20ms,20ms = 20_000_000ns = 20ns * 1_000_000;   需要一个20位的寄存器reg [19:0]cnt;reg en_cnt;wire podge;wire nedge;wire arrive_time_20ms;//状态设计parameter IDLE      = 4'b0001;parameter P_SHAKE   = 4'b0010;parameter DOWN      = 4'b0100;parameter R_SHAKE   = 4'b1000;//异步输入key_in信号的同步化————“打两拍”always@(posedge clk)beginkey_in1 <= key_in;key_in2 <= key_in1;end//上升沿、下降沿设计always@(posedge clk)key_in3 <= key_in2;assign podge = key_in2  &&  (!key_in3);assign nedge = (!key_in2)  &&  key_in3;//20ms计数器模块设计    always@(posedge clk or negedge reset_n)if(!reset_n)cnt <= 20'd0;else if(en_cnt &&(cnt == 20'd999_999))cnt <= 20'd0;else if(en_cnt)cnt <= cnt + 20'd1;else cnt <= 20'd0;//计满20ms信号设计           assign arrive_time_20ms = (cnt == 20'd999_999);//状态机主程序设计always@(posedge clk or negedge reset_n)if(!reset_n)beginkey_r_flag <= 1'd0;key_p_flag <= 1'd0;key_state  <= 1'd1;STATE      <= IDLE;endelse begincase(STATE)IDLE:beginkey_r_flag <= 1'd0;key_state  <= 1'd1;if(nedge)beginSTATE <= P_SHAKE;en_cnt <= 1'd1;endelse STATE <= STATE;endP_SHAKE:beginif(arrive_time_20ms)beginSTATE <= DOWN;en_cnt <= 1'd0;key_p_flag <= 1'd1;key_state <= 1'd0;endelse if(podge)beginSTATE <= IDLE;en_cnt <= 1'd0;endelse STATE <= STATE;  endDOWN:beginkey_p_flag <= 1'd0;key_state <= 1'd0;if(podge)beginSTATE <= R_SHAKE;en_cnt <= 1'd1;endelse STATE <= STATE;          endR_SHAKE:beginif(arrive_time_20ms)beginSTATE <= IDLE;en_cnt <= 1'd0;key_r_flag <= 1'd1;key_state  <= 1'd1;endelse if(nedge)beginSTATE <= DOWN;en_cnt <= 1'd0;endelse STATE <= STATE; enddefault:beginkey_r_flag <= 1'd0;key_p_flag <= 1'd0;key_state  <= 1'd1;STATE      <= IDLE;endendcaseendendmodule

(3)仿真文件代码:

`timescale 1ns / 1psmodule key_filter_tb;reg clk;reg reset_n;reg key_in;wire key_p_flag;wire key_r_flag;wire key_state;key_filter key_filter_inst(.clk(clk),.reset_n(reset_n),.key_in(key_in),.key_p_flag(key_p_flag),.key_r_flag(key_r_flag),.key_state(key_state));initial clk = 1'd1;always #10 clk = ~clk;initial beginreset_n <= 1'd0;key_in  <= 1'd1;#15;reset_n <= 1'd1;#2000;key_in <= 1'd0;#1500;key_in <= 1'd1;#20000;key_in <= 1'd0;#40_000_000;key_in <= 1'd1;#1000;key_in <= 1'd0;#200;key_in <= 1'd1;#1800;key_in <= 1'd0;#25000;key_in <= 1'd1;#30_000_000;$stop;endendmodule

(4)仿真波形分析:

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com