FPGA按钮消抖实验

news2024/11/24 11:59:10

1、概述
        按键的消抖,是指按键在闭合或松开的瞬间伴随着一连串的抖动,这样的抖动将直接影响设计系统的稳定性,降低响应灵敏度。因此,必须对抖动进行处理,即消除抖动的影响。实际工程中,有很多消抖方案,如 RS 触发器消抖,电容充放电消抖,软件消抖。本章利用 FPGA 内部来设计消抖,即采取软件消抖。
        按键的机械特性,决定着按键的抖动时间,一般抖动时间在 5ms~10ms。消抖,也意味着,每次在按键闭合或松开期间,跳过这段抖动时间,再检测按键的状态。只要通过简单的延时就可实现按键的消抖动。

2、硬件电路分析
2.1 原理图
        开发板底板中配套 2 个独立按键与 FPGA 相连,具体请参见底板原理图。本章使用了开发板按键和 led。各个按键独立,消抖过程相同,因此使用底板上的 SW1 按键模拟实际使用。按键每按一次,对应的 LED 灯反转一次。即检测按键是否有闭合和断开的过程,如果有,第一次则 LED 灯点亮,第二次,则 LED 灯熄灭。

2.2 IO约束

set_property PACKAGE_PIN D9 [get_ports {led_o[0]}]
set_property PACKAGE_PIN J11 [get_ports {led_o[1]}]
set_property PACKAGE_PIN B9 [get_ports {led_o[2]}]
set_property PACKAGE_PIN J10 [get_ports {led_o[3]}]
set_property IOSTANDARD LVCMOS15 [get_ports {led_o[*]}]
set_property PACKAGE_PIN C8 [get_ports clk_i]
set_property IOSTANDARD LVCMOS15 [get_ports clk_i]
set_property PACKAGE_PIN H13 [get_ports key_i]
set_property IOSTANDARD LVCMOS15 [get_ports key_i]
set_property PACKAGE_PIN V19 [get_ports rst_n_i]
set_property IOSTANDARD LVCMOS15 [get_ports rst_n_i]

2.3 key 模块的设计
        由于按键滤波是比较通用的一个程序,因此我们可以把一个通用的程序设置为一个模块,方便后面重复使用。

