硬件: 锆石A4开发板,Altera EP4CE10F17C8
语言: Verilog HDL
原理 : 机械式按键大概有20ms的抖动,所以检测到按键变化后等20ms再判断一次,如果键值相同才视为有效;
顶级模块 按键切换LED显示
module Key(led,key,clock,reset);
input clock,reset;
input [7:0] key;
output [7:0] led;
wire [7:0] keyVal;//消除抖动后的按键值
reg [7:0] led; //控制显示的寄存器
reg [7:0] led_next;
//消抖
KeyDebounced kd1(.keyVal(keyVal),.key(key),.clock(clock),.reset(reset));
//时序电路
always @(posedge clock,negedge reset)
begin
if(!reset)
led <= 8'h0;
else
led <= led_next;
end
//组合电路 给显示寄存器leds赋值
always @(keyVal)
led_next = led ^ keyVal;
endmodule
按键消抖模块
module KeyDebounced(keyVal,key,clock,reset);
parameter KeyCnt = 8;//默认8个按键
parameter TIME = 20'd999_999;//50Mhz 0.02us 20ms 10^6-1
input clock,reset;
input [7:0] key;
output [7:0] keyVal;//输出稳定的键值
reg [19:0] time_cnt;
reg [19:0] time_cnt_next;
reg [KeyCnt-1:0] key_reg;
reg [KeyCnt-1:0] key_reg_next;
//时序电路 给定时器赋值
always @(posedge clock,negedge reset)
begin
if(!reset)
time_cnt <= 20'h0;
else
time_cnt <= time_cnt_next;
end
//组合电路 实现定时器
always @(*)
begin
if(time_cnt == TIME)
time_cnt_next = 20'h0;
else
time_cnt_next =time_cnt + 20'h1;
end
//时序电路 给按键寄存器赋值
always @(posedge clock,negedge reset)
begin
if(!reset)
key_reg <= 8'h0;
else
key_reg <= key_reg_next;
end
//组合电路 每隔一个定时器周期接受依次按键的值
always @(*)
begin
if(time_cnt == TIME)
key_reg_next = key;
else
key_reg_next <= key_reg;
end
assign keyVal = key_reg & (~key_reg_next);
endmodule