首页 > 技术 > 内容

矩阵键盘的verilog代码分享

时间:2026-01-12  作者:Diven  阅读:0

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

猜您喜欢


判断贴片电阻好坏,可以从以下几个方面入手:外观检查: 首先观察电阻表面是否有裂纹、烧焦痕迹、变形或缺损。焊盘是否完整,有无虚焊或脱焊现象。这些肉眼可见的缺陷都表...
2024-11-26 11:29:42
近年来,随着电动汽车、手机、笔记本电脑等电子产品的普及,电池作为这些设备的心脏,其重要性不言而喻。而电池管理系统 (Battery Management Sys...
2024-06-28 00:00:00
铝壳电阻因其优良的散热性能和稳定的电阻特性,应用于各种电子设备中。KOA(兴亚)作为知名的电阻制造商,其铝壳电阻产品因品质可靠、性能稳定而受到业界青睐。本文将详...
2015-04-27 20:32:12
追求更高效电子设备的道路上,同步整流驱动电路是很重要的配件。这种电路通过精确控制电流方向,最大限度地减少了能量损失,从而提升了整体效率。传统的二极管整流电路在电...
2024-03-28 00:00:00
保险丝作为保护电路的重要元件,其性能和规格受到关注。ZOYI LIGHTING作为知名的照明及电气配件制造商,其一次性保险丝产品因质量稳定、性能可靠而广受市场欢...
2024-10-12 05:46:30
通用胶水和胶棒因其出色的粘合性能和的适用性,成为日常生活和各种项目中不可少的工具。能够快速有效地粘合多种材料,包括纸张、木材、塑料和金属等,满足不同用户的需求。...
2011-05-31 00:00:00
贴片电阻1002,指的是尺寸为1.0mm x 0.25mm的矩形片状电阻器,以其微小的体积和稳定的性能,广泛应用于各种电子产品中。 「1002」代表其尺寸,其中...
2024-11-26 11:29:41
TO92是一种广泛应用于电子元件中的封装类型,因其结构简单、成本低廉以及良好的散热性能而受到许多电子工程师的青睐。TO92封装通常用于小功率晶体管、集成电路和其...
2025-02-24 14:17:38
TAIYO YUDEN(太阳诱电)作为一家知名的日本制造商,高质量和可靠性。其排阻产品应用于各种电子设备中,为电路提供稳定、可靠的电阻网络。本文将详细介绍TAI...
2017-04-10 08:06:30
合金电阻因其优异的稳定性和可靠性被应用于各种电子设备中。作为知名的合金电阻品牌,RALEC(旺诠)凭借其高品质和很好性能,赢得了众多用户的青睐。本文将围绕RAL...
2016-11-04 05:58:29