tear086 发表于 2010-2-20 00:21:33

矩阵键盘.[Verilog]

新近写的,水平有限,欢迎拍砖。

http://cache.amobbs.com/bbs_upload782111/files_26/ourdev_534322.png
(原文件名:矩阵键盘.png)


module matrixKeyboard_drive(
input            i_clk,
input            i_rst_n,
input       row,               // 矩阵键盘 行
output reg col,               // 矩阵键盘 列
output reg keyboard_val         // 键盘值   
);

//++++++++++++++++++++++++++++++++++++++
// 分频部分 开始
//++++++++++++++++++++++++++++++++++++++
reg cnt;                         // 计数子

always @ (posedge i_clk, negedge i_rst_n)
if (!i_rst_n)
    cnt <= 0;
else
    cnt <= cnt + 1'b1;

wire key_clk = cnt;                // (2^20/50M = 21)ms
//--------------------------------------
// 分频部分 结束
//--------------------------------------


//++++++++++++++++++++++++++++++++++++++
// 状态机部分 开始
//++++++++++++++++++++++++++++++++++++++
// 状态数较少,独热码编码
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;// 有按键按下

reg current_state, next_state;    // 现态、次态

always @ (posedge key_clk, negedge i_rst_n)
if (!i_rst_n)
    current_state <= NO_KEY_PRESSED;
else
    current_state <= next_state;

