0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如何设计一个实用的按键模块

FPGA之家 来源:FPGA之家 作者:FPGA之家 2022-09-05 09:19 次阅读

一.简介

这是FPGA之旅的第二个设计实例了,按键在项目中的作用是非常大的,使用的很频繁,本例将带大家设计一个实用的按键模块。

二. 按键电路

按键为输入设备,通过电路图可以知道,当按键按下的时候,FPGA会检测到低电平,按键没有按下的时候,FPGA检测到的是高电平。

e32b1824-2cad-11ed-ba43-dac502259ad0.png

三. Verilog代码编写

直接来一段最简单的按键检测的代码编写,都不用仿真

按键按下,LED灯状态取反。

module KEY(  input    clk,    input    rst_n,    input    key,    output  reg  led);    always@(posedge clk or negedge rst_n)    begin        if(rst_n == 1'b0)             led <= 1'b0;        else if(key == 1'b0)            led <= ~led;        else            led <= led;    endendmodule 

当按键按下后,LED的状态取反,这个在仿真的时候是可以看到变化的,但是实际上板测试的话,是没有效果的,因为clk的时钟周期一般为20ns,每次按键按下的持续时间可以达到ms以上,所以LED会多次取反,所以这么简单粗暴是不可以的,需要我们做一些额外处理。此外在按键按下的瞬间,电平会出现不稳定的情况,也需要进行处理。解决这些问题,正是这个例程的重点。

四. 解决方案设计

按键按下的时候,一共有两个问题

电平不稳定

短时间内重复检测

第一个问题可以通过按键消抖来解决,第二个问题,可以在按键消抖的基础上,增加一些判断来解决,于是就有了以下三种模式

模式一,按下生效,释放,算一次

模式二,按下,释放生效,算一次

模式三,按下,一段时间算一次

这里通过状态机的方式来实现,第一步就是要分析一共有几个状态。

空闲态:按键没有按下时,所处的状态。

消抖态: 按键按下后,进入消抖态,在此期间,如果按键释放了的话,回到空闲态,否则进入延时态。

延时态:延时,直到按键释放。

释放态:按键释放,回归到空闲态。

模式一,可以在消抖态完成后,生效。

模式二,可以在释放态,生效。

模式三,可以在延时态,生效。

完美,这不就全部都解决了嘛! 代码如下。

//按键消抖module btn_dis_shake(        input      clk,  input      rst_n,    input      ikey,        //按键输入outputokey//按键输出);//模式//0   按下生效,抬起,算一次//1   按下抬起,算一次//2  按下后,一段时间算一次parameter      mode = 2;
localparam      S_IDLE    =    'd0;localparam      S_DIS_SHAKE =       'd1;localparam      S_DEALY    =    'd2;localparam      S_UP    =    'd3;
localparam      DIS_SHAKE  =  'd6000;    //消抖延时localparam      DELAY    =  'd50000;  //模式2中,一段时间
reg[3:0] state  ,  next_state;
wire neg_key,pos_key;  //按键下降沿上升沿reg   key0,key1;      //按键状态储存
reg[30:0]  delay_cnt;
assign    neg_key =  key1 & (~key0);    //判断按键信号的下降沿assignpos_key=(~key1)&key0;//判断按键信号的上升沿//根据模式来判断按键输出assignokey=(mode==0&&state==S_DIS_SHAKE&&delay_cnt==DIS_SHAKE)?1'b1:(mode==1&&state==S_UP)?1'b1:(mode==2&&state==S_DEALY&&delay_cnt==DELAY)?1'b1:1'b0;always@(posedge clk or negedge rst_n)begin  if(rst_n  == 1'b0)  begin      key0 <= 1'b1;      key1 <= 1'b1;  end  else  begin    key0 <= ikey;    key1 <= key0;  endendalways@(posedge clk or negedge rst_n)begin  if(rst_n == 1'b0)    state <= S_IDLE;  else    state <= next_state;end
always@(*)begin  case(state)    S_IDLE:      if(neg_key  ==  1'b1)        next_state <= S_DIS_SHAKE;      else        next_state <= S_IDLE;    S_DIS_SHAKE:      //按下消抖        if(delay_cnt == DIS_SHAKE)          next_state <= S_DEALY;        else if(pos_key == 1'b1)          next_state <= S_IDLE;        else          next_state <= S_DIS_SHAKE;    S_DEALY:      //延时      if(delay_cnt == DELAY  && pos_key == 1'b1)        next_state <= S_UP;      else if( pos_key == 1'b1)        next_state <= S_UP;      else        next_state <= S_DEALY;    S_UP:      next_state <= S_IDLE;    default:  next_state <= S_IDLE;  endcaseend
//延时计数always@(posedge clk or negedge rst_n)begin  if(rst_n == 1'b0)    delay_cnt <= 'd0;  else if(state != next_state)    delay_cnt  <= 'd0;  else if(state == S_DIS_SHAKE)    delay_cnt <= delay_cnt + 1'b1;  else if(state == S_DEALY && delay_cnt == DELAY)    delay_cnt <= 'd0;  else if(state == S_DEALY)    delay_cnt <= delay_cnt + 1'b1;  else    delay_cnt <= 'd0;end
endmodule 

代码是写完了,对不对呢 ? 上仿真!!!仿真的时候别忘记了将DIS_SHAKE这个参数调小一点了,可以设置为2就可以了,否则,你可以试试哦,就只对模式一进行仿真,其他的模式,也可以自行尝试喔!

`timescale  1ns/1psmodule testbeach();
    reg clk;    reg rst_n;    reg ikey;    wire okey;      always#50clk<= ~clk;     initial begin       clk = 1'b0;       rst_n = 1'b1;       ikey = 1'b1;                #100        rst_n = 1'b0;        #100        rst_n = 1'b1;                ikey = 1'b0;  //按下        #400        ikey = 1'b1;  //释放        #200        ikey = 1'b0;  //按下        #600        ikey = 1'b1;  //释放    end
btn_dis_shake #(.mode(0))btn_dis_shakeHP(          .clk    (clk),    .rst_n  (rst_n),      .ikey    (ikey),        //按键输入    .okey  (okey)      //按键输出);    endmodule

当当当当!!!完美对应起来,测试通过!

e335a618-2cad-11ed-ba43-dac502259ad0.png 

审核编辑:彭静
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • FPGA
    +关注

    关注

    1603

    文章

    21326

    浏览量

    593242
  • 模块
    +关注

    关注

    7

    文章

    2485

    浏览量

    46538
  • led灯
    +关注

    关注

    22

    文章

    1554

    浏览量

    107032
  • 代码
    +关注

    关注

    30

    文章

    4556

    浏览量

    66784

原文标题:FPGA实现按键模块

文章出处:【微信号:zhuyandz,微信公众号:FPGA之家】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    华为Mate 30 Lite的渲染图曝光,后置指纹识别按键模块

    近日,有消息曝光了一张华为Mate 30 Lite的渲染图。渲染图显示,华为Mate 30 Lite正面采用一块挖孔屏,后置四摄,且采用正方形框的设计。同时手机后置指纹识别按键模块,渲染图中出现了两种颜色的版本,分别是绿色版本和渐变色版本。
    的头像 发表于 09-17 13:52 2517次阅读

    液晶电视电源模块EMC设计

    液晶电视结构主要包括:液晶显示模块,电源模块,驱动模块(主要包括主驱动板和调谐器板)以及按键模块。一般液晶显示
    发表于 01-25 15:04 2980次阅读
    液晶电视电源<b class='flag-5'>模块</b>EMC设计

    使用FPGA进行按键模块消抖的详细资料说明

    按键消抖实验可谓是经典中的经典,按键消抖实验虽曾在《建模篇》出现过,而且还惹来一堆麻烦。事实上,笔者这是在刁难各位同学,好让对方的惯性思维短路一下,但是惨遭口水攻击 。.. 面对它,笔者宛如被甩的男人,对它又爱又恨。不管怎么样,如今 I’ll be back,笔者再也不会
    发表于 06-12 17:45 3次下载

    微雪电子树莓派电容触摸 按键模块介绍

     树莓派电容触摸模块 16个触摸按键 TTP229-LSF
    的头像 发表于 11-12 16:20 2507次阅读
    微雪电子树莓派电容触摸 <b class='flag-5'>按键</b><b class='flag-5'>模块</b>介绍

    微雪电子8个独立按键模块按钮简介

    8个独立按键模块 8位按键 可用作输入 或进行I/O测试 提供测试程序(AVR、STM8、STM32) 型号 8 Push Buttons
    的头像 发表于 12-30 09:13 2111次阅读
    微雪电子8个独立<b class='flag-5'>按键</b><b class='flag-5'>模块</b>按钮简介

    微雪电子5 IO 按键模块 小键盘介绍

    5 IO 按键模块 - 10个按键 1个摇杆 10个按键 1个摇杆 提供测试程序 原理图 型号 5 IO Keypad
    的头像 发表于 12-30 09:12 1066次阅读
    微雪电子5 IO <b class='flag-5'>按键</b><b class='flag-5'>模块</b> 小键盘介绍

    微雪电子AD按键模块简介

    AD按键模块 16个按键 仅占用1个AD口 检测接口(被接入方需具备AD检测功能)提供测试程序(STM32) 型号 AD Keypad
    的头像 发表于 12-30 09:28 1570次阅读
    微雪电子AD<b class='flag-5'>按键</b><b class='flag-5'>模块</b>简介

    微雪电子4x4矩阵式按键模块小键盘简介

    4x4矩阵式按键模块 16个按键 占用8个IO接口 提供测试程序 原理图 型号 4x4 Keypad
    的头像 发表于 12-30 09:27 2526次阅读
    微雪电子4x4矩阵式<b class='flag-5'>按键</b><b class='flag-5'>模块</b>小键盘简介

    微雪电子电容触摸 按键模块简介

    电容按键模块 I2C 或 I/O接口 8个按键 1个滑条 取代传统按钮 电容式触摸按键 可自动校准 型号 Capacitive Touch Keypad (B)
    的头像 发表于 12-30 09:36 1917次阅读
    微雪电子电容触摸 <b class='flag-5'>按键</b><b class='flag-5'>模块</b>简介

    dfrobotADkey 按键模块介绍

    ADKey 键盘模块让你使用1路模拟口即可读取5个按键的状态,为Arduino节约IO口。
    的头像 发表于 11-29 16:40 2911次阅读
    dfrobotADkey <b class='flag-5'>按键</b><b class='flag-5'>模块</b>介绍

    dfrobotADKeyboard模拟按键模块简介

    Arduino UNO的数字口本来就不多,如果是5个数字按键则要占用5个端口,实在是浪费资源。
    的头像 发表于 12-13 15:36 1608次阅读
    dfrobotADKeyboard模拟<b class='flag-5'>按键</b><b class='flag-5'>模块</b>简介

    STM32G4系列MCU学习笔记:按键模块

    第一次以写博客的方式记录自己在嵌入式学习过程中的学习经历和踩的那些坑~Day1 那么开始叭!STM32G4系列MCU学习笔记:按键模块前言一、硬件操作1. 原理图2. 硬件分析3. 初始化代码
    发表于 12-05 20:51 10次下载
    STM32G4系列MCU学习笔记:<b class='flag-5'>按键</b><b class='flag-5'>模块</b>

    单片机独立按键模块(含短按,长按,连发功能)

    最近看了很多按键扫描的文章,发现各有长处,后来自己花了一点时间做了一个单片机独立按键扫描的模块,此模块优点颇多,支持短按,长按,连发功能,只要配置相关结构体就可以实现这些功能,唯一的缺
    发表于 12-22 19:46 23次下载
    单片机独立<b class='flag-5'>按键</b><b class='flag-5'>模块</b>(含短按,长按,连发功能)

    第十一章 ​扩展模块之矩阵按键模块

    第一节硬件解读不说废话,我们直接看蓝桥杯物联网的扩展的按键模块的原理图:由上面的图我们可以看出,这是一个2*3的矩阵键盘了,关于矩阵键盘的知识就不再重复了,大家都已经参加物联网的比赛了,这些基础知识
    的头像 发表于 02-07 15:57 538次阅读
    第十一章 ​扩展<b class='flag-5'>模块</b>之矩阵<b class='flag-5'>按键</b><b class='flag-5'>模块</b>

    单片机按键切换模式怎么设置

    单片机:选择一款合适的单片机型号,例如常见的8051、STM32等。 按键模块:用于实现按键输入,通常由一个或多个按键组成。 电路板:将单片机、
    的头像 发表于 12-13 11:07 1618次阅读