GEO*_*HET 11
我想你可以在这里学到很多东西:http://www.ganssle.com/debouncing.pdf
如果可能的话,你最好的选择是硬件,但也有一些关于软件的想法.
来自TFA的简单示例代码:
#define CHECK_MSEC 5 // Read hardware every 5 msec
#define PRESS_MSEC 10 // Stable time before registering pressed
#define RELEASE_MSEC 100 // Stable time before registering released
// This function reads the key state from the hardware.
extern bool_t RawKeyPressed();
// This holds the debounced state of the key.
bool_t DebouncedKeyPress = false;
// Service routine called every CHECK_MSEC to
// debounce both edges
void DebounceSwitch1(bool_t *Key_changed, bool_t *Key_pressed)
{
static uint8_t Count = RELEASE_MSEC / CHECK_MSEC;
bool_t RawState;
*Key_changed = false;
*Key_pressed = DebouncedKeyPress;
RawState = RawKeyPressed();
if (RawState == DebouncedKeyPress) {
// Set the timer which allows a change from current state.
if (DebouncedKeyPress) Count = RELEASE_MSEC / CHECK_MSEC;
else Count = PRESS_MSEC / CHECK_MSEC;
} else {
// Key has changed - wait for new state to become stable.
if (--Count == 0) {
// Timer expired - accept the change.
DebouncedKeyPress = RawState;
*Key_changed=true;
*Key_pressed=DebouncedKeyPress;
// And reset the timer.
if (DebouncedKeyPress) Count = RELEASE_MSEC / CHECK_MSEC;
else Count = PRESS_MSEC / CHECK_MSEC;
}
}
Run Code Online (Sandbox Code Playgroud)
}
Rod*_*ddy 11
最简单的解决方案通常是最好的,我发现只需每N毫秒读取一次开关状态(10到50之间,取决于开关)一直对我有用.
我已经删除了破碎和复杂的去抖动程序,并用一个简单的慢速轮询代替它们,结果总是那么好.
要实现它,你需要在你的系统上有一个简单的周期性定时器中断(假设没有RTOS支持),但是如果你习惯用裸机编程,这应该不难安排.
请注意,这种简单的方法会增加检测状态变化的延迟.如果一个开关需要T ms达到一个新的稳定状态,并且每隔X ms轮询一次,那么检测到压力的最坏情况延迟是T + X ms.您的轮询间隔X 必须大于最差情况下的反弹时间T.