原创 【博客大赛】基于FPGA技术的键盘设计

2013-2-27 15:08 1827 16 20 分类: FPGA/CPLD 文集: FPGA

wps_clip_image-22530

wps_clip_image-18686

wps_clip_image-27660

2.2. 键盘工作简析

2.2.1. 工作流程

1) 默认:

Row[3:0]为输入,默认为4'b1111,因为电阻上拉

Col[3:0]为输出,默认输出4'b0000,保证按键按下时电流流向Col[3:0]

2) 当某一按键按下时,电流流向Col[x]=1,相应Row[x]=0

3) 通过循环Col键值扫描,代码如下:

    case(next_state)
    SCAN_IDLE    :    begin
                col_data <= 4'b0000;    //ensure current can flow when key is down
                row_data_r <= 4'b0000;
                col_data_r <= 4'b0000;
                end
    //SCAN_JITTER1:    
    SCAN_COL0    :    col_data <= 4'b1110;    //scan the 1th row if the key is down
    SCAN_COL1    :    col_data <= 4'b1101;    //scan the 2th row if the key is down
    SCAN_COL2    :    col_data <= 4'b1011;    //scan the 3th row if the key is down
    SCAN_COL3    :    col_data <= 4'b0111;    //scan the 4th row if the key is down
    SCAN_READ    :    begin
                row_data_r <= row_data;    //register the sudden col_data
                col_data_r <= col_data;    //register the sudden row_data
                end    
    //SCAN_JITTER2:
    default:;    //default vaule
    Endcase

当col_data为某一值的时候,若row_data!=4'b1111,则可确定是该列的键被按下!从而可以通过{row_data,col_data}来确定被按下的键。

1.1.1. 状态机

采用三段式状态机描述整个矩阵键盘的扫描状态控制,状态如下:

    parameter    SCAN_IDLE    =    3'd0;    表示初始化状态
    parameter    SCAN_JITTER1=    3'd1;    表示消抖动状态
    parameter    SCAN_COL0    =    3'd2;    表示Col0检测状态
    parameter    SCAN_COL1    =    3'd3;    表示Col1检测状态
    parameter    SCAN_COL2    =    3'd4;    表示Col2检测状态
    parameter    SCAN_COL3    =    3'd5;    表示Col3检测状态
    parameter    SCAN_READ    =    3'd6;    表示读取{Row[3:0],Col[3:0]}键值
    parameter    SCAN_JITTER2=    3'd7;    表示按键松手检测

其中消抖动为了简便,做了20ms状态检测计,如下:

    //---------------------------------------
    //generate for 20ms signal        
    localparam    KEY_DELAY = 20'hf_ffff;    //50MHz, 20ms    
    reg [19:0]    delay_cnt;    
    always @(posedge clk or negedge rst_n)
    begin
        if(!rst_n) 
            delay_cnt <= 0; 
        else if(delay_cnt < KEY_DELAY)    //(current_state == SCAN_JITTER1)
            delay_cnt <= delay_cnt + 1'b1;
        else
            delay_cnt <= 20'd0;
    end
    wire    delay_20ms = (delay_cnt == KEY_DELAY) ? 1'b1 : 1'b0;//key is down

状态机如下:

wps_clip_image-22801

1.1.1. 仿真图

通过testbench仿真,符合预期目标,结果如下:

wps_clip_image-31361

时序及编码

    case ({row_data_r, col_data_r})
    8'b0111_0111:    key_value <= 4'h0;
    8'b0111_1011:    key_value <= 4'h1;
    8'b0111_1101:    key_value <= 4'h2;
    8'b0111_1110:    key_value <= 4'h3;
                                 
    8'b1011_0111:    key_value <= 4'h4;
    8'b1011_1011:    key_value <= 4'h5;
    8'b1011_1101:    key_value <= 4'h6;
    8'b1011_1110:    key_value <= 4'h7;
                                 
    8'b1101_0111:    key_value <= 4'h8;
    8'b1101_1011:    key_value <= 4'h9;
    8'b1101_1101:    key_value <= 4'hA;
    8'b1101_1110:    key_value <= 4'hB;
                                             
    8'b1110_0111:    key_value <= 4'hC;
    8'b1110_1011:    key_value <= 4'hD;
    8'b1110_1101:    key_value <= 4'hE;
    8'b1110_1110:    key_value <= 4'hF;
    default        :    key_value <= key_value;        
    endcase

每次接受到key_flag一个触发的高电平,表示按键按下,可以直接读取键值,进行相应的操作!接口如下:

 

    //----------------------------------------------
    //the target component instantiation
    matrix_key_scan u_matrix_key_scan
    (
        .clk        (clk),      //global clock
        .rst_n        (rst_n),    //global reset
                                
        .row_data    (row_data),    //row data: pull-up with 3.3V    
        .col_data    (col_data),    //column data: for key scan
                                
        .key_flag    (key_flag), //the mark of key is pressed
        .key_value    (key_value)    //the returned value of matrix key
    );
 
PARTNER CONTENT

文章评论4条评论)

登录后参与讨论

用户516101 2013-10-13 15:48

完整的代码怎么看不到啊??

用户434882 2013-3-22 10:52

希望能给出testbench,方便检测

用户1587968 2013-3-5 21:27

很好,谢谢分享!

345002072_353389109 2013-3-2 18:53

博主做的挺好的,加油!

相关推荐阅读
wxg1988 2014-04-22 17:50
全球创客马拉松武汉站已经开始报名啦
星星之火,可以燎原! 全球创客马拉松在深圳、上海、北京、南京、成都等地相继点燃中国的创客之火,下一站:武汉! 改变世界,抑或改变自己,全球创客马拉松也许可以是梦想启航的地方。 英雄不问...
wxg1988 2013-10-24 13:15
液晶显示器原理LCD驱动基础
LCD显示器概述   ——》液晶显示器,LCD为英文 Liquid Crystal Display的缩写,它是一种数字显示技术,可以通过液晶和彩色过滤光源,并在平面面板上产生图像。  ...
wxg1988 2013-08-13 10:20
Arduino mini 亲手打造
Arduino,满足您创新创意的需要! Arduino 是一款便捷灵活、方便上手的开源电子原型平台,包含硬件(各种型号的Arduino板)和软件(Arduino IDE)。它适用于艺术家、设计...
wxg1988 2013-07-30 20:44
【博客大赛】STM32中断小结
  STM32中断EXTI STM32中断支持15个异常中断和240个外部中断,有256个中断优先级,其中I/O可配置为EXTI中断,捕捉外部信号,可配置为上升沿,下降沿,上升下降沿三种中...
wxg1988 2013-07-16 21:09
关注创客与开源电子,可以订阅
   http://list.qq.com/cgi-bin/qf_invite?id=04a0d177cb5a2dd6a4da786f024011139e353139950c4411 关注创客...
EE直播间
更多
我要评论
4
16
关闭 站长推荐上一条 /3 下一条