FPGA学习基础之--按键控制蜂鸣器


前言

本文笔者将为大家详细的介绍按键控制蜂鸣器这一过程,将自己的学习过程分享给大家


一、蜂鸣器简介

1.分类

源指的是振荡源
有源蜂鸣器,只需提供高电平1
无源蜂鸣器,需要提供变化的脉冲信号

2.工作原理

蜂鸣器的工作原理是当电流通过时,压电陶瓷或磁性材料会发生机械振动,产生声音。蜂鸣器的发声频率与电流的频率相关。通过改变电流的频率和幅度,可以控制蜂鸣器发出的声音。

3.蜂鸣器原理图

在这里插入图片描述

二、按键消抖

1.背景

在这里插入图片描述

按键通常使用机械弹性开关,当机械触点断开、闭合时,由于机械触点的弹性作用,一个按键开关在闭合时不会马上稳定地接通,在断开时也不会一下子断开。因而在闭合及断开的瞬间均伴随有一连串的抖动。这种抖动现象会影响按键信号的稳定性,可能导致系统误判按键状态,进而引发误操作。

2.目的

按键消抖的主要目的是通过软件或硬件手段,对按键信号进行预处理和滤波,以确保只有有效的按键操作被正确识别。它旨在消除抖动带来的不稳定因素,提高系统的响应准确性和可靠性。

3.方法

按键消抖的方法主要分为硬件消抖和软件消抖两大类,每种方法都有其独特的优势和局限性。

1. 硬件消抖

滤波消抖:

利用RC积分电路等滤波元件来吸收振荡脉冲,通过选取适当的时间常数来消除按键抖动的影响。这种方法在硬件层面实现,无需修改软件代码,但需要根据具体的电路和按键特性来选择合适的滤波参数。

硬件消抖芯片:

集成了按键消抖功能的专用集成电路(IC),能够在硬件层面对按键抖动信号进行处理,提供稳定和可靠的按键输出。这种方法具有高度的稳定性和可靠性,但可能需要额外的成本投入。

2. 软件消抖

软件延时消抖:

当检测到按键状态改变时,在代码中添加一个适当的延时(通常为5ms~10ms),等待抖动信号消失后再进行后续操作。这种方法实现简单,无需额外硬件支持,但延时时间需要经过调试才能确定,且较长的延时可能导致按键响应速度变慢。

状态机消抖:

通过构建一个有限状态机来处理按键信号。该状态机根据按键输入的变化来判断当前按键状态(按下、释放或保持),从而过滤掉抖动信号并保留有效的按键操作。这种方法设计相对复杂,但灵活性较高,可以根据具体需求进行定制。

本次实验采用软件延时消抖
在这里插入图片描述

三、实验任务

使用开发板的k0来控制蜂鸣器鸣叫,初始状态为蜂鸣器鸣叫,按下后停止鸣叫,再次按下开关,重新鸣叫

四、自锁现象

1.定义

在电路中,自锁是指交流接触器通过自身的常开辅助触头使线圈总是处于得电状态的现象。这个常开辅助触头就被称为自锁触头。

2.原理

  • 当接触器线圈得电后,其常开辅助触点会闭合,从而保持回路的接通状态。
  • 如果将常开辅助触点与启动按钮并联,当启动按钮被按下时,接触器会动作,辅助触点闭合,进行状态保持。此时,即使松开启动按钮,接触器也不会失电断开,因为辅助触点已经闭合,形成了自锁回路。

3.应用

自锁电路在很多领域的安全性方面有非常好的表现。例如,在电动机控制电路中,自锁可以确保电动机在启动后能够持续运行,直到按下停止按钮为止。


五、程序设计

1.思路整理

在这里插入图片描述

2.系统框图

在这里插入图片描述

3.按键消抖模块

在这里插入图片描述

4.蜂鸣器模块

在这里插入图片描述

5.RTL代码

5.1按键消抖模块

module key_debounce(  
    input           sys_clk,  
    input           sys_rst_n,  
    input           key,  
    output  reg     key_filter  
);  
  
reg         key_d0, key_d1;  
reg [19:0]  cnt;  
  
parameter   CNT_MAX = 20'd1000000; // 计时20ms(假设系统时钟频率合适)  
  
// 对key打两拍  
always @(posedge sys_clk or negedge sys_rst_n) begin  
    if (!sys_rst_n) begin  
        key_d0 <= 1'b1;  
        key_d1 <= 1'b1;  
    end else begin  
        key_d0 <= key;  
        key_d1 <= key_d0;  
    end  
