FPGA|CPLD|ASIC论坛
登录
直播中
chunfen2634
9年用户
184经验值
擅长:可编程逻辑
私信
关注
[资料]
明德扬至简设计法--分享一份实现矩阵键盘的verilog代码 可直接使用
矩阵键盘
verilog代码
`define SCAN
module key_scan(
clk ,
rst_n ,
key_col, //键盘列输入
key_row, //键盘行输出
key_num, //指示哪一个按键按下,用0~15指示
key_vld //按下有效指示信号,其为1表示按下一次。
);
parameter KEY_W = 4 ;
parameter COL = 0 ;
parameter ROW = 1 ;
parameter DLY = 2 ;
parameter FIN = 3 ;
parameter COL_CNT = 16;
parameter
ti
ME_20MS= 1000000;
//输入信号定义
input clk ;
input rst_n ;
input [3:0] key_col;
//输出信号定义
output key_vld;
output[3:0] key_num;
output[KEY_W-1:0] key_row;
//输出信号reg定义
reg [3:0] key_num;
reg [KEY_W-1:0] key_row;
reg key_vld;
reg [ 3:0] key_col_ff0 ;
reg [ 3:0] key_col_ff1 ;
reg [ 1:0] key_col_get ;
reg shake_flag ;
reg shake_flag_ff0;
reg [ 3:0] state_c ;
reg [19:0] shake_cnt ;
reg [ 3:0] state_n ;
reg [ 1:0] row_index ;
reg [15:0] row_cnt ;
reg [ 2:0] x ;
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
key_col_ff0 <= 4'b1111;
key_col_ff1 <= 4'b1111;
end
else begin
key_col_ff0 <= key_col ;
key_col_ff1 <= key_col_ff0;
end
end
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
shake_cnt <= 0;
end
else if(add_shake_cnt)begin
if(end_shake_cnt)
shake_cnt <= 0;
else
shake_cnt <= shake_cnt + 1;
end
else begin
shake_cnt <= 0;
end
end
assign add_shake_cnt = key_col_ff1!=4'hf && shake_flag==0;
assign end_shake_cnt = add_shake_cnt && shake_cnt==TIME_20MS-1;
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
shake_flag <= 0;
end
else if(end_shake_cnt) begin
shake_flag <= 1'b1;
end
else if(key_col_ff1==4'hf) begin
shake_flag <= 1'b0;
end
end
`ifdef SCAN
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
state_c <= COL;
end
else begin
state_c <= state_n;
end
end
always @(*)begin
case(state_c)
COL: begin
if(col2row_start)begin
state_n = ROW;
end
else begin
state_n = state_c;
end
end
ROW: begin
if(row2dly_start)begin
state_n = DLY;
end
else begin
state_n = state_c;
end
end
DLY : begin
if(dly2fin_start)begin
state_n = FIN;
end
else begin
state_n = state_c;
end
end
FIN: begin
if(fin2col_start)begin
state_n = COL;
end
else begin
state_n = state_c;
end
end
default: state_n = COL;
endcase
end
assign col2row_start = state_c==COL && end_shake_cnt;
assign row2dly_start = state_c==ROW && end_row_index;
assign dly2fin_start = state_c==DLY && end_row_index;
assign fin2col_start = state_c==FIN && key_col_ff1==4'hf;
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
key_row <= 4'b0;
end
else if(state_c==ROW)begin
key_row <= ~(1'b1 << row_index);
end
else begin
key_row <= 4'b0;
end
end
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
row_cnt <= 0;
end
else if(add_row_cnt) begin
if(end_row_cnt)
row_cnt <= 0;
else
row_cnt <= row_cnt + 1;
end
end
assign add_row_cnt = state_c==ROW || state_c==DLY;
assign end_row_cnt = add_row_cnt && row_cnt==COL_CNT-1;
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
row_index <= 0;
end
else if(add_row_index) begin
if(end_row_index)
row_index <= 0;
else
row_index <= row_index + 1;
end
end
assign add_row_index = end_row_cnt;
assign end_row_index = add_row_index && row_index==x-1;
always @(*)begin
if(state_c==ROW)
x = 4;
else
x = 1;
end
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
key_col_get <= 0;
end
else if(col2row_start) begin
if(key_col_ff1==4'b1110)
key_col_get <= 0;
else if(key_col_ff1==4'b1101)
key_col_get <= 1;
else if(key_col_ff1==4'b1011)
key_col_get <= 2;
else
key_col_get <= 3;
end
end
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
key_num <= 0;
end
else if(state_c==ROW && end_row_cnt)begin
key_num <= {row_index,key_col_get};
end
else begin
key_num <= 0;
end
end
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
key_vld <= 1'b0;
end
else if(state_c==ROW && end_row_cnt && key_col_ff1[key_col_get]==1'b0)begin
key_vld <= 1'b1;
end
else begin
key_vld <= 1'b0;
end
end
`else
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
key_vld <= 0;
end
else begin
key_vld <= end_shake_cnt;
end
end
always @(*)begin
key_num = 0;
end
`endif
endmodule
回帖
(2)
goodbey155
2017-3-1 09:56:47
谢谢分享,大好人!
谢谢分享,大好人!
举报
chunfen2634
2017-3-23 10:01:16
多谢通过!
多谢通过!
举报
更多回帖
rotate(-90deg);
回复
相关帖子
矩阵键盘
verilog代码
插值滤波器设计-
明德
扬
至
简
设计与应用FPGA
2019-08-16
1442
明德
扬
独创“
至
简
设计
法
”介绍
2019-07-25
1627
基于
至
简
设计
法
的数字时钟设计
2019-07-24
1445
基于
至
简
设计
法
实现
的PWM调制
verilog
2019-01-18
1875
基于
至
简
设计
法
实现
的红外接收
verilog
2017-11-05
1501
基于
至
简
设计
法
实现
的PWM调制
verilog
2017-09-27
4247
明德
扬
至
简
设计
法
资料大全
2017-07-27
3898
【潘文明
至
简
设计
法
】FPGA学习资料汇总,免费下载
2017-06-29
6474
【
明德
扬
】倾情分享海量FPGA设计技巧学习资料 转
2017-03-27
5278
基于
至
简
设计
法
的数字时钟设计
2017-02-15
3633
发帖
登录/注册
20万+
工程师都在用,
免费
PCB检查工具
无需安装、支持浏览器和手机在线查看、实时共享
查看
点击登录
登录更多精彩功能!
首页
论坛版块
小组
免费开发板试用
ebook
直播
搜索
登录
×
20
完善资料,
赚取积分