实验要求
消抖实验:参考消抖模块,编写“key_denounce.v“。开发板上电后下载程序,按下“PL KEY3”按键,可以看到 4 个 LED 会变化,对应二进制数据,按一次加一。
实验原理
一般按键按下时会产生低于20ms的高频脉冲信号抖动,为消除按键抖动,提高按键检测的可靠性,FPGA程序设计每20ms检测一次按键的状态,当检测到有效下降沿,说明有按键按下,相应LED灯反转。
实验思路
每20ms检测一次按键的状态,如果检测到有效下降沿,说明有按键被按下,如果某按键被按下(Flag),相应LED亮灭情况反转(取反),否则亮灭情况不变。
key_denounce.v的Verilog代码:
module key_denounce(
input wire sys_clk, // 系统时钟,周期 20ns
input wire rst_n, // 复位信号,低电平有效
input wire key, // 按键输入
output reg [3:0] led // 4 个 LED 输出,高电平灯亮,低电平灯灭
);
// 按键消抖参数
parameter DEBOUNCE_TIME = 20'd1000000; // 消抖时间,假设时钟频率为 50MHz,20ms 消抖
reg [19:0] debounce_cnt;
reg key_reg;
// 按键消抖
always @(posedge sys_clk or negedge rst_n) begin
if (!rst_n) begin
debounce_cnt <= 20'd0;
key_reg <= 1'b1;
end else if (key != key_reg) begin
debounce_cnt <= debounce_cnt + 1;
if (debounce_cnt == DEBOUNCE_TIME) begin
key_reg <= key;
debounce_cnt <= 20'd0;
end
end else begin
debounce_cnt <= 20'd0;
end
end
// 按键下降沿检测
reg key_reg1;
wire key_neg_edge;
always @(posedge sys_clk or negedge rst_n) begin
if (!rst_n) begin
key_reg1 <= 1'b1;
end else begin
key_reg1 <= key_reg;
end
end
assign key_neg_edge = key_reg1 & ~key_reg;
// 计数器逻辑
reg [3:0] counter; // 增加一个中间计数器
always @(posedge sys_clk or negedge rst_n) begin
if (!rst_n) begin
counter <= 4'd0000; // 复位时计数器清零
led <= 4'b1111; // 复位时所有灯熄灭(高电平,因为后续要取反)
end else if (key_neg_edge) begin
counter <= counter + 1;
led <= ~counter; // 对计数器的值取反后赋给 led,以纠正灯的亮暗状态
end
end
endmodule
添加约束文件
############## clock and reset define##################
create_clock -period 20 [get_ports sys_clk]
set_property IOSTANDARD LVCMOS33 [get_ports {sys_clk}]
set_property PACKAGE_PIN U18 [get_ports {sys_clk}]
set_property IOSTANDARD LVCMOS33 [get_ports rst_n]
set_property PACKAGE_PIN M15 [get_ports rst_n]
#############LED Setting#############################
set_property PACKAGE_PIN J14 [get_ports {led[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[0]}]
set_property PACKAGE_PIN K14 [get_ports {led[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[1]}]
set_property PACKAGE_PIN J18 [get_ports {led[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[2]}]
set_property PACKAGE_PIN H18 [get_ports {led[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[3]}]
############## key define##############################
set_property PACKAGE_PIN M15 [get_ports {key[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {key[0]}]
set_property PACKAGE_PIN M14 [get_ports {key[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {key[1]}]
set_property PACKAGE_PIN L17 [get_ports {key[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {key[2]}]
set_property PACKAGE_PIN L16 [get_ports {key[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {key[3]}]
实验结果
开发板上电后下载程序,按下“PL KEY3”按键,可以看到 4 个LED会变化,对应二进制数据,按一次加一。
按下“PL KEY3”按键,LED显示为二进制1
再次按下“PL KEY3”按键,LED显示为二进制2
按下“PL KEY3”按键,LED显示为二进制3
再次按下“PL KEY3”按键,LED显示为二进制4