// 根据条件转移状态
always @ *
case (current_state)
    NO_KEY_PRESSED :                  // 没有按键按下
      if (row != 4'hF)
          next_state = SCAN_COL0;
      else
          next_state = NO_KEY_PRESSED;
    SCAN_COL0 :                         // 扫描第0列
      if (row != 4'hF)
          next_state = KEY_PRESSED;
      else
          next_state = SCAN_COL1;
    SCAN_COL1 :                         // 扫描第1列
      if (row != 4'hF)
          next_state = KEY_PRESSED;
      else
          next_state = SCAN_COL2;   
    SCAN_COL2 :                         // 扫描第2列
      if (row != 4'hF)
          next_state = KEY_PRESSED;
      else
          next_state = SCAN_COL3;
    SCAN_COL3 :                         // 扫描第3列
      if (row != 4'hF)
          next_state = KEY_PRESSED;
      else
          next_state = NO_KEY_PRESSED;
    KEY_PRESSED :                     // 有按键按下
      if (row != 4'hF)
          next_state = KEY_PRESSED;
      else
          next_state = NO_KEY_PRESSED;                     
endcase

reg       key_pressed_flag;             // 键盘按下标志
reg col_val, row_val;             // 列值、行值

// 根据次态,给相应寄存器赋值
always @ (posedge key_clk, negedge i_rst_n)
if (!i_rst_n)
begin
    col            <= 4'h0;
    key_pressed_flag <=    0;
end
else
    case (next_state)
      NO_KEY_PRESSED :                  // 没有按键按下
      begin
      col            <= 4'h0;
      key_pressed_flag <=    0;       // 清键盘按下标志
      end
      SCAN_COL0 :                     // 扫描第0列
      col <= 4'b1110;
      SCAN_COL1 :                     // 扫描第1列
      col <= 4'b1101;
      SCAN_COL2 :                     // 扫描第2列
      col <= 4'b1011;
      SCAN_COL3 :                     // 扫描第3列
      col <= 4'b0111;
      KEY_PRESSED :                     // 有按键按下
      begin
      col_val          <= col;      // 锁存列值
      row_val          <= row;      // 锁存行值
      key_pressed_flag <= 1;          // 置键盘按下标志
      end
    endcase
//--------------------------------------
// 状态机部分 结束
//--------------------------------------


   
//++++++++++++++++++++++++++++++++++++++
// 扫描行列值部分 开始
//++++++++++++++++++++++++++++++++++++++
always @ (posedge key_clk, negedge i_rst_n)
if (!i_rst_n)
    keyboard_val <= 4'h0;
else
    if (key_pressed_flag)
      case ({col_val, row_val})
      8'b1110_1110 : keyboard_val <= 4'h0;
      8'b1110_1101 : keyboard_val <= 4'h4;
      8'b1110_1011 : keyboard_val <= 4'h8;
      8'b1110_0111 : keyboard_val <= 4'hC;
      
      8'b1101_1110 : keyboard_val <= 4'h1;
      8'b1101_1101 : keyboard_val <= 4'h5;
      8'b1101_1011 : keyboard_val <= 4'h9;
      8'b1101_0111 : keyboard_val <= 4'hD;
      
      8'b1011_1110 : keyboard_val <= 4'h2;
      8'b1011_1101 : keyboard_val <= 4'h6;
      8'b1011_1011 : keyboard_val <= 4'hA;
      8'b1011_0111 : keyboard_val <= 4'hE;
      
      8'b0111_1110 : keyboard_val <= 4'h3;
      8'b0111_1101 : keyboard_val <= 4'h7;
      8'b0111_1011 : keyboard_val <= 4'hB;
      8'b0111_0111 : keyboard_val <= 4'hF;      
      endcase
//--------------------------------------
//扫描行列值部分 结束
//--------------------------------------
      
endmodule

http://cache.amobbs.com/bbs_upload782111/files_26/ourdev_534321.jpg
(原文件名:current_state.jpg)

tiky 发表于 2010-2-20 01:38:03

sofa,good!

abs123 发表于 2010-2-20 11:46:30

很好,要学习。

quzegang 发表于 2010-2-20 16:56:53

顶下

281229961 发表于 2010-2-27 10:49:06

顶啊

shiqing0477 发表于 2010-2-27 11:10:42

顶!!艾米电子!!

hwdpaley 发表于 2010-3-5 13:42:38

good,正需要呢!

sunjie718 发表于 2010-5-14 23:37:34

法规和加快

tear086 发表于 2010-7-23 12:32:58

./bbs_upload/files_31/ourdev_570182.png

shinehjx 发表于 2010-7-24 08:02:06

请教
列输出的脚是否要设为开漏型,如何设?
如果列是推挽输出型,同时按下多个键可能会有冲突,相当于列输出1和列输出0的线短接在一起

avrwoo 发表于 2010-7-24 10:02:20

mark

tear086 发表于 2010-7-24 11:28:17

回复【10楼】shinehjx
-----------------------------------------------------------------------

暂时没有考虑,不好意思。

STM_FPGA 发表于 2010-8-3 11:23:10

always @ (posedge i_clk, negedge i_rst_n)
if (!i_rst_n)
    cnt <= 0;
else
    cnt <= cnt + 1'b1;

wire key_clk = cnt;                // (2^20/50M = 21)ms

tear086 .COM 缺氧 ,这里怎么会是21ms呢??应该是(2^19/50M = 10)ms 吧?

jlqamark 发表于 2010-8-3 13:03:59

写的不错,10楼提的问题真是透彻

tear086 发表于 2010-8-3 18:13:43

回复【13楼】STM_FPGA
-----------------------------------------------------------------------

您再好好想想。

STM_FPGA 发表于 2010-8-3 19:45:36

回复【15楼】tear086 .COM 缺氧
--------------------------------------------------------
恩,对。粗心啦!

jeloc218 发表于 2010-9-29 17:05:29

顶一个

lyeerr 发表于 2010-12-16 21:08:38

always @ *
是什么意思啊?
每次执行都是列先输出,再行输入的么?这个时序能够保证么?

ibmx311 发表于 2010-12-17 00:10:14

正要用到,非常感谢

BINGSHUIHUO 发表于 2010-12-17 00:19:07

10楼提的问题真是透彻

hzm2008 发表于 2010-12-22 16:27:42

我觉得这个程序有问题,当行值为2时,进入第0列扫描时,就判断当前值是第2行第0列的值被按下了吗

jp19848 发表于 2010-12-23 21:27:10

mark

zhanggaiqing 发表于 2010-12-28 19:05:36

这个怎样与12864的液晶显示连在一起啊弄了好就了都没弄出来

loveBT 发表于 2010-12-29 21:56:12

mark

hbchf 发表于 2011-1-7 10:47:21

mark

ken_ly 发表于 2011-2-18 21:56:41

学习

jason0726 发表于 2011-2-24 23:47:51

正好要用到,可以参考

dengyaoan 发表于 2011-7-3 23:42:59

good参考 

0900820417 发表于 2011-10-27 19:35:59

哈哈哈哈,都是没有消抖的,哈哈哈哈哈

tongluren 发表于 2011-12-14 16:52:32

mark

skyxjh 发表于 2013-4-19 00:20:37

FPGA开漏输出怎么设置呢?怎么设置上拉输入?这样就可以翻转扫描矩阵键盘了。
页: [1]
查看完整版本: 矩阵键盘.[Verilog]