按键控制蜂鸣器
一、实验任务
本节实验任务是使用领航者上的 PL KEY0 按键来控制蜂鸣器发声。初始状态为蜂鸣器鸣叫,按下按
键后蜂鸣器停止鸣叫,再次按下开关,蜂鸣器重新鸣叫。
二、程序设计
软件消抖的原理主要为按键按下或松开后,由处理器延时 5ms 至 20ms,然后再对按键状态进行采样并判断
- 蜂鸣器是高电平有效
- 按键是低电平有效
- 物理按键需要消抖,所以需要一个消抖模块
设计文件
三个模块分别是三个.v文件,顶层模块只做例化
//顶层模块
module key_beep (
input sys_clk,
input sys_rst_n,
input key,
output beep
);
wire key_value;
wire key_flag;
key_deshake u_ke_deshake (
.sys_clk (sys_clk ),
.sys_rst_n(sys_rst_n),
.key (key ),
.key_flag (key_flag ),
.key_value(key_value)
);
beep_control u_beep_contol (
.sys_clk (sys_clk ),
.sys_rst_n(sys_rst_n),
.key_flag (key_flag ),
.key_value(key_value),
.beep (beep )
);
endmodule
//消抖模块
module key_deshake(
input sys_clk ,
input sys_rst_n ,
input key , //按键值
output key_value , //消抖后的key值
output key_flag //消抖后的按键值的有效标志
);
reg [19:0] cnt;
reg key_reg ; //记录上一次的key的值
always @(posedge sys_clk or negedge sys_rst_n) begin
if (!sys_rst_n) begin
// reset
key_reg <= 1'b1; //按键初始值是高电平
cnt <= 20'd0;
end
else begin
key_reg <= key;
if (key_reg != key)
cnt <= 20'd1000_000; //前后两次值不一样说明按键了
else begin
if(cnt > 20'd0)
cnt <= cnt - 1'b1; //开始倒数
else
cnt <= 20'd0;
end
end
end
always @(posedge sys_clk or posedge sys_rst_n) begin
if (!sys_rst_n) begin
// reset
key_flag <= 1'b0;
key_value <= 1'b1;
end
//当倒数到1时将按键值送出去,完成消抖
else if (cnt == 20'd1) begin
key_value <= key;
key_flag <= 1'b1;
end
else begin
key_value <= key_value;
key_flag <= 1'b0;
end
end
endmodule
//控制蜂鸣器模块
module beep_control(
input sys_clk ,
input sys_rst_n ,
input key_value ,
input key_flag ,
output beep
);
always @(posedge sys_clk or negedge sys_rst_n) begin
if (!sys_rst_n) begin
// reset
beep <= 1'b1;
end
else if (key_flag == 1'b1 && key_value == 1'b0) begin
beep <= ~beep;
end
end
endmodule
tb文件