| |
/*2*2键盘扫描程序*/
module ffd(data_in ,CLK,EN ,key_buf,data_out );
input [1:0] data_in ; //列定义
input EN,CLK;
output [1:0] data_out;//行定义
output [3:0] key_buf ;
parameter DELAY=1,ROW1=2,ROW2=3,ROW1TEMP=4,ROW2TEMP=5,KEY=6,WAIT=7,DELAY1=8,KEYTEMP=9;//状态定义
reg [1:0] data_out ;
reg [3:0] key_buf;
reg [3:0] key_buf1;//键值寄存器
reg [4:0] count,count1;
reg [4:0] STATE;
reg [4:0] STATE_TEMP;
always @(posedge CLK )
if(EN)
begin
case(STATE)
KEY:
begin
data_out <= 2'b00; //行线全部置0
STATE=DELAY;
STATE_TEMP=KEYTEMP;
end
KEYTEMP:
begin
if(data_in ==2'b11) //判断是否有按键按下
STATE=KEY;
else
begin
STATE=DELAY; //如果有就延时去抖
STATE_TEMP=ROW1TEMP;
end
end
ROW1TEMP: begin
data_out <= 2'b10; //第一行扫描
STATE=DELAY;
STATE_TEMP=ROW1;
end
ROW1:
begin
case({data_out ,data_in}) //第一行判断
4'b1011: begin //无键按下
key_buf1<=4'b0000;
STATE=ROW2TEMP; //进入第二行扫描
end
4'b1010: begin
key_buf1<=4'b1011;//键值放入key_buf1
STATE=WAIT; //等待弹起
end
4'b1001: begin
key_buf1<=4'b0111;
STATE=WAIT;
end
default: begin
key_buf<=4'b0000;
STATE=ROW2TEMP;
end
endcase
end
ROW2TEMP: begin
data_out <= 2'b01; //第二行扫描
STATE=DELAY;
STATE_TEMP=ROW2;
end
ROW2:
begin
case({data_out ,data_in})
4'b0111: begin
key_buf1<=4'b0000;//同上
STATE=KEY;
end
4'b0110: begin
key_buf1<=4'b1110;
STATE=WAIT;
end
4'b0101: begin
key_buf1<=4'b1101;
STATE=WAIT;
end
default: begin
key_buf<=4'b0000;
STATE=KEY;
end
endcase
end
DELAY: //去抖延时
begin
if(count==1)
begin
STATE=STATE_TEMP; //进入第一行扫描
count<=0;
end
else
count<=count+1;
end
WAIT: //等待弹起
begin
if(data_in ==2'b11)
begin
STATE=DELAY1;
key_buf<=key_buf1;//把键值存起来
end
else
STATE=WAIT;
end
DELAY1: //弹起后的延时
begin
if(count1==1)
begin
STATE=KEY; //从新扫描
count1<=0;
end
else
count1<=count1+1;
end
endcase
end
else //变量初始化
begin
STATE=KEY;
count<=0;
count1<=0;
key_buf<=4'b1111;
data_out<= 2'b11;
end
endmodule