FPGA-状态机的实现实例(按键的消抖)

简介: FPGA-状态机的实现实例(按键的消抖)

大致思路有了,如何设计实现呢?貌似这是一个很复杂的设计,实则不然,FSM的本质就是对具有逻辑规律和时序逻辑的事物的描述,采用FSM设计,问题迎刃而解!

1、从状态变量入手,分析状态变量:


    IDLE:按键空闲状态(由于上拉电阻的作用,按键未被按下时保持高电平);

    FILTER_DOWN:按下滤波状态;

    DOWN:按下稳定状态;

    FILTER_UP:释放滤波状态;

2、分析状态转移条件,绘制状态转移图(visio)


3、照图施工,选用合适的描述方案


    在描述的时候,有两个重要问题需要解决:

1)按键信号属于异步信号,在状态转移中需要对按键边沿敏感,所以首先采用一级D触发器将key_in与clk同步,产生pedge和nedge信号,也就是边沿检测电路,代码如下:

//边沿检测电路always@(posedgeclk)
key_temp<=key_in;                                 //暂存上一个clk按键状态assignkey_nedge= (key_temp)&&(!key_in);        //下降沿检测assignkey_pedge= (!key_temp)&&(key_in);        //上升沿检测

2)当20ms延时完毕后,应该输出一个脉冲,通知其它模块检测key_flag引脚电平;

    完整的verilog描述代码如下:

`timescale1ns/1ps//// Module Name: key_filter// Description: //独立按键消抖模块//modulekey_filter(
inputclk,                    //50M时钟信号inputrst,                    //低电平复位inputkey_in,                 //按键输入outputregkey_flag,          //消抖完毕输出脉冲outputregkey_state//按键状态输出);
reg  [3:0]NS;            //nextstateregkey_temp;
wirekey_pedge;    
wirekey_nedge;
regen_cnt;
reg [19:0]cnt;            //需要计数次数1_000_000//边沿检测电路always@(posedgeclk)
key_temp<=key_in;                          //暂存上一个clk按键状态assignkey_nedge= (key_temp)&&(!key_in);        //下降沿检测assignkey_pedge= (!key_temp)&&(key_in);        //上升沿检测//带使能端计数器,用于20ms延时always@(posedgeclk,negedgerst)
if(!rst)
cnt<=0;
elseif(en_cnt)
cnt<=cnt+1'b1;elsecnt<=0;
//状态one-hot编码localparamIDLE=4'b0001,        //空闲状态FILTER_DOWN=4'b0010,        //按下消抖状态DOWN=4'b0100,        //按下稳定状态FILTER_UP=4'b1000;        //释放消抖状态//一段式状态机always@(posedgeclk,negedgerst)
if(!rst)beginNS<=IDLE;
en_cnt<=0;
key_flag<=0;
key_state<=1;
endelsecase(NS)
IDLE:
beginkey_flag<=0;
key_state<=1;
if(key_nedge)beginNS<=FILTER_DOWN;
en_cnt<=1'b1;        //使能计数器endelseNS<=IDLE;
endFILTER_DOWN:
if(cnt>=20'd999_999)beginen_cnt<=0;               //20ms时间到,失能计数器,进入稳定状态key_flag<=1'b1;          //key_flag输出一个clk高脉冲NS<=DOWN;
endelseif(key_pedge)beginen_cnt<=0;                //20ms时间内发生上升沿,失能计数器,保持空闲状态NS<=IDLE;
endDOWN:
beginkey_flag<=0;
key_state<=0;
if(key_pedge)beginNS<=FILTER_UP;
en_cnt<=1'b1;         //使能计数器endelseNS<=DOWN;
endFILTER_UP:
if(cnt>=20'd999_999)beginen_cnt<=0;
NS<=IDLE;                 //20ms时间到,失能计数器,进入稳定状态key_flag<=1;
endelseif(key_nedge)beginen_cnt<=0;                //20ms时间内发生上升沿,失能计数器,保持按下稳定状态NS<=DOWN;            
enddefault:
NS<=IDLE;
endcaseendmodule
目录
相关文章
|
7月前
|
存储 算法 测试技术
FPGA(现场可编程门阵列)技术概述及其应用实例
FPGA(现场可编程门阵列)技术概述及其应用实例
|
5月前
|
异构计算
FPGA新起点V1开发板(十)——按键控制LED
FPGA新起点V1开发板(十)——按键控制LED
FPGA新起点V1开发板(十)——按键控制LED
|
5月前
|
异构计算
FPGA新起点V1开发板(八-语法篇)——状态机
FPGA新起点V1开发板(八-语法篇)——状态机
|
算法 异构计算
通过状态机方法实现基于FPGA的维特比译码器,包含testbench测试文件
通过状态机方法实现基于FPGA的维特比译码器,包含testbench测试文件
166 0
|
算法 异构计算
基于状态机方法的按键消抖模块FPGA实现,包括testbench
基于状态机方法的按键消抖模块FPGA实现,包括testbench
161 0
|
异构计算
|
异构计算
实验二 基于FPGA的分频器的设计(基本任务:设计一个分频器,输入信号50MHz,输出信号频率分别为1KHz、500Hz及1Hz。拓展任务1:用按键或开关控制蜂鸣器的响与不响。拓展任务2:用按键或开)
实验二 基于FPGA的分频器的设计(基本任务:设计一个分频器,输入信号50MHz,输出信号频率分别为1KHz、500Hz及1Hz。拓展任务1:用按键或开关控制蜂鸣器的响与不响。拓展任务2:用按键或开)
1337 0
实验二 基于FPGA的分频器的设计(基本任务:设计一个分频器,输入信号50MHz,输出信号频率分别为1KHz、500Hz及1Hz。拓展任务1:用按键或开关控制蜂鸣器的响与不响。拓展任务2:用按键或开)
|
异构计算
FPGA-基于UART的QVGA显示(二)(实现PC端发送字母数字汉字的分别显示通过按键可以删除字符)
FPGA-基于UART的QVGA显示(二)(实现PC端发送字母数字汉字的分别显示通过按键可以删除字符)
128 0
FPGA-基于UART的QVGA显示(二)(实现PC端发送字母数字汉字的分别显示通过按键可以删除字符)

热门文章

最新文章