有4个按钮需要输入,为防止去抖,我需要使用ISR(中断服务程序)。 INT0和INT1中断向量可以处理开关1和2,但我们需要处理剩下的2个开关以防止去抖,我该怎么做?
答案 0 :(得分:0)
使用引脚中断进行去抖动的替代方法是使用周期性定时器中断(或系统时钟,如果有的话)。使用这种方法,您几乎可以获得无限制的去抖功能。
将硬件配置为每5-20毫秒生成一次滴答中断,您可以每次对引脚进行采样。您的去抖期将根据您的收集时间和您收集的样本数量来确定。对于每个按钮,您可以将每个样本存储为字节,半字或字的位,具体取决于使用的样本数量。
例如,简单的去抖动可以使用10毫秒的刻度并且只使用两个样本。在每次中断时,您都会遇到类似的内容:
const byte mask = 0x3; // this mask has N lsb's set,
// where N is the number of samples.
static bit debounced = 0; // this stores the debounced output of a button
static byte samples = 0; // this stores the raw samples
samples = samples << 1; // shift the samples to make room
samples |= ReadBit(theThingToDebounce); // for the new sample (and or it in)
if ((samples & mask) == 0x0) // test that all samples are 0
{
debounced = 0; // debounced output is 0
}
else if ((samples & mask) == mask) // test that all samples are 1
{
debounced = 1; // debounced output is 1
}
根据您的要求,这可以简化一些,或者更复杂。如果您需要在去抖按钮状态更改时向应用程序发出信号,则需要进行其他检查以查看先前状态是否与新状态相反,然后发出信号。如果您不需要这样做,那么您可以在每次调用时实际评估样本(以确定是否有去抖1或0)以检查按钮的状态。
以上剪辑可以很容易地变成真正的代码。可以使用mask
和samples
的类型以及mask
的值轻松更改样本数。更改周期将是您的滴答周期的配置,这将更加特定于设备。
通常,mask
可以基于N
样本定义,而不是手动更新。如果您想要一个数字集的N
个最低有效位,您可以实现这一点,但计算2^N-1
,或者在代码中更容易:(1<<N) - 1
。这为我们提供了一个新的定义:
const byte nSamples = 4;
const byte mask = (1 << nSamples) - 1; // 1 << 4 = 0x10, 0x10 - 1 = 0xF.
// This gives us a number with the four LSB's set.
要在多个引脚上运行此操作,您只需根据要监控的引脚数量使samples
和debounced
数组大小,然后在每个引脚的循环中执行算法销。