fpga按键去抖
时间:10-02
整理:3721RD
点击:
/*2017.3.11 zc in xidian
reset低电平复位
key_pre直接接去抖前的按键 按下为低
key_out为去抖后的按键 输出高表示按下。
*/
module debounce(
input clk_50M,
input reset,
input key_pre,
output key_out);
parameter idle= 6'b0000_01,
delay1= 6'b0000_10,
press= 6'b0001_00,
taiqi= 6'b0010_00,
delay2= 6'b0100_00,
nopress=6'b1000_00; //没用到
reg[5:0] state;
reg [31:0] cnt;
reg delay;
always@(posedge clk_50M)
begin
if(!reset)
begin cnt<=0; delay=0; end
else
if(clk_50M==1)
if(cnt==999_999)//延时20ms
//if(cnt==99) //[color=rgb(68, 68, 68) !important]仿真
begin cnt<=0; delay<=1;end
else
begin cnt<=cnt+1; delay<=0; end
end
always@(posedge clk_50M)
begin
if(!reset)
state<=idle;
else
if(delay==1) //delay为1时,进程只可能触发一次,因为delay的宽度只可能是一个clk 不可能跨越多个clk的
begin
case(state)
idle: if(key_pre==0) state<=delay1; else state<=idle;
delay1: if(key_pre==0) state<=press; else state<=idle;
press: if(key_pre==1) state<= delay2; else state<=press;
//delay2: if(key_pre==1) state<=taiqi; else state<=press;
//刚开始有delay2又跳到press 这是不对的 既然为1了 说明已经有抬起的动作了 如果再返回press状态 可能造成多次有press状态 去抖动不理想
delay2: if(key_pre==1) state<=taiqi; else state<=delay2;
taiqi: state<=idle;
default:state<=idle;
endcase
end
end
assign key_out=(state==taiqi && delay==1)?1'b1:1'b0; //加上delay==1这个条件保证key_out只输出一次高
//弹起状态时才能认为按下 如果在press状态下输出 则长时间按下会认为多次按下
endmodule
reset低电平复位
key_pre直接接去抖前的按键 按下为低
key_out为去抖后的按键 输出高表示按下。
*/
module debounce(
input clk_50M,
input reset,
input key_pre,
output key_out);
parameter idle= 6'b0000_01,
delay1= 6'b0000_10,
press= 6'b0001_00,
taiqi= 6'b0010_00,
delay2= 6'b0100_00,
nopress=6'b1000_00; //没用到
reg[5:0] state;
reg [31:0] cnt;
reg delay;
always@(posedge clk_50M)
begin
if(!reset)
begin cnt<=0; delay=0; end
else
if(clk_50M==1)
if(cnt==999_999)//延时20ms
//if(cnt==99) //[color=rgb(68, 68, 68) !important]仿真
begin cnt<=0; delay<=1;end
else
begin cnt<=cnt+1; delay<=0; end
end
always@(posedge clk_50M)
begin
if(!reset)
state<=idle;
else
if(delay==1) //delay为1时,进程只可能触发一次,因为delay的宽度只可能是一个clk 不可能跨越多个clk的
begin
case(state)
idle: if(key_pre==0) state<=delay1; else state<=idle;
delay1: if(key_pre==0) state<=press; else state<=idle;
press: if(key_pre==1) state<= delay2; else state<=press;
//delay2: if(key_pre==1) state<=taiqi; else state<=press;
//刚开始有delay2又跳到press 这是不对的 既然为1了 说明已经有抬起的动作了 如果再返回press状态 可能造成多次有press状态 去抖动不理想
delay2: if(key_pre==1) state<=taiqi; else state<=delay2;
taiqi: state<=idle;
default:state<=idle;
endcase
end
end
assign key_out=(state==taiqi && delay==1)?1'b1:1'b0; //加上delay==1这个条件保证key_out只输出一次高
//弹起状态时才能认为按下 如果在press状态下输出 则长时间按下会认为多次按下
endmodule