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
目录
相关文章
|
11天前
|
存储 算法 测试技术
FPGA(现场可编程门阵列)技术概述及其应用实例
FPGA(现场可编程门阵列)技术概述及其应用实例
|
异构计算
|
异构计算
实验二 基于FPGA的分频器的设计(基本任务:设计一个分频器,输入信号50MHz,输出信号频率分别为1KHz、500Hz及1Hz。拓展任务1:用按键或开关控制蜂鸣器的响与不响。拓展任务2:用按键或开)
实验二 基于FPGA的分频器的设计(基本任务:设计一个分频器,输入信号50MHz,输出信号频率分别为1KHz、500Hz及1Hz。拓展任务1:用按键或开关控制蜂鸣器的响与不响。拓展任务2:用按键或开)
884 0
实验二 基于FPGA的分频器的设计(基本任务:设计一个分频器,输入信号50MHz,输出信号频率分别为1KHz、500Hz及1Hz。拓展任务1:用按键或开关控制蜂鸣器的响与不响。拓展任务2:用按键或开)
|
5月前
|
异构计算
FPGA-基于UART的QVGA显示(二)(实现PC端发送字母数字汉字的分别显示通过按键可以删除字符)
FPGA-基于UART的QVGA显示(二)(实现PC端发送字母数字汉字的分别显示通过按键可以删除字符)
84 0
FPGA-基于UART的QVGA显示(二)(实现PC端发送字母数字汉字的分别显示通过按键可以删除字符)
|
C语言 异构计算
FPGA-独立按键的消抖(软件消抖未用状态机)
FPGA-独立按键的消抖(软件消抖未用状态机)
309 0
|
15天前
|
机器学习/深度学习 算法 异构计算
m基于FPGA的多通道FIR滤波器verilog实现,包含testbench测试文件
本文介绍了使用VIVADO 2019.2仿真的多通道FIR滤波器设计。展示了系统RTL结构图,并简述了FIR滤波器的基本理论,包括单通道和多通道的概念、常见结构及设计方法,如窗函数法、频率采样法、优化算法和机器学习方法。此外,还提供了Verilog核心程序代码,用于实现4通道滤波器模块,包含时钟、复位信号及输入输出接口的定义。
28 7
|
3月前
|
算法 异构计算
基于FPGA的ECG信号滤波与心率计算verilog实现,包含testbench
基于FPGA的ECG信号滤波与心率计算verilog实现,包含testbench
|
2月前
|
算法 异构计算
m基于FPGA的电子钟verilog实现,可设置闹钟,包含testbench测试文件
该文介绍了基于FPGA的电子钟设计,利用Vivado2019.2平台进行开发并展示测试结果。电子钟设计采用Verilog硬件描述语言,核心包括振荡器、分频器和计数器。时间显示为2个十进制格式,闹钟功能通过存储器和比较器实现,当当前时间等于设定时间时触发。文中给出了Verilog核心程序示例,展示了时钟信号、设置信号及输出的交互。
34 2

热门文章

最新文章