|
module key(
input clk,
input rst,
input [3:0] row, // 矩阵键盘 行
output reg [3:0] col, // 矩阵键盘 列
output reg [6:0] keyboard_val // 键盘值
);
//++++++++++++++++++++++++++++++++++++++
// 状态机部分 开始
//++++++++++++++++++++++++++++++++++++++
// 状态编码
parameter NO_KEY_PRESSED = 6'b000_001; // 没有按键按下
parameter SCAN_COL0 = 6'b000_010; // 扫描第0列
parameter SCAN_COL1 = 6'b000_100; // 扫描第1列
parameter SCAN_COL2 = 6'b001_000; // 扫描第2列
parameter SCAN_COL3 = 6'b010_000; // 扫描第3列
parameter KEY_PRESSED = 6'b100_000; // 有按键按下
//parameter delay = 6'b111_111; //延时5ms
reg [5:0] current_state, next_state; // 现态、次态
reg key_pressed_flag; // 键盘按下标志
reg [3:0] col_reg, row_reg; // 列值、行值
//reg delay_en; //延时5ms后使能端为1,否则为0
reg [11:0]c0;
//reg [5:0] temp_state;
reg clk0;
always @(posedge clk or negedge rst)
if(!rst)
current_state<=NO_KEY_PRESSED;
else
current_state<=next_state;
always @(posedge clk0)
begin
case(current_state)
NO_KEY_PRESSED:
if(row!=4'b1111) next_state=SCAN_COL0;
else begin next_state=NO_KEY_PRESSED;end
SCAN_COL0:
begin
if(row!=4'b1111)
next_state=KEY_PRESSED;
else next_state=SCAN_COL1;
end
SCAN_COL1:
begin
if(row!=4'b1111)
next_state=KEY_PRESSED;
else next_state=SCAN_COL2;
end
SCAN_COL2:
begin
if(row!=4'b1111)
next_state=KEY_PRESSED;
else next_state=SCAN_COL3;
end
SCAN_COL3:
begin
if(row!=4'b1111)
next_state=KEY_PRESSED;
else next_state=NO_KEY_PRESSED;
end
KEY_PRESSED:
if(row!=4'b1111)
next_state=KEY_PRESSED;
else next_state=NO_KEY_PRESSED;
default: next_state=NO_KEY_PRESSED;
endcase
end
always @ (posedge clk or negedge rst)
begin
if (!rst)
begin
col<= 4'b0000; key_pressed_flag<=0;
end
else
case(next_state)
NO_KEY_PRESSED:begin col=4'b0000;key_pressed_flag=0;end
SCAN_COL0: col=4'b1110;
SCAN_COL1: col=4'b1101;
SCAN_COL2: col=4'b1011;
SCAN_COL3: col=4'b0111;
KEY_PRESSED: begin
col_reg=col;row_reg=row;
key_pressed_flag=1;
end
endcase
end
always@(posedge clk0 or negedge rst) begin
if(!rst) keyboard_val<=7'b0000000;
else if(key_pressed_flag)
begin
case({col_reg,row_reg})
8'b1110_1110: keyboard_val=7'b1111110; //显示"0"
8'b1110_1101: keyboard_val=7'b0110011; //显示"4"
8'b1110_1011: keyboard_val=7'b1111111; //显示"8"
8'b1110_0111: keyboard_val=7'b1001110; //显示"C"
8'b1101_1110: keyboard_val=7'b0110000; //显示"1"
8'b1101_1101: keyboard_val=7'b1011011; //显示"5"
8'b1101_1011: keyboard_val=7'b1110011; //显示"9"
8'b1101_0110: keyboard_val=7'b0111101; //显示"d"
8'b1011_1110: keyboard_val=7'b1101101; //显示"2"
8'b1011_1101: keyboard_val=7'b1011111; //显示"6"
8'b1011_1011: keyboard_val=7'b1110111; //显示"A"
8'b1011_0111: keyboard_val=7'b1001111; //显示"E"
8'b0111_1110: keyboard_val=7'b1111001; //显示"3"
8'b0111_1101: keyboard_val=7'b1110000; //显示"7"
8'b0111_1011: keyboard_val=7'b0011111; //显示"b"
8'b0111_0111: keyboard_val=7'b1000111; //显示"F"
default: keyboard_val=7'b0000000;
endcase
end
end
always@(posedge clk)
if(c0<4000)
c0=c0+1;
else begin c0=0; clk0=~clk0;end
endmodule |
|