首页 > 其他分享 >FPGA知识基础之--500ms计数器,边沿检测,按键消抖

FPGA知识基础之--500ms计数器,边沿检测,按键消抖

时间:2024-08-02 09:56:35浏览次数:13  
标签:FPGA clk -- 消抖 sys key rst data reg

目录


前言


一、边沿检测

1.1 使用背景

在我们设计电路时,经常会遇到需要继续检测上升沿和下降沿的电路,因此需要对边沿继续检测

1.2 方法:打拍法

1.2.1 背景

data数据信号不是时钟信号,不稳定,有许多毛刺,不能直接利用always语句中的posedge和nesedge来检测,因此需要通过其他办法来对边沿进行检测
有关毛刺,在数字电路的竞争与冒险中有讲解,是一个很重要的概念,希望读者先行掌握

在这里插入图片描述

1.2.2 原理

采用两个寄存器,对data数据信号进行打两拍处理,来消除数据不稳定产生的毛刺
在这里插入图片描述

1.2.3 上升沿

在这里插入图片描述由上述波形图可知:上升沿脉冲即为data_0为0 ,data_1为1时所取的信号
代码

module pos_data(
input 			sys_clk,
input 			sys_rst_n,
input 			data,
			
output			pos_data
);

reg 			data_0;
reg 			data_1;

always @(posedge sys_clk or negedge sys_rst_n) begin
	if(!sys_rst_n)
		begin 
			data_0 <= 1'd0;
			data_1 <= 1'd0;
		end
	else 
		begin
			data_0 <= data;
			data_1 <= data_0;
		end 
end 

assign pos_data = data_0 && ~data_1; //若是下降沿,则改为~data_0 && data_1;若是边缘,则改为 data_0 ^ data_1
endmodule

tb代码



`timescale 1ns / 1ns        

module tb_pos_data();

//parameter define
parameter  CLK_PERIOD = 20;           
      

//reg define
reg           sys_clk;
reg           sys_rst_n;
reg           data;

//wire define
wire         pos_data;


initial begin
    sys_clk <= 1'b0;
    sys_rst_n <= 1'b0;
    data <= 1'b0;
    #200
    sys_rst_n <= 1'b1;

    #200
    data <= 1'b1;
    #200
    data <= 1'b0;
    #200
    data <= 1'b1;

end


always #(CLK_PERIOD/2) sys_clk = ~sys_clk;


pos_data  u_pos_data(
    .sys_clk      (sys_clk),
    .sys_rst_n    (sys_rst_n),
    .data          (data),
    .pos_data        (pos_data)
    );

endmodule


波形

在这里插入图片描述

需要注意的是,在编写Testbench时,要将data改变的时间间隔延长一些,否则结果不明显

二、计数器

2.1 原理

计时500ms用寄存器cnt_500;因为晶振为50MHZ,即20ns,所以需要cnt记到25000时清零,25000转化为二进制为0110 0001 1010 1000,有15位,所以cnt需要定义为15位
在这里插入图片描述

2.2 RTL代码

module cnt_500(
input                   sys_clk,
input                   sys_rst_n,

output  reg  [14:0]      cnt

);

parameter  CNT_MAX = 25000 ;

always @(posedge sys_clk or negedge sys_rst_n) begin
    if(!sys_rst_n) 
        cnt <= 15'd0;
    else if (cnt < (CNT_MAX - 1'd1))
        cnt <= cnt + 1'd1;
    else 
        cnt <= 1'd0;
    
end

endmodule

Testbench代码


`timescale 1ns / 1ns   
module tb_cnt_500();

parameter CLK_PERIOD = 20;


reg            sys_clk;
reg           sys_rst_n;

wire   [14:0]     cnt ;






always #(CLK_PERIOD/2) sys_clk = ~sys_clk;

initial begin
    sys_clk <= 1'd0;
    sys_rst_n <= 1'd0;
    #200
    sys_rst_n <= 1'd1;


    
end

cnt_500 u_cnt_500(
    .sys_clk     (sys_clk),
    .sys_rst_n   (sys_rst_n),
    .cnt          (cnt)
);

endmodule

波形

在这里插入图片描述
符合预期

三、按键消抖

RTL代码

module key_debounce(  
input       sys_clk,
input       sys_rst_n,
input       key,

output   reg   key_filter
);

parameter CNT_MAX = 1000; //延时20ms


reg key_0;
reg key_1;
reg   [9:0] cnt;

always @(posedge sys_clk or negedge sys_rst_n) begin 
    if(!sys_rst_n) begin
        key_0 <= 1'b0;
        key_1 <= 1'b0;
    end
    else
    begin
        key_0    <= key;
        key_1   <= key_0;
    end 
end

always @(posedge sys_clk or negedge sys_rst_n) begin 
    if(!sys_rst_n) 
        cnt <= 0;
    else if  ( key_0 !=  key_1 | cnt == (CNT_MAX - 1)) 
        cnt <= 0;
    else if (cnt < (CNT_MAX - 1) )
        cnt <= cnt + 1;
    
    
   
end

always @(posedge sys_clk or negedge sys_rst_n) begin 
    if(!sys_rst_n) 
        key_filter <= 1;
    else if  (cnt == (CNT_MAX-1))
        key_filter <= key_1;
end 


endmodule

