基于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;

时间: 2024-07-30 10:07:22

基于FPGA的按键扫描程序的相关文章

关于按键扫描程序的终极讨论

一.思路 基于STM8,按键处理,思路是这样的: 每20ms左右一次去扫描按键,用一个key_now记录当前值,用key_last记录上次的值,如果key_now和key_last同时有效,则开始进行cnt++. 我设定两个阈值,LONG_PRESS为100(100*20ms=2s),SHORT_PRESS为4(4*20ms=80ms,去抖). cnt大于LONG_PRESS,表示是长按,反之再判断cnt是不是大于SHORT_PRESS,表示是短按,否则把cnt清零. 另外一种情况,我们在设置参

基于状态机的按键扫描的实现

一般的按键输入软件接口程序非常简单,在程序中一旦检测到按键输入口为低电平(有时可能为高),便采用软件延时的方 法来进行消抖,然后再次检测按键输入,如果再次确认为低电平则表示有按键按下,转入执行按键处理程序.如果延时后检测的电平为高电平则放弃本次按键检测, 重新开始一次按键检测过程.在简单的系统中这种方法比较可以用,但是在复杂的系统实时性要求较高的系统中这种方法的CPU利用率比较低,造成资源的浪费. 另外,由于在不同的产品系统中对按键功能的定义和使用方式也会不同,而且是多变的,加上在测试和按键处理

新型的按键扫描程序

不过我在网上游逛了很久,也看过不少源程序了,没有发现这种按键处理办法的踪迹,所以,我将他共享出来,和广大同僚们共勉.我非常坚信这种按键处理办法的便捷和高效,你可以移植到任何一种嵌入式处理器上面,因为C语言强大的可移植性. 同时,这里面用到了一些分层的思想,在单片机当中也是相当有用的,也是本文的另外一个重点. 对于老鸟,我建议直接看那两个表达式,然后自己想想就会懂的了,也不需要听我后面的自吹自擂了,我可没有班门弄斧的意思,hoho--但是对于新手,我建议将全文看完.因为这是实际项目中总结出来的经验

单片机按键扫描程序,仅三行代码(转)

以下假设你懂C语言,因为纯粹的C语言描述,所以和处理器平台无关,你可以在MCS-51,AVR,PIC,甚至是ARM平台上面测试这个程序性能.当然,我自己也是在多个项目用过,效果非常好的.      好了,工程人员的习惯,废话就应该少说,开始吧.以下我以AVR的MEGA8作为平台讲解,没有其它原因,因为我手头上只有AVR的板子而已没有51的.用51也可以,只是芯片初始化部分不同,还有寄存器名字不同而已.核心算法:unsigned char Trg;unsigned char Cont;void K

4*4键盘扫描程序--去抖加长按

前阵子做的是一个叫精密电压源的项目,使用了4*4的键盘,使用了8个GPIO,是比较简单的做法了,之前在网上看到一个老外已经能用3个GPIO实现多达25个按键的控制了,对应的接线图如下 使用的是新塘某Cortex-M0单片机,(讲真,单片机这部分虽然我水平不行但是我是写腻了),从网上找了些按键扫描程序又结合当前的项目写了一个按键扫描的程序,不用延迟来去抖,也可以添加长按功能,废话不多说,直接上代码 uint8_t b_key_scan;uint8_t b_key_debounce;uint8_t

基于FPGA的飞机的小游戏

基于FPGA的飞机的小游戏 实验原理 ????该实验主要分为4个模块,采用至上而下的设计方法进行设计.由50M的晶振电路提供时钟源,VGA显示控制模块.图形显示控制模块.移动模块的时钟为25M,由时钟分频电路产生获得.时钟分频模块采用PLL进行设计,由50M时钟进行2分频获得25M时钟. ????移动模块,控制我方飞机和敌方飞机.子弹的移动,移动的速度可以通过时钟的频率进行控制,操作我方飞机的移动和子弹的发射由外部按键进行控制,控制的方式有发射子弹.左移.右移. ????图像显示控制模块,用于控

基于FPGA的图像开发平台 其他摄像头附件说明(OV5642 OV9655)

基于FPGA的图像开发平台 其他摄像头附件说明 FPGA_VIP_V101 编者 奇迹再现 个人博客 http://www.cnblogs.com/ccjt/ 联系邮箱 [email protected] 淘宝网址 http://ccjt.taobao.com 修订记录 见下页 版权归奇迹再现所有,抄袭请注明出处, 参考文献:CrazyBingo原创相关文档.请尊重原创. 前言: 本系统方案理论适合DVP绝大部分摄像头测试,调试及开发,针对其他摄像头,因为寄存器参数不同,需要进行相应移植. 目前

基于FPGA的Sobel边缘检测的实现

前面我们实现了使用PC端上位机串口发送图像数据到VGA显示,通过MATLAB处理的图像数据直接是灰度图像,后面我们在此基础上修改,从而实现,基于FPGA的动态图片的Sobel边缘检测.中值滤波.Canny算子边缘检测.腐蚀和膨胀等.那么这篇文章我们将来实现基于FPGA的Sobel边缘检测. 图像边缘:简言之,边缘就是图像灰度值突变的地方,亦即图像在该部分的像素值变化速度非常之快,这就好比在坐标轴上一条曲线有刚开始的平滑突然来个大转弯,在变化出的导数非常大. Sobel算子主要用作边缘检测,在技术

基于FPGA的均值滤波算法实现

我们为了实现动态图像的滤波算法,用串口发送图像数据到FPGA开发板,经FPGA进行图像处理算法后,动态显示到VGA显示屏上,前面我们把硬件平台已经搭建完成了,后面我们将利用这个硬件基础平台上来实现基于FPGA的一系列图像处理基础算法. 椒盐噪声(salt & pepper noise)是数字图像的一个常见噪声,所谓椒盐,椒就是黑,盐就是白,椒盐噪声就是在图像上随机出现黑色白色的像素.椒盐噪声是一种因为信号脉冲强度引起的噪声,产生清楚该噪声的算法也比较简单. 均值滤波的方法将数据存储成3x3的矩阵