今天,第一次在CPLD板上实现了第一个数字电路4×4键盘扫描的verilog 代码,欢迎大家讨论。
// *********************************************************************
// 键盘扫描VerilogHDL代码
//2007.7.26 by Levension @SCUT
// *********************************************************************
module keypad(keyval,y,x,clk);
output [4:0] keyval; //返回的键值
output [3:0] x; //输出,列坐标
input [3:0] y; //输入,行坐标
input clk; //时钟源
reg [4:0] keyval;
reg [3:0] x;
parameter clkdiv="2048";
parameter S0=4'd0, //状态机
S1=4'd1,
S2=4'd2,
Wait="4"'d3,
R0=4'd8,
R0Temp=4'd9,
R1=4'd10,
R1Temp=4'd11,
R2=4'd12,
R2Temp=4'd13,
R3=4'd14,
R3Temp=4'd15;
reg [3:0] state;
reg [11:0] cnt; //2.048MHz,分频因子,分为1000Hz
always @(posedge clk)
cnt <= cnt==clkdiv ? 0 : cnt+1;
reg clken;
always @(posedge clk)
clken <= cnt==clkdiv;
always @(posedge clk) //键盘扫描部分
if(clken)
begin
case(state)
S0: //判断是否按键按下
begin
x<=4'b0000;
state="S1";
end
S1:
begin
if(y==4'b1111) //无按键,返回
state="S0";
else
x<=4'b0000;
repeat(204800) @(posedge clk); //延时100ms,消抖
state="S2";
end
S2:
begin
if(y==4'b1111)
state="S0";
else
state="R0Temp";
end
R0Temp: //扫描第一列
begin
x<=4'b1110;
state="R0";
end
R0:
case(y)
4'b1111:
state="R1Temp";
4'b0111:
begin
keyval<=5'd1;
state="Wait";
end
4'b1011:
begin
keyval<=5'd5;
state="Wait";
end
4'b1101:
begin
keyval<=5'd9;
state="Wait";
end
4'b1110:
begin
keyval<=5'd13;
state="Wait";
end
default:
state="Wait";
endcase
R1Temp: //扫描第二列
begin
x<=4'b1101;
state="R1";
end
R1:
case(y)
4'b1111:
state="R2Temp";
4'b0111:
begin
keyval<=5'd2;
state="Wait";
end
4'b1011:
begin
keyval<=5'd6;
state="Wait";
end
4'b1101:
begin
keyval<=5'd10;
state="Wait";
end
4'b1110:
begin
keyval<=5'd14;
state="Wait";
end
default:
state="Wait";
endcase
R2Temp: //扫描第三列
begin
x<=4'b1011;
state="R2";
end
R2:
case(y)
4'b1111:
state="R3Temp";
4'b0111:
begin
keyval<=5'd3;
state="Wait";
end
4'b1011:
begin
keyval<=5'd7;
state="Wait";
end
4'b1101:
begin
keyval<=5'd11;
state="Wait";
end
4'b1110:
begin
keyval<=5'd15;
state="Wait";
end
default:
state="Wait";
endcase
R3Temp: //扫描第四列
begin
x<=4'b0111;
state="R3";
end
R3:
case(y)
4'b1111:
state="Wait";
4'b0111:
begin
keyval<=5'd4;
state="Wait";
end
4'b1011:
begin
keyval<=5'd8;
state="Wait";
end
4'b1101:
begin
keyval<=5'd12;
state="Wait";
end
4'b1110:
begin
keyval<=5'd16;
state="Wait";
end
default:
state="Wait";
endcase
Wait: //返回S0状态
state="S0";
endcase
end
endmodule
用户53511 2008-2-21 14:34
谢谢你的建议,这是我初学的作品,各方面比较不成熟,希望多指教。
1、考虑到移植性,同意delay,更好。
2、这里的“S1”是从文件中张贴时不小心带上的,谢谢你细心的发现呀。
用户53511 2007-8-17 21:24
我用的是ateara的EPM7218,时钟是2.048MHz的,试验过没问题的。你检查一下硬件和引脚设置吧。
用户847144 2007-8-17 14:51
我怎么运行的时候有问题呢?/
有一列总是扫描不到