按键消抖状态机 Verilog 代码实现
/=============================================================状态机模块================================================================/ reg [1:0] state; output reg key_flag1; //经消抖后可确认的按下动作 reg key_state; //按键状态,高电平为未按下,低电平为按下状态
always@(posedge clk ) begin
begin
case(state)
S1: //高电平(松开稳定)
begin
key_flag1 <= 1'b0; //按键未按下,不计
key_state <= 1'b1; //按键松开状态
en_counter <= 1'b0; //计数器归零
if(nedge) //检测到下降沿,进入下一个状态同时打开计数器
begin
state <= S2;
en_counter <= 1'b1; //计数器使能
end
else
state <= state; //保持目前状态
end
S2: //下降沿抖动(按下毛刺)
if(cnt_full) //计数满,说明达到稳定状态,关闭计数器,进入下一个状态
begin
state <= S3;
en_counter <= 1'b0; //计数器归零
key_flag1 <= 1'b1; //按键可确认已按下
key_state <= 1'b0; //按键按下状态
end
else if(pedge) //检测到上升沿(毛刺),跳回S1状态同时关闭计数器
begin
en_counter <= 1'b0; //计数器归零
state <= S1;
end
else
state <= state; //保持目前状态
S3: //低电平(按下稳定)
begin
key_flag1 <= 1'b0; //一个按键周期测到一次就行,现在可清零了(后面代码编写只在意其posedge)
if(pedge) //检测到上升沿,进入下一个状态同时打开计数器
begin
state <= S4;
en_counter <= 1'b1; //计数器使能
end
else
state <= state; //保持目前状态
end
S4: //上升沿抖动(松开毛刺)
if(cnt_full)
begin
state <= S1;
key_state <= 1'b1;
end
else
if(nedge)
begin
en_counter <= 1'b0; //计数器归零
state <= S3;
end
else
state <= state; //保持目前状态
default:
state <= S1;
endcase
end
end
// 设计原理内容:该状态机模块用于对按键信号进行消抖和稳定处理,输出一个可确认的按下动作。其中,按键的状态分为高电平(松开稳定)、下降沿抖动(按下毛刺)、低电平(按下稳定)、上升沿抖动(松开毛刺)四种状态。在高电平状态下,如果检测到下降沿,则进入下降沿抖动状态,同时打开计数器;在下降沿抖动状态下,如果计数满,则说明达到稳定状态,进入低电平状态;如果检测到上升沿,则说明出现按下毛刺,回到高电平状态;在低电平状态下,如果检测到上升沿,则进入上升沿抖动状态,同时打开计数器;在上升沿抖动状态下,如果计数满,则说明达到松开稳定状态,回到高电平状态;如果检测到下降沿,则说明出现松开毛刺,回到低电平状态。最后,如果状态机处于非以上四种状态,则回到高电平状态。在状态机运行过程中,会输出一个key_flag1信号,表示经过消抖和稳定处理后的可确认按下动作,同时输出一个key_state信号,表示当前按键的状态(高电平或低电平)。
原文地址: http://www.cveoy.top/t/topic/oTd2 著作权归作者所有。请勿转载和采集!