AC620FPGA学习笔记——矩阵键盘
UART
工程地址:https://github.com/HaHaHaHaHaGe/Planof2019_half/tree/master/Course_Project/FPGA/class07_keyboard
按下4*4矩阵键盘的任意一个按键,将结果通过串口返回给上位机(16bit)
(按键消抖部分使用之前所做的pushkey模块)
硬件结构
开发板:AC620
整体框架
引脚配置
与之前项目不同的是,此次需要使用内部上拉,否则在进行扫描时,4个输入引脚将被悬空
配置方法:
此图由于在截图的时候已经配置好了line_in的配置,一般情况下是空的
完成后即可配置完毕
代码部分
代码过多更多代码在github
顶层代码
module top(
clk,
rst,
tx,
rx,
line_in,
line_out
);
input clk,rst,rx;
input [3:0]line_in;
output[3:0]line_out;
output tx;
reg start;
wire busy;
reg [7:0]data;
reg rdreq;
reg wrreq;
wire empty,full;
wire [7:0]qout;
uart_tx uart_tx1(
.clk(clk),
.rst(rst),
.start(start),
.data(qout),
.busy(busy),
.tx(tx)
);
wire irq;
reg clr;
uart_rx uart_rx1(
.clk(clk),
.rst(rst),
.irq(irq),
.data(),
.rx(rx)
);
fifo fifo1 (
.clock(clk),
.data(data),
.rdreq(rdreq),
.wrreq(wrreq),
.empty(empty),
.full(full),
.q(qout)
);
wire [15:0]keyout;
reg [15:0]keyout2;
keyboard keyboard1(
.clk(clk),
.rst(rst),
.keyout(keyout),
.line_in(line_in),
.line_out(line_out),
);
reg [3:0]flag;
reg irq2;
reg [2:0]flag2;
[email protected](posedge clk,negedge rst)
if(!rst) begin
wrreq <= 0;
flag2 <= 0;
keyout2 <= 16'b0;
data <= 0;
end
else case(flag2)
0: if(keyout2 != keyout) begin flag2<=1; data <= keyout[15:8]; end
1: begin wrreq <= 1; flag2<=2; end
2: begin wrreq <= 0; flag2 <= 3; data <= keyout[7:0]; end
3: begin wrreq <= 1; flag2<=4; end
4: begin wrreq <= 0; keyout2<=keyout; flag2<=0;end
endcase
[email protected](posedge clk,negedge rst)
if(!rst) begin
start <= 1'b0;
clr <= 0;
flag <= 4'b0;
rdreq <= 0;
end
else
case(flag)
0: if(empty == 0) begin rdreq <= 1; flag <= 1; end else flag <= 0;
1: begin rdreq <= 0; flag <= 2; start <= 1; end
2: begin start <= 0; flag <= 3; end
3: if(busy == 0) flag <= 0;
endcase
endmodule
Keyboard
module keyboard(
clk,
rst,
keyout,
line_in,
line_out,
);
input clk,rst;
input [3:0]line_in;
output [15:0]keyout;
output reg [3:0]line_out;
reg [3:0]in_1;
reg [3:0]in_2;
reg [15:0]line_in_out;
pushkey pushkey1(
.clk(clk),
.key(line_in_out[0]),
.out(keyout[0])
);
pushkey pushkey2(
.clk(clk),
.key(line_in_out[1]),
.out(keyout[1])
);
pushkey pushkey3(
.clk(clk),
.key(line_in_out[2]),
.out(keyout[2])
);
pushkey pushkey4(
.clk(clk),
.key(line_in_out[3]),
.out(keyout[3])
);
pushkey pushkey5(
.clk(clk),
.key(line_in_out[4]),
.out(keyout[4])
);
pushkey pushkey6(
.clk(clk),
.key(line_in_out[5]),
.out(keyout[5])
);
pushkey pushkey7(
.clk(clk),
.key(line_in_out[6]),
.out(keyout[6])
);
pushkey pushkey8(
.clk(clk),
.key(line_in_out[7]),
.out(keyout[7])
);
pushkey pushkey9(
.clk(clk),
.key(line_in_out[8]),
.out(keyout[8])
);
pushkey pushkey10(
.clk(clk),
.key(line_in_out[9]),
.out(keyout[9])
);
pushkey pushkey11(
.clk(clk),
.key(line_in_out[10]),
.out(keyout[10])
);
pushkey pushkey12(
.clk(clk),
.key(line_in_out[11]),
.out(keyout[11])
);
pushkey pushkey13(
.clk(clk),
.key(line_in_out[12]),
.out(keyout[12])
);
pushkey pushkey14(
.clk(clk),
.key(line_in_out[13]),
.out(keyout[13])
);
pushkey pushkey15(
.clk(clk),
.key(line_in_out[14]),
.out(keyout[14])
);
pushkey pushkey16(
.clk(clk),
.key(line_in_out[15]),
.out(keyout[15])
);
[email protected](posedge clk,negedge rst)
if(!rst) begin
in_1 <= 4'b0;
in_2 <= 4'b0;
end
else begin
in_1 <= line_in;
in_2 <= in_1;
end
[email protected](posedge clk, negedge rst)
if(!rst) begin
line_in_out <= 15'b0;
line_out <= 4'b1110;
end
else begin
line_out <= {line_out[2:0],line_out[3]};
case(line_out)
4'b1110:line_in_out[3:0] <= in_2;
4'b1101:line_in_out[7:4] <= in_2;
4'b1011:line_in_out[11:8] <= in_2;
4'b0111:line_in_out[15:12] <= in_2;
default:line_out<=4'b1110;
endcase
end
endmodule