FPGA之按键控制蜂鸣器

目的:按键按下的时候,改变蜂鸣器的状态(本次采用有源蜂鸣器)

蜂鸣器,根据有无震荡源分为有源蜂鸣器和无源蜂鸣器。从背面有无电路板可以区分,背面封起来的为有源蜂鸣器,背面有电路板的为无源蜂鸣器。
判断正负极:
长的引脚是正极,短的引脚是负极;或正面有加号的是正极,对应的另一端即为负极。
有源蜂鸣器,如下图,工作只需提供直流电压,但是只能发出一种声音。(本次采用有源蜂鸣器)
在这里插入图片描述
无源蜂鸣器,如下图,工作需要震荡信号(不断变化的高低电平),可以改变震荡频率来改变声音。
在这里插入图片描述
蜂鸣器原理图
在这里插入图片描述
按键的消抖
本次的按键消抖方法是检测按键信号稳定20ms即可。
在这里插入图片描述
本次系统框图
在这里插入图片描述
顶层模块原理图
在这里插入图片描述
代码实现:
top_key_beep模块代码(顶层模块)

//顶层模块
module top_key_beep(
    input  sys_clk,     //时钟信号50Mhz
    input  sys_rst_n,   //复位信号
    
    input  key,         //按键信号
    output keep         //蜂鸣器控制信号
);

//wire define
wire key_value;
wire key_flag;

/* 例化两个子模块 */
//例化按键消抖模块
key_debounce u_key_debounce(
    .sys_clk    (sys_clk),
    .sys_rst_n  (sys_rst_n),
    
    .key        (key),
    .key_flag   (key_flag),
    .key_value  (key_value)
);

//例化蜂鸣器控制模块
beep_control u_beep_control(
    .sys_clk    (sys_clk),
    .sys_rst_n  (sys_rst_n),
    
    .key_flag   (key_flah),
    .key_value  (key_value),
    .beep       (beep)
    
);
endmodule

key_debounce模块代码

//通过计数消除机械按键抖动
module key_debounce(
    input       sys_clk,    //外部50M时钟
    input       sys_rst_n,  //外部复位信号,低有效
    
    input       key,        //外部按键输入
    output reg  key_flag,   //按键数据有效信号
    output reg  key_value   //按键消抖后的数据
);
//reg define
reg [31:0] delay_cnt;  //计数器,对系统时钟计数,在按键抖动发生之后没去判断按键什么时候稳定达20ms
reg        key_reg;    //寄存按键的数据

//在按键状态改变后倒计时
always @(posedge sys_clk or negedge sys_rst_n) begin
    if (!sys_rst_n) begin
        key_reg <= 1'b1;    //外部的按键在没按下的时候保持高电平
        delay_cnt <= 32'd0; //计数器清零
    end
    else begin
    key_reg <= key;//key_reg记录上一个时钟周期按键的数据
    if(key_reg != key) //一旦检测到按键状态发生变化(有按键被按下或释放),与当前按键状态作比较
        delay_cnt <= 32'd1000000;//给延时计数器重新装载初始值(计数时间为20ms)
    else if(key_reg == key) begin //在按键状态稳定时,计数器递减,开始20ms倒计时
        if(delay_cnt > 32'd0)
            delay_cnt <= delay_cnt - 1'b1;
        else
            delay_cnt <= delay_cnt;
        end
   end
end

always @(posedge sys_clk or negedge sys_rst_n) begin
    if(!sys_rst_n) begin
        key_flag <= 1'b0;
        key_flag <= 1'b1;
    end
    else begin
        if(delay_cnt == 32'd1) begin  //当计数器递减到1时,说明按键稳定状态维持了20ms
            key_flag <= 1'b1; //此时按键消抖过程结束,给出一个时钟周期的标志信号
            key_value <= key; //并寄存此时按键的值,此时为有效信号
        end
        else begin
           key_flag <= 1'b0;
           key_value <= key_value;
        end
    end
end

endmodule

beep_control模块

//按键控制蜂鸣器
module beep_control(
    input          sys_clk,     //系统时钟
    input          sys_rst_n,   //复位信号,低电平有效
    
    input          key_flag,    //按键有效信号
    input          key_value,   //消抖后的按键信号
    output  reg    beep         //蜂鸣器控制信号
);

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

endmodule

设置管脚,编译下载到板子上。

发布了10 篇原创文章 · 获赞 17 · 访问量 3632

猜你喜欢

转载自blog.csdn.net/yijiancmy/article/details/104184121
今日推荐