目的:按键按下的时候,改变蜂鸣器的状态(本次采用有源蜂鸣器)
蜂鸣器,根据有无震荡源分为有源蜂鸣器和无源蜂鸣器。从背面有无电路板可以区分,背面封起来的为有源蜂鸣器,背面有电路板的为无源蜂鸣器。
判断正负极:
长的引脚是正极,短的引脚是负极;或正面有加号的是正极,对应的另一端即为负极。
有源蜂鸣器,如下图,工作只需提供直流电压,但是只能发出一种声音。(本次采用有源蜂鸣器)
无源蜂鸣器,如下图,工作需要震荡信号(不断变化的高低电平),可以改变震荡频率来改变声音。
蜂鸣器原理图
按键的消抖
本次的按键消抖方法是检测按键信号稳定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
设置管脚,编译下载到板子上。