一、基本信息
- 按键消抖模块( key_debounce):对按键信号延时采样,将消抖后的按键信号和按键数据有效信号输出
至 beep_control 模块。 - 蜂鸣器控制模块( beep_control):根据输入的按键信号和按键数据有效信号,来控制蜂鸣器的鸣叫。
实际生成的RTL视图:
注意事项:
- 蜂鸣器默认驱动电流较小,需要修改驱动电流为12mA或16mA。
- 如果修改了默认的驱动电流,也需要同时修改默认的
I/O Standard
,否则会出现Pin <pin name> is missing an I/O standard assignment
错误。
二、代码编写
//----------------- Copyright (c) -----------------
// Copyright(C) ZHJ0125 2022
// All rights reserved
//-------------------------------------------------
// File Name : key_beep.v
// Created Date : 2022-04-15 15:51
// Modified Date : 2022-04-15 15:51
// Created By : ZHJ0125
// Last Version : V0.1
// Descriptions : 使用按键控制蜂鸣器发声。
// 初始状态为蜂鸣器(不)鸣叫,按下开关后蜂鸣器开始鸣叫;
// 再次按下开关,蜂鸣器停止鸣叫。以此循环。
//-------------------------------------------------
module key_beep(
input clk,
input rst_n,
input key,
output beep
);
wire key_flag;
wire key_value;
key_debounce u_key_debounce(
.clk(clk),
.rst_n(rst_n),
.key(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
//--------------------------------
// key_debounce:按键消抖模块
//--------------------------------
module key_debounce(
input clk,
input rst_n,
input key,
output reg key_flag,
output reg key_value
);
reg key_buf; // 暂存按键值
reg [19:0] counter; // 20ms-20bit
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
key_buf <= 1'b1;
counter <= 20'd0;
end
else begin
key_buf <= key;
if(key_buf != key) // 电平发生了变化,可能有按键被按下
counter <= 20'd1000_000;
else if(key_buf == key) // 电平处在保持状态时,计时20ms
if(counter > 20'd0)
counter <= counter - 1'd1;
else
counter <= counter;
else
counter <= counter;
end
end
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
key_flag <= 1'b0;
key_value <= 1'b1;
end
else begin
if(counter == 20'd1) begin // 电平状态保持了20ms,可以采样了
key_flag <= 1'b1;
key_value <= key;
end
else begin // 电平正在保持状态或者说还未保持20ms
key_flag <= 1'b0;
key_value <= key_value;
end
end
end
endmodule
//--------------------------------
// beep_control:蜂鸣器处理模块
//--------------------------------
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'b0; // 复位默认状态蜂鸣器(不)鸣叫
else begin
if(key_flag && ~(key_value)) // 按键被按下一次
beep <= ~beep;
else
beep <= beep;
end
end
endmodule