按键扫描
该模块包含按键消抖,输入按键的引脚状态,输出
module KeyScan(
input clk,
input rst_n,
input [3:0] KEY, //按键输入
output reg [3:0] KEY_state //每个按键是否按下的状态
);
parameter KEY_DELAY_COUNT = 20'd5; //按键延时消抖的常量,定义10MS需要计数500_000,这里仿真只是使用5个周期代替,实际的时候自行修改
reg [19:0] count; //仿真查看延时计数值
reg [1:0] key_down_state; //仿真按键当前是否按下的状态
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
key_down_state <= 'd0; //状态标志位清零
KEY_state <= 'b1111; //状态标志位复位
end
else
begin
//状态标志位为0同时有按键按下的时候
if(key_down_state == 'd0 && KEY != 'b1111)
begin
//将状态标志位置1
key_down_state <= 'd1;
end
//等待延时计数值到达设定值
else if(key_down_state == 'd1 && count == KEY_DELAY_COUNT)
begin
//将状态标志位置2
key_down_state <= 'd2;
//将按键状态值获取,这是延时后的状态,是按下后的状态值,这个状态值只会存在一个周期,因为下一个周期就会被最后一个else将将状态标志位复位
//所以按键按下的状态只会保存一个周期
KEY_shang_state <= KEY_shang;
KEY_jin_state <= KEY_jin;
KEY_que_ren_state<= KEY_que_ren;
end
//当全部按键抬起的时候,将状态标志位置0,就又可以检测按键是否按下了
else if(key_down_state == 'd2 && KEY == 'b1111 )
key_down_state <= 'd0;
//其他情况将状态标志位复位
else
begin
KEY_state <= 'b1111;
end
end
end
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
count <= 'd0;
end
else
begin
//按键计数值到了指定数,清零
if(count == KEY_DELAY_COUNT)
count <= 'd0;
//按键状态处于状态1,开始延时计数
else if(key_down_state == 'd1)
count <= count + 'd1;
else
count <= count;
end
end
endmodule