end  
  
// 如果按键有变化,重新计时20ms  
always @(posedge sys_clk or negedge sys_rst_n) begin  
    if (!sys_rst_n)   
        cnt <= 0;  
    else if (key_d0 != key_d1)  
        cnt <= CNT_MAX;  
    else if (cnt > 0)  
        cnt <= cnt - 1;  
    // else 已经是0,无需额外处理  
end  
  
// 滤除抖动后的key赋值  
always @(posedge sys_clk or negedge sys_rst_n) begin  
    if (!sys_rst_n)   
        key_filter <= 1'b1;  
    else if (cnt == 0)  
        key_filter <= key_d1;  
    // else 保持当前值  
end  
  
endmodule

5.2 蜂鸣器模块

module key_beep(
input 			sys_clk,
input 			sys_rst_n,
input 			key_filter,
	
output 	reg 	beep
);

reg 	key_filter_d0;

wire neg_key_filter;
 
assign neg_key_filter = key_filter_d0 & (~key_filter) ;

//打一拍
always @(posedge sys_clk or negedge sys_rst_n)begin
	if (!sys_rst_n) begin
		key_filter_d0 <= 1'b1;
		end
	else 
		key_filter_d0 <= key_filter;
end


//控制蜂鸣器
always @(posedge sys_clk or negedge sys_rst_n)begin
	if (!sys_rst_n) 
		beep <= 1'b1;
	else if (neg_key_filter)
		beep <= ~beep;
	else
		beep <= beep;
end

endmodule 

5.3 顶层模块

module top_key_beep(
input 			sys_clk,
input 			sys_rst_n,
input 			key,
	
output 	 		beep
);

parameter CNT_MAX = 20'd1000000; //计时20ms	

wire key_filter;

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)
	); 
key_beep	
	u_key_filter(
	.sys_clk       (sys_clk),
	.sys_rst_n     (sys_rst_n),
	.key_filter    (key_filter), 
	.beep          (beep)
	);              
	
endmodule

6.仿真

6.1Testbench代码


`timescale 1ns / 1ns        //仿真单位/仿真精度

module tb_top_key_beep();

//parameter define
parameter  CLK_PERIOD = 20;           //时钟周期 20ns
parameter  CNT_MAX = 20'd10;          //消抖时间 200ns

//reg define
reg           sys_clk;
reg           sys_rst_n;
reg           key;

//wire define
wire          beep;

//信号初始化
initial begin
    sys_clk <= 1'b0;
    sys_rst_n <= 1'b0;
    key <= 1'b1;
    #200
    sys_rst_n <= 1'b1;
//key信号变化
    #20
    key <= 1'b0;
    #20
    key <= 1'b1;
    #50
    key <= 1'b0;  
    #40
    key <= 1'b1;
    #20
    key <= 1'b0;
    #300
    key <= 1'b1;
    #50
    key <= 1'b0;
    #40
    key <= 1'b1;
    #300
    key <= 1'b0;
end

//产生时钟
always #(CLK_PERIOD/2) sys_clk = ~sys_clk;

//例化待测设计
top_key_beep #(
    .CNT_MAX    (CNT_MAX)  
)u_top_key_beep(
    .sys_clk      (sys_clk),
    .sys_rst_n    (sys_rst_n),
    .key          (key),
    .beep         (beep)
    );

endmodule


6.2仿真波形

6.2.1按键消抖模块

在这里插入图片描述

6.2.2 蜂鸣器模块

在这里插入图片描述

6.2.3 TOP模块

在这里插入图片描述

六、上板验证

6.1XDC文件

#时序约束
create_clock -period 20.000 -name sys_clk [get_ports sys_clk]
#------------------------------系统时钟和复位-----------------------------------
set_property -dict {PACKAGE_PIN R4 IOSTANDARD LVCMOS33} [get_ports sys_clk]
set_property -dict {PACKAGE_PIN U2 IOSTANDARD LVCMOS33} [get_ports sys_rst_n]
#----------------------------------按键-----------------------------------------
set_property -dict {PACKAGE_PIN T1 IOSTANDARD LVCMOS33} [get_ports {key}]
#-----------------------------------蜂鸣器--------------------------------------
set_property -dict {PACKAGE_PIN P16 IOSTANDARD LVCMOS33} [get_ports beep]

6.2 RTL原理图

在这里插入图片描述

6.3 综合

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值