你有没有一个简单的去抖动例程来处理单个开关输入?
这是一个没有任何操作系统的简单裸机系统。
我希望避免使用特定计数的循环构造,因为处理器速度可能会波动。
发布于 2008-09-30 21:18:23
我认为你可以在这里学到很多关于这方面的知识: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;
}
}}
发布于 2008-10-02 21:43:19
最简单的解决方案通常是最好的,我发现简单地每N毫秒读取开关状态(根据开关的不同,在10到50之间)对我来说总是有效的。
我已经剔除了破碎和复杂的去反跳例程,并将它们替换为一个简单的慢速轮询,这样的结果总是足够好的。
要实现它,您需要在您的系统上使用一个简单的定期计时器中断(假设没有RTOS支持),但是如果您习惯于在裸机上对其进行编程,那么这应该不难安排。
注意,这种简单的方法增加了对状态改变的检测的延迟。如果开关需要T ms才能达到新的稳定状态,并且每隔X ms轮询一次,那么检测压力的最坏情况延迟是T+X ms。轮询间隔X必须大于最坏情况下的反弹时间T。
发布于 2008-09-30 21:27:13
没有一个简单的解决方案可以适用于所有类型的按钮。无论这里的人告诉你使用什么,你都必须在你的硬件上尝试一下,看看它有多好用。看看示波器上的信号,确保你真的知道发生了什么。Rich B的pdf链接看起来是一个很好的起点。
https://stackoverflow.com/questions/155071
复制相似问题