static inline uint8_t elapsed_ge(uint16_t start, uint16_t delay)
{
uint16_t now = TIM10NOW;
return (uint16_t)(now - start) >= delay;
}
typedef struct {
uint8_t stable; // 去抖后的稳定状态(0/1)
uint8_t last_raw; // 上一次采样的原始状态
uint8_t debouncing; // 是否正在去抖
uint16_t t0; // 去抖开始时间
} KeyDebounce_t;
#define DEBOUNCE_TICKS (20u * 2u) // 例:20ms,若 500us/tick => 1ms=2tick
uint8_t Key_Update(KeyDebounce_t *k)
{
uint8_t raw = KEY_READ(); // 当前原始电平/状态
uint8_t event = 0;
// 1) 检测到原始输入变化:启动去抖计时
if (!k->debouncing) {
if (raw != k->stable) {
k->debouncing = 1;
k->t0 = TIM10NOW;
k->last_raw = raw;
}
return 0;
}
// 2) 去抖期间,如果又变了:重新计时(说明还在抖)
if (raw != k->last_raw) {
k->last_raw = raw;
k->t0 = TIM10NOW;
return 0;
}
// 3) 原始输入保持不变满 debounce 时间:确认稳定改变
if (elapsed_ge(k->t0, DEBOUNCE_TICKS)) {
k->debouncing = 0;
// 此时 raw 持续稳定,更新 stable
if (k->stable != raw) {
k->stable = raw;
// 产生事件:例如 stable 变成“按下电平”
if (k->stable == KEY_PRESSED_LEVEL) {
event = 1; // 按下事件
}
}
}
return event;
}