module key #
(
    parameter CLK_FREQ = 100000000
)
(
input clk_i,
input key_i,
output key_cap
);
//10ms
parameter CNT_10MS = (CLK_FREQ/100 - 1'b1);
parameter KEY_S0 = 2'd0;
parameter KEY_S1 = 2'd1;
parameter KEY_S2 = 2'd2;
parameter KEY_S3 = 2'd3;

reg [24:0] cnt10ms = 25'd0;
(*mark_debug = "true"*) reg [1:0] key_s = 2'b0;
(*mark_debug = "true"*) reg [1:0] key_s_r = 2'b0;
(*mark_debug = "true"*) wire en_10ms ;
 
assign en_10ms = (cnt10ms == CNT_10MS);
assign key_cap = (key_s==KEY_S2)&&(key_s_r==KEY_S1);

always @(posedge clk_i)begin
    if(cnt10ms < CNT_10MS) 
        cnt10ms <= cnt10ms + 1'b1;
    else 
        cnt10ms <= 25'd0;
end

always @(posedge clk_i)begin
    key_s_r <= key_s;
end

always @(posedge clk_i)begin
    if(en_10ms)begin
        case(key_s)
        KEY_S0:begin
           if(!key_i)
               key_s <= KEY_S1; 
        end  
        KEY_S1:begin
           if(!key_i)
               key_s <= KEY_S2; 
            else 
               key_s <= KEY_S0; 
        end 
        KEY_S2:begin
           if(key_i)
               key_s <= KEY_S3; 
        end  
        KEY_S3:begin
           if(key_i)
              key_s <= KEY_S0;
            else   
              key_s <= KEY_S2; 
        end
        endcase                  
    end
end

endmodule

        以上代码中,首先把系统时钟做分频,产生 10ms 的分频时钟使能信号。每10ms都会判断一次是否有按键按下。在设计的状态机中,分 4 个状态:
        KEY_S0:判断按键是否按下,如果是,转移到状态 KEY_S1;
        KEY_S1:10ms 后再次判断按键是否按下,如果是,转移状态到 KEY_S2,否则继续回到KEY_S0;
        KEY_S2:判断按键是否抬起,如果是,转移状态到 KEY_S3
        KEY_S3:10ms 后再次判断按键是否抬起,如果是,转移状态到 KEY_S0,否则继续回到KEY_S2;
        当状态从 KEY_S1 转到 KEY_S2 代表依次按钮按下 key_cap 输出一次高电平。

2.4 调用 key 模块
        以下代码中调用了 key 模块,并且每次 key_cap 有效,都会翻转一次 LED 的输出。

`timescale 1ns / 1ps
module Key_Jitter(
input clk_i,
input rst_n_i,
input key_i,
output [3:0] led_o

);
reg [3:0] led_o;
wire key_cap;

always @(posedge clk_i)begin
    if(!rst_n_i)begin
        led_o <= 4'b0000;
    end
    else if(key_cap)begin
        led_o <= ~led_o;  
    end
end

key#
(
.CLK_FREQ(100000000)
)
key0
(
.clk_i(clk_i),
.key_i(key_i),
.key_cap(key_cap)
);

ila_0 ila_debug (
	.clk(clk_i),
	.probe0({key_cap,led_o})
);

endmodule

2.5 综合布线前仿真时序
1)新建仿真文件,仿真文件源码如下所示。


module Key_Jitter_tb;

	// Inputs
	reg clk_i;
	reg rst_n_i;
	reg key_i;
	wire [2:0] led_o;


	// Instantiate the Unit Under Test (UUT)
	Key_Jitter uut (
		.clk_i(clk_i), 
		.rst_n_i(rst_n_i), 
		.key_i(key_i), 
		.led_o(led_o)
	);

initial
	begin
		// Initialize Inputs
		clk_i = 0;
	end
	always #5 clk_i=~clk_i;

initial
	begin
		// Initialize Inputs
		rst_n_i = 0;
		#100;
		rst_n_i=1;
		key_i = 1;
		#10000;
		forever
			begin
				key_i = 0;
				// Wait 100 ns for global reset to finish
				#100;
				key_i=1; #1000;
				key_i=0; #1000;
				key_i=1; #2000;
				key_i=0; #5000;
				#50000000;
				key_i=1;
				key_i=0; #1000;
                key_i=1; #2000;
                key_i=0; #1000;
                key_i=1; #2000;
				#50000000;
				key_i=0;
				
			end
	end

endmodule


2)进入仿真界面:SIMULATION->单击 Run Simulation ->单击 Run Behavioral Simulation。

Setp3:设置断点

之后再点击下图箭头所指

之后可以看到增加的内部信号,可以以这种方法去观察内部信号

右击框选的需要增加观察的信号选择添加到波形窗口,并且取消断点

3)复位仿真波形

4)重新仿真时间为 1000ms

5)观察仿真波形

6)放大波形观察毛刺

3、板级验证结果分析
        将程序下载。按键 SW1 每按一次,LED 灯很好地熄灭和点亮。LED 灯响应无差错。为清晰的表示消抖的效果,可将延时参数设置很小,可以发现,按键有时候明明已经按下去了,LED 却无响应。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1394079.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

STM32开发板,Win10、Win11 上的驱动安装说明

一、USB线插到 CMSIS-DAP 接口上&#xff0c;将自动识别到两个设备 ① CMSIS-DAP&#xff1a;用于烧录代码、在线硬件仿真; 在Keil里烧录&#xff0c;无需通过FlyMCU; ② USB转TTL&#xff1a;用于开发板与电脑间串口通信 &#xff0c;即USART1, TX-PA9、RX-PA10; 接口备注&a…

百度地图实现搜索并在地图上标注,手动点击标注获取经纬度

在代码只需要替换为你自己的key即可。 如何申请key:如何申请百度地图ak?|2023年5月更新版 - 知乎 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><title>百度地图搜索</title><!-- 引入百度地…

Unity中四元数常用的方法

单位四元数 #region 单位四元数print(Quaternion.identity);testObj.rotation Quaternion.identity;//初始化对象时可能会用来赋值Instantiate(testObj,Vector3.zero,Quaternion.identity);#endregion 插值运算 #region 插值运算 //四元数中也提供了如同Vector3的插值运算 /…

[linux]使用libqrencode库生成二维码数据

一、需求 要将一段数据生成为二维码&#xff0c; 二、方案 使用linux标准库&#xff0c;通过libqrencode将需要写入的信息转为二维码图片数据。 三、实现 3.1编写c文件 #include <stdio.h> #include <stdlib.h> #include <qrencode.h> int main() {QRc…

【开源】基于JAVA语言的快乐贩卖馆管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 搞笑视频模块2.3 视频收藏模块2.4 视频评分模块2.5 视频交易模块2.6 视频好友模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 搞笑视频表3.2.2 视频收藏表3.2.3 视频评分表3.2.4 视频交易表 四、系…

HTML快速上手

前腰&#xff1a;本文只是概括重要的 html 标签&#xff0c;这些标签的使用频率较高&#xff0c;更多标签相关的资源您可以跳转 Mmdn 进行深入的学习。 1.HTML 基础 就其核心而言&#xff0c;HTML 是一种相当简单的、由不同 元素 组成的标记语言&#xff0c;它可以被应用于文本…

C语言之【函数】篇章以及例题分析

文章目录 前言一、函数是什么&#xff1f;二、C语言中函数的分类1、库函数2、自定义函数 三、函数的参数1、实际参数&#xff08;实参&#xff09;2、形式参数&#xff08;形参&#xff09; 四、函数的调用1、传值调用2、传址调用3、专项练习3.1 素数判断3.2 闰年判断3.3 二分查…

android软件全屏时,输入法显示的输入框位置代码

一、问题描述 在输入密码框时,点击密码输入框,会跳出软键盘,同时附带一个输入框: 这个输入框并不随输入法设置,而是一个系统自带的配置。 当这个密码以明文的方式显示时,输入网址或者ip,长按后能够打开浏览器。这是我不希望出现的。 二、探索password的TextView 根据…

Ubuntu 在更新内核后 Virtual Box 不能为虚拟电脑打开一个新任务

前言 我也不知道啥时候自动给我更新了内核&#xff0c;重启电脑之后我的内核升级成6.5.0-14-generic&#xff0c;导致Virtual Box无法找到内核文件。 解决方法 方法1 sudo apt update sudo apt install linux-headers-generic build-essential dkms sudo apt remove virtua…

甜蜜而简洁——深入了解Pytest插件pytest-sugar

在日常的软件开发中,测试是确保代码质量的关键步骤之一。然而,对于测试报告的生成和测试结果的可读性,一直以来都是开发者关注的焦点。Pytest插件 pytest-sugar 以其清晰而美观的输出,为我们提供了一种愉悦的测试体验。本文将深入介绍 pytest-sugar 插件的基本用法和实际案…

Vue-26、Vue内置指令v-cloak与v-once以及v-pre

1、v-cloak 本质上是一个特殊属性&#xff0c;Vue实例创建完毕并接管容器后&#xff0c;会删掉v-cloak属性使用css配合v-cloak可以解决网速慢时页面展示出{{xxx}}的问题 代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF…

vue二次封装ant-design-vue中的Modal弹窗组件,实现拖拽,全屏两种功能,原有参数属性不变

在我们的项目的有的地方需要用弹框的拖拽&#xff0c;以及弹窗自定义全屏显示的需求&#xff0c;所以再次将二次合一&#xff0c;同时弹框里面内容自适应屏幕高度 在ant-design-vue中&#xff0c;已经实现了拖拽&#xff0c;全屏的功能&#xff0c;下面是ant官网的示例 自定义…

【JavaEE进阶】 关于应用分层

文章目录 &#x1f38b;序言&#x1f343;什么是应⽤分层&#x1f38d;为什么需要应⽤分层&#x1f340;如何分层(三层架构)&#x1f384;MVC和三层架构的区别和联系&#x1f333;什么是高内聚低耦合⭕总结 &#x1f38b;序言 在我们进行项目开发时我们如果一股脑将所有代码都…

零售EDI:Babylist EDI 项目案例

Babylist 与各种不同的品牌和零售商合作&#xff0c;包括婴儿用品、玩具、衣物和其他相关产品的制造商。用户可以在 Babylist 上浏览各种不同的产品&#xff0c;并根据自己的需求和喜好选择适合的项目。本文将为大家介绍对接Babylist 的EDI项目案例。 Babylist EDI 需求 传输协…

升级8.0:民生手机银行的“内容解法”

数字化浪潮&#xff0c;滚滚来袭。 随着数字中国建设的持续推进&#xff0c;数字经济正在蓬勃发展。中商产业研究院分析师预测&#xff0c;2023年中国数字经济市场规模将增长至56.7万亿元&#xff0c;占GDP的比重将达到43.5%。 在此浪潮下&#xff0c;数字化的触角蔓延到各行…

[C++] opencv - copyTo函数介绍和使用案例

copyTo函数介绍 copyTo函数是OpenCV库中的一个成员函数&#xff0c;用于将一个Mat对象的内容复制到另一个Mat对象中。 函数原型&#xff1a; void cv::Mat::copyTo(OutputArray m) const;void cv::Mat::copyTo(OutputArray m, InputArray mask) const; 参数说明&#xff1a;…

指向未来: 量子纠缠的本质是一个指针

指向未来: 量子纠缠的本质是一个指针 概述基本概念理解量子纠缠PythonJavaC 理解波粒二象性PythonJavaC 理解量子隧穿理解宇宙常量PythonJavaC 概述 量子纠缠 (Quantum Entanglement) 是量子系统重两个或多个粒子间的一种特殊连接, 这种连接使得即使相隔很远, 这些粒子的状态也…

oracle11g的闪回技术-闪回表-时间戳

--数据库闪回表 --1创建表&#xff08;登录模式system&#xff09; CREATE table dept2 as select * from dept;--此语句如果加上where条件可用于工作中数据的临时备份 select * from dept2;--查询新建表信息 --进入sql>set time on 通过时间点闪回 记录弹出的时间点&#…

2024年linux内核开发会是程序员新的风口吗?

前言 众所周知&#xff0c;linux操作系统一直靠着稳定&#xff0c;安全&#xff0c;开源等优势占据着80%以上的服务器市场。小至私人企业&#xff0c;大至世界百强&#xff0c;都离不开它的身影。以至于无论你擅长的是哪门语言&#xff0c;面试的时候都会或多或少的涉及linux的…

物联网网关与plc怎么连接?

物联网网关与plc怎么连接&#xff1f; 物联网是当今社会中最热门的技术之一&#xff0c;而物联网网关则是连接物联网设备与云平台的核心设备之一。物联网网关在连接各种传感器和设备时起着至关重要的作用。而另一种广泛应用于工业控制和自动化领域的设备是可编程逻辑控制器&…