简单的去抖动例程

Ben*_*oit 8 embedded

你有简单的去抖程序来处理单个开关输入吗?

这是一个没有任何操作系统的简单裸机系统.

我想避免使用具有特定计数的循环结构,因为处理器速度可能会波动.

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.

  • @Tom,重点在于*是*没有去抖逻辑:你不需要它.开关'反弹'实际上只是一种人工制品,它是通过对机械接触簇的采样速度比设计运行时更快而引起的.通过降低采样率,您可以回避问题.(是的,视频刷新频率是大多数好开关的亮点) (3认同)