if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_14)==1)
{
delay_ms(20);//延时20ms再去检测按键值
if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_14)==0) // 相当于下降沿
{
KEY1 = 1; //表示KEY1被按下
}
}
typedef struct _Key_t
{
u32 last_time;
enum
{
May_Press,
Release,
}private_state;
enum
{
No_Press,
Short_Press,
Long_Press,
}state;
}Key_t;
if(key_state.private_state==Release)
{
if(KEY==0)
{
key_state.private_state=May_Press;
key_state.last_time=course_ms();
}
}
else if(key_state.private_state==May_Press)
{
if(KEY==1)
{
if((course_ms()-key_state.last_time>10)&&(course_ms()-key_state.last_time
{
key_state.state=Short_Press;
key_state.private_state=Release;
}
else if(course_ms()-key_state.last_time>Is_ShortPress_Threshold)
{
key_state.state=Long_Press;
key_state.private_state=Release;
}
else
key_state.private_state=Release;
}
}
module debounce( input wire clk, nrst, input wire key_in, output reg key_out
); // 20ms parameter// localparam TIME_20MS = 1_000_000;
localparam TIME_20MS = 1_000; // just for test // variable
reg [20:0] cnt; reg key_cnt;
// debounce time passed, refresh key state
always @(posedge clk or negedge nrst) begin
if(nrst == 0)
key_out <= 0; else if(cnt == TIME_20MS - 1)
key_out <= key_in; end
// while in debounce state, count, otherwise 0
always @(posedge clk or negedge nrst) begin
if(nrst == 0)
cnt <= 0; else if(key_cnt)
cnt <= cnt + 1'b1;
else
cnt <= 0;
end
//
always @(posedge clk or negedge nrst) begin
if(nrst == 0)
key_cnt <= 0; else if(key_cnt == 0 && key_in != key_out)
key_cnt <= 1; else if(cnt == TIME_20MS - 1)
key_cnt <= 0; endendmodule
module debounce( input wire clk, nrst, input wire key_in, output reg key_out
);// localparam TIME_20MS = 1_000_000;
localparam TIME_20MS = 1_000; reg key_cnt; reg [20:0] cnt; always @(posedge clk or negedge nrst) begin
if(nrst == 0)
key_cnt <= 0; else if(cnt == TIME_20MS - 1)
key_cnt <= 0; else if(key_cnt == 0 && key_out != key_in)
key_cnt <= 1; end
always @(posedge clk or negedge nrst) begin
if(nrst == 0)
cnt <= 0; else if(key_cnt) begin
if(key_out == key_in)
cnt <= 0; else
cnt <= cnt + 1'b1;
end
else
cnt <= 0; end
always @(posedge clk or negedge nrst) begin
if(nrst == 0)
key_out <= 0; else if(cnt == TIME_20MS - 1)
key_out <= key_in; endendmodule
module debounce( input wire clk, nrst, input wire key_in, output reg key_out
);// localparam TIME_20MS = 1_000_000;
localparam TIME_20MS = 1_000; // just for test
reg key_cnt; reg [20:0] cnt; always @(posedge clk or negedge nrst) begin
if(nrst == 0)
key_cnt <= 0; else if(key_cnt == 0 && key_out != key_in)
key_cnt <= 1; else if(cnt == TIME_20MS - 1)
key_cnt <= 0; end
always @(posedge clk or negedge nrst) begin
if(nrst == 0)
cnt <= 0; else if(key_cnt)
cnt <= cnt + 1'b1;
else
cnt <= 0; end
always @(posedge clk or negedge nrst) begin
if(nrst == 0)
key_out <= 0; else if(key_cnt == 0 && key_out != key_in)
key_out <= key_in; endendmodule
// 按键消抖测试电路// 时间单位`timescale 1ns/10ps// modulemodule debounce_tb; // time period parameter
localparam T = 20; // variable
reg clk, nrst; reg key_in; wire key_out; // instantiate debounce uut(
.clk (clk ),
.nrst (nrst ),
.key_in (key_in ),
.key_out(key_out)
); // clock
initial begin
clk = 1; forever #(T/2) clk = ~clk; end
// reset
initial begin
nrst = 1;
@(negedge clk) nrst = 0;
@(negedge clk) nrst = 1; end
// key_in
initial begin
// initial value
key_in = 0;
// wait reset
repeat(3) @(negedge clk);
// no bounce // key down
key_in = 1; // last 60ms
repeat(3000) @(negedge clk); // key up
key_in = 0; // wait 50ms
repeat(2500) @(negedge clk); // down 5ms, up 15ms // key down, bounce 5ms
repeat(251) @(negedge clk) key_in = ~key_in; // last 60ms
repeat(3000) @(negedge clk); // key up, bounce 15ms
repeat(751) @(negedge clk) key_in = ~key_in; // wait 50ms
repeat(2500) @(negedge clk); // down 19ms, up 19ms // key down, bounce 19ms
repeat(951) @(negedge clk) key_in = ~key_in; // last 60ms
repeat(3000) @(negedge clk); // key up, bounce 19ms
repeat(951) @(negedge clk) key_in = ~key_in; // wait 50ms
repeat(2500) @(negedge clk);
// additional, this situation shoud not ever happen // down 25ms, up 25ms // key down, bounce 25ms
repeat(1251) @(negedge clk) key_in = ~key_in; // last 60ms
repeat(3000) @(negedge clk); // key up, bounce 25ms
repeat(1251) @(negedge clk) key_in = ~key_in; // wait 50ms
repeat(2500) @(negedge clk); // stop $stop; endendmodule
-END-
推荐阅读