Testbench代码

`timescale 1ns/1ns 
module tb_key_debounce();


reg key;
reg sys_clk;
reg sys_rst_n;

wire key_filter;

parameter CLK_PERIOD = 20;
parameter CNT_MAX = 10;//延时200ns


initial begin
    sys_clk <= 1'd0;
    sys_rst_n <= 1'd0;
    key <= 1'd1;
    #10
    sys_rst_n <= 1'd1;
    key <= 1'd0;
    #20
    key <= 1'd1;
    #30
    key <= 1'd0;
    #300
    key <= 1'd1;
    #20
    key <= 1'd0;
    #10
    key <= 1'd1;
    #30
    key <= 1'd0;

end


always #(CLK_PERIOD/2) sys_clk = ~sys_clk;
key_debounce #(
        .CNT_MAX    (CNT_MAX)
)
    u_key_debounce(
        .sys_clk    (sys_clk),
        .sys_rst_n  (sys_rst_n),
        .key        (key),

        .key_filter (key_filter)
);


endmodule

波形展示
在这里插入图片描述

标签:FPGA,clk,--,消抖,sys,key,rst,data,reg
From: https://blog.csdn.net/2301_76707170/article/details/140831807

相关文章

  • 如何从智联招聘网站快速抓取职位详情?两大技巧揭秘
    摘要:本文将揭秘如何利用Python爬虫技术,高效且合法地从智联招聘网站抓取职位详情信息。通过实战示例,展现两大核心技巧,助你在大数据时代抢占先机,为你的市场分析、人才研究提供强大支持。一、引言:数据之海,精准捕捞的重要性在信息爆炸的时代,精准获取有价值的数据如同深海捕捞,Py......
  • 轮转数组的Java实现
    轮转数组给定一个整数数组nums,将数组中的元素向右轮转k个位置,其中k是非负数。输入:nums=[1,2,3,4,5,6,7],k=3输出:[5,6,7,1,2,3,4]解释:向右轮转1步:[7,1,2,3,4,5,6]向右轮转2步:[6,7,1,2,3,4,5]向右轮转3步:[5,6,7,1,2,3,4]解法1:把数组看成......
  • ChatGPT副业变现的4种方式
    AI的出现,几家欢喜几家愁。有人担心受怕恐因AI被裁,有人却早已利用AI躺赚......
  • 2024年必备技能:智联招聘岗位信息采集技巧全解析
    随着大数据时代的发展,精准定位职业机会成为程序员求职的关键。本文将深入解析如何利用Python高效采集智联招聘上的岗位信息,助你在2024年的职场竞争中脱颖而出。通过实战代码示例,揭示网络爬虫背后的秘密,让你轻松掌握这一必备技能。正文:一、为什么学习智联招聘岗位信息采集很......
  • C高级(3):shell脚本
    目录1shell的基础概念:1.1概念1.2创建和执行2变量2.1用户自定义变量2.2位置变量2.3预定义变量2.4环境变量3功能语句3.1说明性语句3.2功能性语句1)read2)expr3)let4结构性语句4.1if语句4.2case语句4.3for循环4.4while4.5循环控制语句1shell的基础概念:1.1概......
  • 27、Python之面向对象:方生方死?对象生命周期是如何管理的
    引言前面关于面向对象的几篇文章,其实主要围绕着面向对象的第一个核心理念——封装,进行面向对象的介绍。从类、对象的静态构成的角度,对类与对象的定义及使用进行介绍。在进入面向对象另外两个理念的介绍之前,我觉得有必要对Python中对象的生命周期管理进行一些介绍,从而知道我们......
  • C基础:结构体 struct
    目录1.结构体基本用法1.1定义1.2结构体定义格式1.3结构体变量1.3.1概念1.3.2定义格式1.3.3定义结构体变量的方式1.3.4结构体变量赋值1.5.3访问结构体成员变量1.4重定义typedef1.4.1基本用法1.4.2定义结构体的同时重定义1.4.3先定义结构体,然后重定义2......
  • 浅析前端数据埋点监控:用户行为与性能分析的桥梁
    在数字化时代,数据是企业决策的重要依据。前端作为用户与产品交互的第一线,其数据埋点监控不仅能够收集用户行为数据,帮助产品团队洞察用户需求,优化用户体验,还能分析性能数据,确保产品运行的流畅性。简单来说就是,为了更有效地优化工厂的运营和布局,我们可以通过在工厂的关键区域安装监......
  • Java毕业设计-基于springboot开发的智能学习平台系统-毕业论文(附毕设源代码)
    文章目录前言一、毕设成果演示(源代码在文末)二、毕设摘要展示1、开发说明2、需求/流程分析3、系统功能结构三、系统实现展示1、学生信息管理2、课程信息管理3/试卷信息管理4/公告信息管理四、毕设内容和源代码获取总结逃逸的卡路里博主介绍:✌️码农一枚|毕设布道师......
  • 接口
    接口(Interface)接口(Interface)在面向对象编程(OOP)中是一个非常重要的概念,它定义了一组方法规范(也称为成员函数),但通常不实现这些方法的具体逻辑。接口是一种引用类型,它是一种抽象的类型,用于指定一组方法,但不实现它们。实现接口的类必须提供接口中所有方法的具体实现。一.接口的概......