[资料] 明德扬至简设计法--分享一份实现矩阵键盘的verilog代码 可直接使用

[复制链接]

技术员

发表于 2017-2-21 11:31:32   438 查看 2 回复 显示全部楼层 倒序浏览
分享
  1. `define  SCAN

  2. module  key_scan(
  3.                  clk    ,
  4.                  rst_n  ,
  5.                  key_col, //键盘列输入
  6.                  key_row, //键盘行输出
  7.                  key_num, //指示哪一个按键按下,用0~15指示
  8.                  key_vld  //按下有效指示信号,其为1表示按下一次。
  9.                );


  10.     parameter      KEY_W    =   4 ;
  11.     parameter      COL      =   0 ;
  12.     parameter      ROW      =   1 ;
  13.     parameter      DLY      =   2 ;
  14.     parameter      FIN      =   3 ;
  15.     parameter      COL_CNT  =   16;
  16.     parameter      TIME_20MS=   1000000;

  17.     //输入信号定义
  18.     input               clk    ;
  19.     input               rst_n  ;
  20.     input  [3:0]        key_col;

  21.     //输出信号定义
  22.     output              key_vld;
  23.     output[3:0]         key_num;
  24.     output[KEY_W-1:0]   key_row;

  25.     //输出信号reg定义
  26.     reg   [3:0]         key_num;
  27.     reg   [KEY_W-1:0]   key_row;
  28.     reg                 key_vld;


  29.     reg   [ 3:0]        key_col_ff0   ;
  30.     reg   [ 3:0]        key_col_ff1   ;
  31.     reg   [ 1:0]        key_col_get   ;
  32.     reg                 shake_flag    ;
  33.     reg                 shake_flag_ff0;
  34.     reg   [ 3:0]        state_c       ;
  35.     reg   [19:0]        shake_cnt     ;
  36.     reg   [ 3:0]        state_n       ;
  37.     reg   [ 1:0]        row_index     ;
  38.     reg   [15:0]        row_cnt       ;
  39.         reg   [ 2:0]        x             ;


  40. always  @(posedge clk or negedge rst_n)begin
  41.     if(rst_n==1'b0)begin
  42.         key_col_ff0 <= 4'b1111;
  43.         key_col_ff1 <= 4'b1111;
  44.     end
  45.     else begin
  46.         key_col_ff0 <= key_col    ;
  47.         key_col_ff1 <= key_col_ff0;
  48.     end
  49. end


  50. always  @(posedge clk or negedge rst_n)begin
  51.     if(rst_n==1'b0)begin
  52.         shake_cnt <= 0;
  53.     end
  54.     else if(add_shake_cnt)begin
  55.         if(end_shake_cnt)
  56.             shake_cnt <= 0;
  57.         else
  58.             shake_cnt <= shake_cnt + 1;
  59.     end
  60.     else begin
  61.         shake_cnt <= 0;
  62.     end
  63. end

  64. assign  add_shake_cnt = key_col_ff1!=4'hf && shake_flag==0;
  65. assign  end_shake_cnt = add_shake_cnt && shake_cnt==TIME_20MS-1;

  66. always  @(posedge clk or negedge rst_n)begin
  67.     if(rst_n==1'b0)begin
  68.         shake_flag <= 0;
  69.     end
  70.     else if(end_shake_cnt) begin
  71.         shake_flag <= 1'b1;
  72.     end
  73.     else if(key_col_ff1==4'hf) begin
  74.         shake_flag <= 1'b0;
  75.     end
  76. end


  77. `ifdef SCAN
  78. always  @(posedge clk or negedge rst_n)begin
  79.     if(rst_n==1'b0)begin
  80.         state_c <= COL;
  81.     end
  82.     else begin
  83.         state_c <= state_n;
  84.     end
  85. end



  86. always  @(*)begin
  87.     case(state_c)
  88.         COL: begin
  89.                      if(col2row_start)begin
  90.                          state_n = ROW;
  91.                      end
  92.                      else begin
  93.                          state_n = state_c;
  94.                      end
  95.                  end
  96.         ROW: begin
  97.                      if(row2dly_start)begin
  98.                          state_n = DLY;
  99.                      end
  100.                      else begin
  101.                          state_n = state_c;
  102.                      end
  103.                  end
  104.         DLY :  begin
  105.                      if(dly2fin_start)begin
  106.                          state_n = FIN;
  107.                      end
  108.                      else begin
  109.                          state_n = state_c;
  110.                      end
  111.                  end
  112.         FIN: begin
  113.                      if(fin2col_start)begin
  114.                          state_n = COL;
  115.                      end
  116.                      else begin
  117.                          state_n = state_c;
  118.                      end
  119.                   end
  120.        default: state_n = COL;
  121.     endcase
  122. end

  123. assign  col2row_start = state_c==COL && end_shake_cnt;
  124. assign  row2dly_start = state_c==ROW && end_row_index;
  125. assign  dly2fin_start = state_c==DLY && end_row_index;
  126. assign  fin2col_start = state_c==FIN && key_col_ff1==4'hf;





  127. always  @(posedge clk or negedge rst_n)begin
  128.     if(rst_n==1'b0)begin
  129.         key_row <= 4'b0;
  130.     end
  131.     else if(state_c==ROW)begin
  132.         key_row <= ~(1'b1 << row_index);
  133.     end
  134.     else begin
  135.         key_row <= 4'b0;
  136.     end
  137. end


  138. always  @(posedge clk or negedge rst_n)begin
  139.     if(rst_n==1'b0)begin
  140.         row_cnt <= 0;
  141.     end
  142.     else if(add_row_cnt) begin
  143.         if(end_row_cnt)
  144.             row_cnt <= 0;
  145.         else
  146.             row_cnt <= row_cnt + 1;
  147.     end
  148. end
  149. assign add_row_cnt = state_c==ROW || state_c==DLY;
  150. assign end_row_cnt = add_row_cnt && row_cnt==COL_CNT-1;


  151. always  @(posedge clk or negedge rst_n)begin
  152.     if(rst_n==1'b0)begin
  153.         row_index <= 0;
  154.     end
  155.     else if(add_row_index) begin
  156.         if(end_row_index)
  157.             row_index <= 0;
  158.         else
  159.             row_index <= row_index + 1;
  160.     end
  161. end
  162. assign add_row_index = end_row_cnt;
  163. assign end_row_index = add_row_index && row_index==x-1;
  164. always  @(*)begin
  165.     if(state_c==ROW)
  166.         x = 4;
  167.     else
  168.         x = 1;
  169. end


  170. always  @(posedge clk or negedge rst_n)begin
  171.     if(rst_n==1'b0)begin
  172.         key_col_get <= 0;
  173.     end
  174.     else if(col2row_start) begin
  175.         if(key_col_ff1==4'b1110)
  176.             key_col_get <= 0;
  177.         else if(key_col_ff1==4'b1101)
  178.             key_col_get <= 1;
  179.         else if(key_col_ff1==4'b1011)
  180.             key_col_get <= 2;
  181.         else
  182.             key_col_get <= 3;
  183.     end
  184. end


  185. always  @(posedge clk or negedge rst_n)begin
  186.     if(rst_n==1'b0)begin
  187.         key_num <= 0;
  188.     end
  189.     else if(state_c==ROW && end_row_cnt)begin
  190.         key_num <= {row_index,key_col_get};
  191.     end
  192.     else begin
  193.         key_num <= 0;
  194.     end
  195. end

  196. always  @(posedge clk or negedge rst_n)begin
  197.     if(rst_n==1'b0)begin
  198.         key_vld <= 1'b0;
  199.     end
  200.     else if(state_c==ROW && end_row_cnt && key_col_ff1[key_col_get]==1'b0)begin
  201.         key_vld <= 1'b1;
  202.     end
  203.     else begin
  204.         key_vld <= 1'b0;
  205.     end
  206. end

  207. `else
  208.     always  @(posedge clk or negedge rst_n)begin
  209.         if(rst_n==1'b0)begin
  210.             key_vld <= 0;
  211.         end
  212.         else begin
  213.             key_vld <= end_shake_cnt;
  214.         end
  215.     end

  216.     always  @(*)begin
  217.         key_num = 0;
  218.     end



  219. `endif

  220. endmodule
复制代码


技术员

发表于 2017-3-1 09:56:47  
谢谢分享,大好人!
回复

点赞 举报

技术员

发表于 2017-3-23 10:01:16    楼主|

PCB在线计价下单

板子大小:

cm
X
cm

层数:

2

板子数量:

10

厚度:

1.6
多谢通过!
回复

举报

高级模式
您需要登录后才可以回帖 登录 | 注册

关闭

站长推荐 上一条 /7 下一条

快速回复 返回顶部 返回列表
-

推荐专区

技术干货集中营

专家问答

用户帮助┃咨询与建议┃版主议事

我的提问

工程师杂谈

工程师创意

工程师职场

论坛电子赛事

社区活动专版

发烧友活动

-

嵌入式论坛

ARM技术论坛

Android论坛

Linux论坛

单片机/MCU论坛

FPGA|CPLD|ASIC论坛

DSP论坛

嵌入式系统论坛

-

电源技术论坛

电源技术论坛

无线充电技术

-

硬件设计论坛

PCB设计论坛

电路设计论坛

电子元器件论坛

控制|传感

总线技术|接口技术

-

测试测量论坛

LabVIEW论坛

Matlab论坛

测试测量技术专区

仪器仪表技术专区

-

EDA设计论坛

multisim论坛

PADS技术论坛

Protel|AD|DXP论坛

Allegro论坛

proteus论坛|仿真论坛

EasyEDA-中国人自已的EDA工具

Orcad论坛

-

综合技术与应用

电机控制

智能电网

光电及显示

参考设计中心

汽车电子技术论坛

医疗电子论坛

-

开源硬件

DFRobot专区

树莓派论坛

智能硬件论坛

开发快智能硬件开发平台

Intel物联网开发者专区

Waveshare

乐美客SBC专区

Arduino论坛

BeagleBone论坛

机器人论坛

创客神器NanoPi

小钢炮CANNON

比派科技banana pi专区

-

无线通信论坛

无线通信技术专区

天线|RF射频|微波|雷达技术

-

IC设计论坛

芯片测试与失效分析

Mixed Signal/SOC[数模混合芯片设计]

Analog/RF IC设计

设计与制造封装测试

-

个人版区

阿东Verilog技术专版

直流马达驱动电路设计

LabVIEW英雄联盟

特权同学FPGA专区

-

厂商专区

灵动微电子 MM32

盈鹏飞嵌入式

TI论坛

TI Deyisupport社区

芯灵思嵌入式论坛

Tisan

米尔科技

庆科社区

WIZnet技术专区

Cypress技术论坛

飞凌嵌入式

Qualcomm技术论坛

英创嵌入式

机智云GoKit论坛

-

检测技术与质量

电磁兼容(EMC)设计与整改

安规知识论坛

检测与认证

-

消费电子论坛

手机技术论坛

平板电脑/mid论坛

音视/视频/机顶盒论坛

-

电子论坛综合区

聚丰众筹官方社区

新人报道区

聚丰供应链

-

论坛服务区

-

供求信息发布

供需广告

招聘┃求职发布区

电子展览展会专区