前面测试了LED,和按键,这一篇结合按键测试蜂鸣器,并实现按键防抖。
参考https://bbs.eeworld.com.cn/thread-1234259-1-1.html
新建工程beep
创建key.v实现按键识别支持防抖。
创建beep.v实现蜂鸣器控制。
创建顶层文件top.v实例化上述模块实现按键控制蜂鸣器。
beep.v
`define PERIOD 32'd25000
`define DUTY 32'd12500
module beep(
//input
input sys_clk,
input sys_rst_n,
input key_flag,
input key_value,
output beepout
);
//reg define
reg [31:0] period_cnt ;
reg [31:0] duty_cycle ;
reg onoff;
//*****************************************************
//** main code
//*****************************************************
assign beepout = (period_cnt >= duty_cycle && onoff) ? 1'b1 : 1'b0;
always @(posedge sys_clk or negedge sys_rst_n) begin
if(!sys_rst_n) begin
period_cnt <= 32'd0;
duty_cycle <= `DUTY;
end
else if(period_cnt == `PERIOD)
period_cnt <= 32'd0;
else
period_cnt <= period_cnt + 1'b1;
end
always @ (posedge sys_clk or negedge sys_rst_n) begin
if(!sys_rst_n) begin
onoff <= 1'b0;
end
else begin
if(key_flag && (~key_value)) begin
onoff <= ~onoff;
//if(onoff)
//beepout <= (period_cnt >= duty_cycle) ? 1'b1 : 1'b0;
//else
// beepout <= 1'b0;
end
end
end
endmodule
key.v
module key(
input sys_clk,
input sys_rst_n,
input key,
output reg key_flag,
output reg key_value
);
//reg define
reg [31:0] delay_cnt;
reg key_reg0;
reg key_reg1;
//*****************************************************
//** main code
//*****************************************************
always @(posedge sys_clk or negedge sys_rst_n) begin
if (!sys_rst_n) begin
key_reg0 <= 1'b1;
key_reg1 <= 1'b1;
delay_cnt <= 32'd0;
end
else begin
key_reg0 <= key;
key_reg1 <= key_reg0;
if(key_reg1 != key_reg0)
delay_cnt <= 32'd500000;
else if(key_reg1 == key_reg0) begin
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_value <= 1'b1;
end
else begin
if(delay_cnt == 32'd1) begin
key_flag <= 1'b1;
key_value <= key_reg1;
end
else begin
key_flag <= 1'b0;
key_value <= key_value;
end
end
end
endmodule
beep_key_top.v
module beep_key_top(
input sys_clk,
input sys_rst_n,
input key,
output beep
);
//wire define
wire key_value;
wire key_flag;
//*****************************************************
//** main code
//*****************************************************
key u_key(
.sys_clk (sys_clk),
.sys_rst_n (sys_rst_n),
.key (key),
.key_flag (key_flag),
.key_value (key_value)
);
beep u_beep(
.sys_clk (sys_clk),
.sys_rst_n (sys_rst_n),
.key_flag (key_flag),
.key_value (key_value),
.beepout (beep)
);
endmodule
自动选择的顶层文件可能不对手动设置
top.v上右键选择Set As Top
从原理图可以看到
25M时钟输入对应D7
没有专门的复位按键就使用KEY0 H3
原理图中KEY1和KEY2对应H2 G3对应代码中的KEY0和KEY1
蜂鸣器对应B10
约束如下
按键KEY0复位
按键KEY1 蜂鸣器响,再按蜂鸣器停止响。
以上实现了按键控制蜂鸣器,主要是按键防抖的思想。
引用: 火辣西米秀 发表于 2023-3-5 22:09 按键防抖是按键都需要有,楼主的防抖代码有什么特点
没什么特别的一般做法