zoukankan      html  css  js  c++  java
  • 基于FPGA的按键扫描程序

    最近在学习FPGA,就试着写了个按键扫描的程序。虽说有过基于单片机的按键扫描处理经验,对于按键的处理还是有一些概念。
    但是单片机程序的编写通常都采用C写,也有用汇编,而FPGA却是采用VHDL或者Verilog这种硬件描述语言来编写。初次利用VHDL编写
    控制程序,最开始就有点反应不过来了。采用VHDL语言编写程序与用C语言编写,在思维上会有很大的不一样,因为C程序时顺序执行的,而VHDL语言
    各个进程之间是并行执行的,这就会要考虑到时序方面的问题,这正也合乎了硬件工作实际过程,毕竟各个功能模块之间既独立又相关的嘛。
    说回基于FPGA的按键扫描处理的问题,通常对按键的处理都要进行延时去抖,以避免按键按下产生的机械抖动等因素影响对按键状态的正确判决。
    而且除了要扫描判断按键是否按下,也要扫描判断按键是否弹开(否则一次按键按下如果时间相对长一些,那么程序很容易会误认为连续多次按下)。
    基于以上分析,下面是我整理了一下用VHDL语言编写的扫描代码,程序实现按键单击,双击,长按的判断处理。(程序中时钟对应50MHZ,根据不同的主时钟对分频应做相应的修改)

    ----------------------------------------------------------------------------------
    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    use IEEE.STD_LOGIC_unsigned.ALL;
    -- Uncomment the following library declaration if using
    -- arithmetic functions with Signed or Unsigned values
    --use IEEE.NUMERIC_STD.ALL;

    -- Uncomment the following library declaration if instantiating
    -- any Xilinx primitives in this code.
    --library UNISIM;
    --use UNISIM.VComponents.all;

    entity key is
    port(key_state:in BIT;--按键转态,1->按下,0->未按下
    clk:in std_logic;
    mode1,mode2:out integer range 0 to 2;
    q:out integer range 0 to 2
    );
    end key;
    architecture Behavioral of key is
    signal cntDiv: std_logic_vector(28 downto 0);
    signal key_count,up_key:integer range 0 to 200000;
    signal twit_count:integer range 0 to 3;--用于判断是否为双击状态
    signal flag_state:integer range 0 to 1;--用于判断是否有按键按下以及按下一次还是连续两次按下

    type state is (short_key,long_key,twis_key);--no_key,
    signal pr_state:state;
    --signal LONG_KEY,TWICE_KEY:integer range 0 to 1000;
    begin
    process(clk)
    begin
    if(clk'event and clk = '1')then
    cntDiv <= cntDiv + '1';
    end if;
    end process;
    process(cntDiv(7),key_state)
    variable flag1,flag2:integer range 0 to 2;------------用于区分短按以及长按的各自不同功能
    ------------flag1=0/1 => 功能1/功能2;
    ------------flag2=0/1 => 功能3/功能4;
    begin
    if(cntDiv(7)'event and cntDiv(7) = '1')then
    if(key_state = '1')then
    key_count <= key_count +1;
    up_key <= 0;
    flag_state <= 1;
    else
    if(key_count > 20 and key_count < 50000)then
    twit_count <= twit_count + 1; --判断是否长按的标志
    key_count <= 0;
    elsif(key_count > 50000)then --------------长按
    pr_state <= long_key;
    key_count <= 0;
    up_key <= 0;
    flag_state <= 0;
    --////////////根据设计需要添加的代码//////////////////
    --代码......................
    ------------------------------------------------
    else
    key_count <= 0;
    end if;
    -------双击,up_key为按键跳起至下一次按下持续时间
    if(up_key > 20 and up_key < 50000 and twit_count = 2 )then pr_state <=twis_key;
    flag_state <= 0;
    up_key <= 0;
    twit_count <= 0;
    flag2 := flag2 +1;
    if(flag2 = 2)then flag2 :=0;
    end if;
    mode2 <= flag2;
    --////////////根据设计需要添加的代码//////////////////
    --代码......................
    ------------------------------------------------
    end if;
    if(up_key > 50000 and twit_count = 1)then --短按
    pr_state <= short_key;
    flag_state <= 0;
    up_key <= 0;
    twit_count <= 0;
    flag1 := flag1 +1;
    if(flag1 = 2)then flag1 :=0;end if;
    --////////////根据设计需要添加的代码//////////////////
    --代码......................
    ------------------------------------------------
    end if;
    if(flag_state = 1)then
    up_key <= up_key + 1;
    end if;
    end if;
    end if;
    end process;
    process(pr_state)
    --variable flag1,flag2:integer range 0 to 2;
    begin
    case pr_state is
    when short_key => q <= 0;------短按返回结果标志
    when long_key => q <= 1;------长按结果标志
    when twis_key => q <= 2;------双击结果标志
    end case;
    end process;
    end Behavioral;

  • 相关阅读:
    Bootstrap入门(二十五)JS插件2:过渡效果
    Bootstrap入门(二十四)data属性
    Bootstrap入门(二十三)JS插件1:模态框
    Bootstrap入门(二十二)组件16:列表组
    Bootstrap入门(二十一)组件15:警告框
    Bootstrap入门(二十)组件14:警告框
    Bootstrap入门(十九)组件13:页头与缩略图
    git 上传本地代码到github 服务器
    Dropzone.js实现文件拖拽上传
    将复杂form表单序列化serialize-object.js
  • 原文地址:https://www.cnblogs.com/jiandahao/p/4670996.html
Copyright © 2011-2022 走看看