消抖程序用于消除按键或开关在按下或释放时产生的抖动,从而提高系统的稳定性和可靠性。以下是几种常见的消抖程序写法:
按键消抖程序(使用状态机)
```verilog
module key_jitter(
input clkin, // 输入时钟信号
input key_in, // 按键输入
output reg key_value, // 输出按键值
output reg [15:0] tout // 输出定时器
);
reg [1:0] key_in_r; // 内部信号,用于存储按键输入
wire pp; // 用于检测按键输入是否有变化
reg [19:0] cnt_base; // 计数器,用于延时
reg key_value_r; // 存储最终的按键值
always @(posedge clkin) begin
key_in_r <= `UD {key_in_r, key_in}; // 更新按键输入
end
always @(posedge clkin) begin
if (pp == 1'b1) begin
cnt_base <= `UD 20'h0000; // 重置计数器
end else begin
cnt_base <= `UD cnt_base + 1; // 计数器递增
end
end
always @(posedge clkin) begin
if (cnt_base == 20'hFFFF) begin
key_value_r <= `UD key_in_r; // 输出按键值
end
end
assign pp = key_in_r ^ key_in_r; // 检测按键输入是否有变化
endmodule
```
按键消抖程序(使用延时)
```c
define DEBOUNCE_TIME 20 // 消抖计时时间,单位为毫秒(ms)
define KEY_PRESSED 0 // 按键按下状态值
define KEY_RELEASED 1 // 按键松开状态值
int readKey() {
static int keyState = KEY_RELEASED; // 按键状态变量,初值为松开
static int prevKeyState = KEY_RELEASED; // 之前的按键状态变量,初值为松开
static unsigned long prevDebounceTime = 0; // 上一次消抖时间戳,初值为0
int keyReading = digitalRead(KEY_PIN); // 读取按键状态值
unsigned long curTime = millis(); // 获取当前时间戳
if (keyReading != prevKeyState) {
prevDebounceTime = curTime; // 更新消抖时间戳
}
if ((curTime - prevDebounceTime) > DEBOUNCE_TIME) {
if (keyReading != keyState) {
keyState = keyReading; // 更新按键状态
}
}
return keyState;
}
```
按键消抖程序(使用中断)
```c
include "STC32G_GPIO.h"
include "STC32G_Delay.h"
include "STC32G_NVIC.h"
include "STC32G_Exti.h"
void GPIO_Init(void) {
P3_MODE_IN_HIZ(GPIO_Pin_2); // 将外部中断引脚配置为高阻输入
P3_PULL_UP_ENABLE(GPIO_Pin_2); // 将外部中断引脚使能上拉电阻
P2_MODE_OUT_PP(GPIO_Pin_7); // 将点灯引脚初始化为推挽输出
}
void Exti_Init(void) {
EXTI_InitTypeDef initer;
initer.EXTI_Line = EXTI_Line2;
initer.EXTI_Mode = EXTI_Mode_Interrupt;
initer.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_Init(&initer);
NVIC_EnableIRQ(EXTI2_IRQn); // 启用外部中断
}
void EXTI2_IRQHandler(void) {
// 处理按键中断事件
}
```
这些程序分别使用状态机、延时和中断的方法来实现按键消抖。选择哪种方法取决于具体的应用场景和硬件平台。