全球最实用的IT互联网信息网站!

AI人工智能P2P分享&下载搜索网页发布信息网站地图

当前位置:诺佳网 > 电子/半导体 > 可编程逻辑 >

FPGA学习系列:26. 矩阵键盘的设计

时间:2018-08-09 10:47

人气:

作者:admin

标签: 仿真 

导读:设计背景: 矩阵键盘在工程设计越来越多的被用到,已然成为了我们做开发接触到的不可缺少的小型项目,利于我们理解设计方向的原理为以后的强化学习打好了坚实的基础。 设计原理...

设计背景:

矩阵键盘在工程设计越来越多的被用到,已然成为了我们做开发接触到的不可缺少的小型项目,利于我们理解设计方向的原理为以后的强化学习打好了坚实的基础。

设计原理:

在使用按键的时候,如果按键不多的话,我们可以直接按键与FPGA相连接,但是如果按键比较多的时候,如何还继续使用直接按键与FPGA相连接的话,所会大量增加FPGA端口的消耗,为了减少FPGA端口的消

耗,我们可以把按键设计成矩阵的形式,就如下图所示:

image.png

由上图可以知道,矩阵键盘的行row(行)与col(列)的交点,都是通过一个按键来相连接。传统的一个按键一个端口的方法,若要实现16个按键,则需要16个端口,而现在这个矩阵键盘的设计,16个按键,仅仅需要8个端口,如果使用16个端口来做矩阵键盘的话,可以识别64个按键,端口的利用率远远比传统的设计好的多,所以如果需要的按键少的话,可以选择传统的按键设计,如果需要的按键比较多的话,可以采用这种矩阵键盘的设计。而我们现在就以扫描法为例来介绍矩阵键盘的工作原理

首先col(列)是FPGA给矩阵键盘输出的扫描信号,而row(行)是矩阵键盘反馈给FPGA的输入信号,用于检测哪一个按键被按下来,如下图所示:

image.png

详细如上图所示,FPGA给出扫描信号COL[3:0]COL = 4’b0111,等下一个时钟周期COL = 4’b1011,再等下一个时钟周期COL =4’b1101,再等下一个时钟周期COL = 4’b1110,再等下一个时钟周期COL = 4’b0111COL就是这样不断循环,给矩阵键盘一个低电平有效的扫描信号,当FPGA给矩阵键盘COL扫描信号的同时,FPGA也要在检测矩阵键盘给FPGA的的反馈信号ROW,举个例子,假若矩阵键盘中的9号案件被按下了:

COL = 4’b1101ROW =4’b1011 ;

9号按键被按下的时候,9号按键的电路就会被导通,扫描电路COL开始扫描,当扫描到COL[1]的时候,由于9号按键的电路被导通了,COL[1]的电压等于ROW[2]的电压,所以会出现当COL = 4’b1101的时候ROW = 4’b1011;然后我们就可以利用这一种现象,来设计一个识别按键的电路。

设计架构图:

image.png

设计代码:

设计模块

0modulekey_borad(clk,rst_n,row,col,key_num);

1 inputclk;

2 inputrst_n;

3 input[3:0]row; //输入反馈信号

4

5

6 outputreg[3:0]col; //输出扫描信号

7 outputreg[3:0]key_num; //按键值得输除

8

9 reg[15:0]count;

10

11 parameterT1ms =50000;//扫描的时间间隔 50000 * 20ns

12 //parameter T1ms = 5;

13

14 regflag;

15 always@(posedgeclk ornegedgerst_n)

16 if(!rst_n)

17 begin

18 count <=16'd0;

19 flag <=1'b0;

20 end

21 else

22 begin

23 if(count <T1ms -1)//计数时间

24 begin

25 count <=count +1'b1;

26 flag <=0;

27 end

28 else

29 begin

30 flag <=1'b1;//计数到了就给一个标志位

31 count <=16'b0;

32 end

33 end

34 always@(posedgeclk ornegedgerst_n)

35 if(!rst_n)

36 begin

37 col <=4'b0111;

38 end

39 else

40 begin

41 if(flag)

42 col <={col[2:0],col[3]};//列扫描

43 else

44 col <=col;

45 end

46

47 //键值得翻译模块

48 always@(posedgeclk ornegedgerst_n)

49 if(!rst_n)

50 key_num =4'd0;

51 else

52 case({row,col}) //位拼接行和列的信号,翻译出对应的键值

53 8'b0111_0111:key_num =4'hf;

54 8'b0111_1011:key_num =4'he;

55 8'b0111_1101:key_num =4'hd;

56 8'b0111_1110:key_num =4'hc;

57

58 8'b1011_0111:key_num =4'hb;

59 8'b1011_1011:key_num =4'ha;

60 8'b1011_1101:key_num =4'h9;

61 8'b1011_1110:key_num =4'h8;

62

63 8'b1101_0111:key_num =4'h7;

64 8'b1101_1011:key_num =4'h6;

65 8'b1101_1101:key_num =4'h5;

66 8'b1101_1110:key_num =4'h4;

67

68 8'b1110_0111:key_num =4'h3;

69 8'b1110_1011:key_num =4'h2;

70 8'b1110_1101:key_num =4'h1;

71 8'b1110_1110:key_num =4'h0;

72 default:;

73 endcase

74endmodule

测试模块

0`timescale1ns/1ps

1

2modulekey_borad_tb();

3 regclk;

4 regrst_n;

5 reg[4:0]pressnum;//按键的值

6 wire[3:0]row;

7

8 wire[3:0]col;

9 wire[3:0]key_num;//输出的值

10

11 initialbegin

12 clk =1'b1;

13 rst_n =1'b0;

14 pressnum =5'd16;

15

16 #200.1

17 rst_n =1'b1;

18 #1000

19 pressnum =5'd16;

20

21 #1000

22 pressnum =5'd8;

23

24 #1000

25 pressnum =5'd16;

26

27 #1000

28 pressnum =5'd15;

29 #1000

30 pressnum =5'd16;

31 #1000

32 $stop;

33

34 end

35 always#10clk =~clk;

36 //例化对应的模块

37 key_top borad_dut(

38 .clk(clk),

39 .rst_n(rst_n),

40 .row(row),

41 .col(col),

42 .key_num(key_num)

43 );

44 yingjian yingjian_dut(//硬件检测电路 //此模块自己可以设计

45 .clk(clk),

46 .rst_n(rst_n),

47 .col(col),

48 .row(row),

49 .pressnum(pressnum)

50 );

51endmodule

仿真:

在仿真图中可以清晰的看出当按键按下的时候为8,显示出来的键值也为8,当抬起的时候为16,那么键值就保持不变,在设置的时候我们设置的是按键抬起为16,通过验证我们得到我们的设计是正确的。

温馨提示:以上内容整理于网络,仅供参考,如果对您有帮助,留下您的阅读感言吧!
相关阅读
本类排行
相关标签
本类推荐

CPU | 内存 | 硬盘 | 显卡 | 显示器 | 主板 | 电源 | 键鼠 | 网站地图

Copyright © 2025-2035 诺佳网 版权所有 备案号:赣ICP备2025066733号
本站资料均来源互联网收集整理,作品版权归作者所有,如果侵犯了您的版权,请跟我们联系。

关注微信