FPGA实现按键控制蜂鸣器实验

**

FPGA实现按键控制蜂鸣器实验

**

实现功能:

使用按键控制蜂鸣器发声。初始状态为蜂鸣器鸣叫,按下开关后蜂鸣器停止鸣叫,再次按下开关,蜂鸣器重新鸣叫。

设计思路

由实验任务可知,我们只需要在按键按下时改变蜂鸣器的鸣叫状态,但实际上在按键按下的过程中存在按键抖动的干扰,体现在数字电路中就是不断变化的高低电平,为避免在抖动过程中采集到错误的按键状态,我们需要对按键数据进行消除抖动处理。因此本系统应至少包含按键消抖模块和蜂鸣器控制模块,
按键控制蜂鸣器系统框图如图所示。
在这里插入图片描述

代码

顶层模块:

module top_key_beep(
input       clk,
input       rst_n,
input       key,

output      beep
);

wire   key_value;
wire   key_flag;

key_filter    u_key_filter(
    .clk           (clk),
	.rst_n         (rst_n),
	.key_in        (key),
	.key_flag      (key_flag),
	.key_value     (key_value)

);

beep_control    u_beep_control(
    .clk           (clk),
	.rst_n         (rst_n),
	.key_flag      (key_flag),
	.key_value     (key_value),
	.beep          (beep)

);

endmodule 

按键消抖模块:

module key_filter(
    input     clk     ,       //时钟
    input     rst_n   ,       //复位
    input     key_in  ,       //按键信息

    output  reg   key_flag,       //按键有效标志,消抖后的
    output  reg   key_value       //有效的按键信息输出
);

reg  [19:0]   cnt_20ms;       //20ms计数器
reg           key_r0  ;       //按键同步信号
reg           key_r1  ;       //按键打拍信号
reg           add_flag;       //20ms计数器开始计数标志

wire          add_cnt_20ms;   //计数器加一条件
wire          end_cnt_20ms;   //计数器结束条件

wire          n_edge      ;   //按键按下的下降沿

//对按下的按键进行同步、打拍
always @(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        key_r0<=1'b1;
        key_r1<=1'b1;    
    end
    else begin
        key_r0<=key_in;
        key_r1<=key_r0;
    end
end

//下降沿检测
assign n_edge=~key_r0&key_r1;

//20ms计数器
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        cnt_20ms <= 20'b0;    
    end
    else if(add_cnt_20ms)begin
        if(end_cnt_20ms)
            cnt_20ms<=20'b0;
        else
            cnt_20ms<=cnt_20ms + 1;
    end
end
assign add_cnt_20ms = add_flag;  
assign end_cnt_20ms = add_cnt_20ms && cnt_20ms== 1_000_000 - 1;

//add_flag
always @(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        add_flag<=1'b0;
    end
    else if(n_edge!=1'b0)begin
        add_flag<=1'b1;
    end
    else if(end_cnt_20ms)begin
        add_flag<=1'b0;
    end
end

//寄存按键信息key_value
always @(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        key_value<=1'b1;
        key_flag<=1'b0;
    end
    else if(end_cnt_20ms)begin
        key_value<=key_r1;
        key_flag<=1'b1;
    end
    else begin
        key_value<=1'b1;
        key_flag<=1'b0;
    end
end

endmodule

蜂鸣器控制模块:

module beep_control(
input      clk,     //时钟
input      rst_n,   //复位

input      key_flag,    //按键标志
input      key_value,   //有效按键

output reg beep        
);

always @(posedge clk or negedge rst_n)begin
	if (!rst_n)                         
	    beep <= 1'b1;                       
	else if (key_flag &&(~key_value))       
		beep <= ~beep;                      
end

endmodule 
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值