Verilog 按键消抖及控制蜂鸣器
程序员文章站
2024-02-24 23:28:52
...
参考:正点原子(http://www.openedv.com)——开拓者FPGA教程
RTL原理图:
top 程序:
//author: bronceyang
//time : 2020年4月16日
//version: 1.0
//功能:按键消抖;按键控制蜂鸣器的叫停
module beep_key(
input sys_clk,
input sys_rst_n,
input key,
output beep
);
//parameter define
// reg define
//wire define
wire key_value;
wire key_flag;
//********************************************
// main()
//*********************************************
//例化按键消抖模块
key_debounce u_key_debounce(
.sys_clk(sys_clk),
.sys_rst_n(sys_rst_n),
.key(key),
.key_value(key_value),
.key_flag(key_flag)
);
//例化按键控制蜂鸣器
beep_control u_beep_control(
.sys_clk(sys_clk),
.sys_rst_n(sys_rst_n),
.key_flag(key_flag),
.key_value(key_value),
.beep(beep)
);
endmodule
按键消抖程序:
//按键消抖模块
module key_debounce(
input sys_clk,
input sys_rst_n,
input key,
output reg key_value,
output reg key_flag
);
//parameter define
parameter CNT_20MS=32'd1_000_000;
//reg define
reg [31:0] cnt_delay;
reg key_reg;
//wire define
//*****************************************
// main
//****************************************
//检测到按键有变化时立刻赋值20ms,不变化时开始倒数计时
aaa@qq.com(posedge sys_clk or negedge sys_rst_n)begin
if (!sys_rst_n)begin
cnt_delay<=32'd0;
key_reg<=1'b1;
end
else begin
key_reg<=key;
if(key_reg!=key) //只要检测到按键变化就重新赋值20ms
cnt_delay<=CNT_20MS;
else begin //按键稳定时,开始计数20ms
if (cnt_delay>32'd0)
cnt_delay<=cnt_delay-1'b1;
else
cnt_delay<=cnt_delay;
end
end
end
//消抖结果输出
always @(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)begin
key_value<=1'b1; //复位状态
key_flag<=1'b0;
end
else begin
if (cnt_delay==32'd1)begin //按键稳定了20ms,已经消抖
key_value<=key;
key_flag<=1'b1;
end
else begin
key_value<=key_value;
key_flag<=1'b0;
end
end
end
endmodule
控制蜂鸣器输出:
//按键消抖结果控制蜂鸣器
module beep_control(
input sys_clk,
input sys_rst_n,
input key_value,
input key_flag,
output reg beep
);
//wire define
wire key_en; //按键检测结果
assign key_en=key_flag && (~key_value);
//控制输出
aaa@qq.com(posedge sys_clk or negedge sys_rst_n)begin
if (!sys_rst_n)
beep<=1'b0;
else if (key_en)
beep<=~beep;
end
endmodule
推荐阅读