矩阵键盘的verilog代码分享

时间:2025-04-28  作者:Diven  阅读:0

define  SCAN

矩阵键盘的verilog代码分享

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      TIME_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

猜您喜欢

白板笔补充液的规格尺寸通常因品牌和类型而异,但市场上的补充液瓶容量大多在30毫升到100毫升之间。常见的瓶身设计为便于握持的圆形或方形,瓶口通常配有滴管或喷嘴,...
2009-08-10 00:00:00

铝单板作为现代建筑装饰的重要材料,因其轻质、高强度和优良的耐候性而应用于外立面、内墙和吊顶等多个领域。那么,铝单板的规格尺寸究竟是多少呢?一般而言,铝单板的标准...
2008-09-21 00:00:00

支架灯在现代家居和办公环境中是重要配件,但不同类型的支架灯有着各自的特点和适用场景。支架灯的光源类型各异。LED支架灯高效节能和长寿命受到欢迎,适合长时间使用;...
2014-03-19 00:00:00

科技日新月异的今天,电子设备性能不断提升,随之而来的是对散热技术更高的要求。作为热管理元器件领域的龙头企业,我们致力于提供高效、可靠的散热解决方案,为科技发展保...
2024-04-29 00:00:00

开发板简介TL6678ZH-EVM开发板基于TI KeyStone架构C6000系列TMS320C6678八核C66x定点/浮点DSP,以及Xilinx Zy...
2022-10-19 15:00:00

NTC热敏电阻(Negative Temperature Coefficient Thermistor)是一种对温度变化敏感的电子元件,应用于温度测量、温控系统...
2025-03-18 01:01:39

现代工业和电子设备中,连接器的选择非常重要。TERMINAL_6.2X30.94MM_TM作为一种高性能连接器,因其优越的性能和广泛的应用场景而受到关注。本文将...
2025-03-08 03:17:21

贴片电阻是现代电子元器件中重要的一部分,应用于各种电子设备中。其中,0402封装尺寸的贴片电阻小巧的体积和优良的性能,成为了许多电子设计师的首选。本文将对040...
2025-04-15 18:31:45

0603贴片电阻的耐压值并非一个固定值,而是根据具体型号和厂家的规格书而定。一般来说,常见的0603贴片电阻的耐压值在75V到150V之间。影响0603贴片电阻...
2024-11-26 11:29:18

现代科技飞速发展的今天,各种设备的配件越来越受到用户的关注。特别是在工业和电子设备领域,优质的配件不仅能提升设备的性能,还能延长其使用寿命。本文将重点介绍“Ac...
2025-03-05 09:26:23