逐位整合的去抖操作符混淆

时间:2017-07-28 23:42:39

标签: c arrays embedded bit-manipulation debounce

我正在制作一个键盘,有些固件运行在用C编程的无线模块上。我正在尝试推出自己的去抖算法,并且可以使用一些帮助。基本上,这是代码的布局方式:

#define DEBOUNCE 5 - 这个值可以是从1(不可取,不是真正的去抖)到无穷大的任何值(由于显而易见的原因,也是不可取的)。我正在使用它去除32个按钮,所以我接下来使用:

创建一个32位整数数组

static uint32_t key_integration[DEBOUNCE];

在每次扫描输入(1KHz轮询速率)时,我将数组的倒数第二个项目移动到最后一个,倒数第三个到第二个到最后一个等等,直到我最后将键的原始扫描输入到第0个数组项中。 (旁边的问题:这样做的简单方法不仅仅是迭代从0到DEBOUNCE-2的循环?如果我有一个(32 * DEBOUNCE)位整数,我只会使用按位移位,但是......无论如何。)

现在我遇到困难的棘手部分:将数组结果与当前(去抖动)键状态进行比较。基本上,如果key_integration int的位X是1是所有数组,我想用当前(去抖动)键状态对其进行异或,以查看它是否已更改。如果key_integration int的每个位X在所有数组上都是0,我想做同样的事情。如果位X在数组中分散为1和0,那么它仍然在去抖动,不需要进行比较。

我目前对如何将key_integration数组与去抖键状态int进行比较感到困惑。我真的很感激建议如何A)比较它们,或B)重构代码以更简单的方式完成相同的结果。我绝对不能相信我所想到的是最好的方法。

1 个答案:

答案 0 :(得分:0)

您可以非常轻松地计算哪些键始终为零或始终为1的掩码(伪代码)

alwaysZ = -1
alwaysO = -1
for (int i = 0; i < DEBOUNCE; i++)
    alwaysZ &= ~keys[i]
    alwaysO &= keys[i]

通过它可以非常简单地确定哪些键保持不变(但两种极性):stable = alwaysZ | alwaysO

虽然这需要在每个投票时刻进行重新计算,但这是可以避免的。显然,如果第i位设置的次数为0或stable[i](可能为DEBOUNCE,则会设置位DEBOUNCE - 1,具体取决于您将该常量定义为意思是,但关键是它将是0或&#34;一切&#34;)。所以这里有一个替代方案:保留一组计数,它会计算每个按钮在整个去抖窗口中被发现处于向下状态的次数。在每个当前按下的按钮上添加一个,从按下DEBOUNCE步骤的每个按钮中减去一个。

使用计数数组,您可以判断每个按钮是否在恒定时间内保持稳定,与去抖动量无关。作为一个缺点,您必须明确检查每个计数,而使用位掩码,您可以立即确定任何按钮是否稳定,然后提前退出。

对于附带问题,您可以使用标准circular buffer技术来避免移动数据本身,只需通过调整索引来虚拟移动数据。但这也不是免费的,因为DEBOUNCE = 5我不会这样做。由于开销不变,它可以很好地扩展到巨大的去抖值。你通常可以避免使用实际的模运算,因为你只是递增一个索引(所以如果你到达结尾就可以递增并返回0),而不是随机索引到缓冲区的中间。