44
键盘扫描实验
实验目的
1、学习HDL程序的基本设计技巧;
2、掌握矩阵键盘的扫描原理和使用方法。
Verilog程序:
module hex_keypad(Col,Code,show,show1,count,scan,clock,Row); output[3:0] Code,Col,count; //定义列信号Col、行列信号共同决定的
输出代码Code、以及计数变量count output[7:0] show,show1; //定义七段显示变量show、show1 input[3:0] Row; //定义输入行信号Row
input scan; //定义数码管选择信号scan
input clock; //定义时钟信号clock
reg[3:0] Col,Code,count; //将输出信号定义为reg型
reg[7:0] show,show1;
reg[1:0] cn; //定义reg型变量cn,用于计数
reg reset,count_up,count_down; //定义变量reset用于计数清零,count_up
开始加计数,count_down开始减计数reg[15:0] times1,times2; //定义变量times1、times2用于决定开
始计数的时间
assign scan=1'b1; //将数码管选择信号赋值为1
always@(posedge clock) //产生列信号
if(cn==4)cn<=0; else
cn<=cn+1;
always@(cn)
case(cn)
2'b00:Col=4'b1110;
2'b01:Col=4'b1101;
2'b10:Col=4'b1011;
2'b11:Col=4'b0111;
endcase
always@(posedge clock) //行列信号共同决定输出代码Code case({Row,Col})
8'b1110_1110:Code=4'h0;
8'b1110_1101:Code=4'h1;
8'b1110_1011:Code=4'h2;
8'b1110_0111:Code=4'h3;
8'b1101_1110:Code=4'h4;
8'b1101_1101:Code=4'h5;
8'b1101_1011:Code=4'h6;
8'b1101_0111:Code=4'h7;
8'b1011_1110:Code=4'h8;
8'b1011_1101:Code=4'h9;
8'b1011_1011:Code=4'hA;
8'b1011_0111:Code=4'hB;
8'b0111_1110:Code=4'hC;
8'b0111_1101:Code=4'hD;
8'b0111_1011:Code=4'hE;
8'b0111_0111:Code=4'hF;
endcase
always@(posedge clock) //由输出Code决定数码管的显示,七段
用十六进制数表示
case(Code[3:0])
4'h0:show=8'hFC;
4'h1:show=8'h60;
4'h2:show=8'hDA;
4'h3:show=8'hF2;
4'h4:show=8'h66;
4'h5:show=8'hB6;
4'h6:show=8'h3E;
4'h7:show=8'hE0;
4'h8:show=8'hFE;
4'h9:show=8'hE6;
4'hA:show=8'hEE;
4'hB:show=8'hCE;
4'hC:show=8'h9C;
4'hD:show=8'h7A;
4'hE:show=8'h9E;
4'hF:show=8'h8E;
endcase
always@(posedge clock) //加减计数
case(Code)
4'h0:begin reset=1;count_up=0;count_down=0;end //按0键时清零4'hE:begin count_up=1;count_down=0;end //按E键加计数4'hF:begin count_down=1;count_up=0;end //按F键减计数default: begin count_down=0;count_up=0;reset=0; end //按其它键不计数endcase
always@(posedge clock)
if(times1==1000) times1<=101; else if (count_up) times1<=times1+1;
always@(posedge clock)
if(times2==1000) times2<=101; else if (count_down) times2<=times2+1; always@(posedge clock)
if(reset)count<=4'h0; else
if (times1>100&&Code==4'hE) //加计数
begin
count<=count+4'b1;
if (count==4'h9) count<=4'h0;
end
else
if (times2>100&&Code==4'hF) //减计数
begin
count<=count-4'b1;
if (count==4'h0) count<=4'h9;
end
always@(posedge clock) //计数显示
case(count[3:0])
4'h0:show1=8'hFC;
4'h1:show1=8'h60;
4'h2:show1=8'hDA;
4'h3:show1=8'hF2;
4'h4:show1=8'h66;
4'h5:show1=8'hB6;
4'h6:show1=8'h3E;
4'h7:show1=8'hE0;
4'h8:show1=8'hFE;
4'h9:show1=8'hE6;
endcase
endmodule
仿真波形:
Col、Row、Code、show、show[17..10]为十六进制显示,times1、times2、count为十进制显示
当Code为F(即按F键)时,show显示8E即F,表明此时按下的是F 键。
times2大于100时,count开始减计数。
当Code为E(即按E键),且times1大于100时开始加计数。
按其它键时保持,不计数。
按0键时清零。
对设计的分析:
在时钟控制下循环给出键盘扫描信号,根据列扫描信号和对应键盘响应信号确定键盘按键位置,直接对数码管给出相应的显示编码。
列扫描信号由变量cn控制,cn受时钟脉冲clock上升沿控制。
从00->01->10->11->00循环计数。
cn的四种状态决定了列扫描信号的四种状态: 1110->1101->1011->0111。
对应行信号的四种状态:1110->1101->1011->0111。
共同决定了Code的十六种状态,对应键盘上的十六个键,控制七段数码管的显示。
加减计数由变量由count_up和count_down控制。
变量count_up和count_down由键盘上的E键和F键控制。
长按E键或F键将开始计数。
开始计数后,按0键可以清零,按其它键可以使计数保持。
重按E键或F键开始加减计数。