逐位积分去Bounce算子混淆

逐位积分去Bounce算子混淆,c,arrays,embedded,bit-manipulation,debounce,C,Arrays,Embedded,Bit Manipulation,Debounce,我正在制作一个键盘,一些固件运行在一个用C语言编程的无线模块上。我正在尝试使用我自己的去盎司算法,可能需要一些帮助。基本上,以下是代码的布局方式: #定义去盎司5-该值可以是从1(不可取,不是真正的去盎司)到无穷大(出于明显原因,也不可取)的任何值。我将使用此命令取消32个按钮的抖动,因此接下来我将使用以下命令创建一个32位整数数组: 静态uint32键集成[DEBOUNCE] 在每次扫描输入(1KHz轮询率)时,我将数组的倒数第二项移动到最后一项,将第三项移动到最后一项,将第二项移动到最后一项

我正在制作一个键盘,一些固件运行在一个用C语言编程的无线模块上。我正在尝试使用我自己的去盎司算法,可能需要一些帮助。基本上,以下是代码的布局方式:

#定义去盎司5
-该值可以是从1(不可取,不是真正的去盎司)到无穷大(出于明显原因,也不可取)的任何值。我将使用此命令取消32个按钮的抖动,因此接下来我将使用以下命令创建一个32位整数数组:

静态uint32键集成[DEBOUNCE]

在每次扫描输入(1KHz轮询率)时,我将数组的倒数第二项移动到最后一项,将第三项移动到最后一项,将第二项移动到最后一项,以此类推,直到最后将键的原始扫描输入到第0个数组项。(附带问题:这比循环从0到去盎司2更容易实现?如果我有一个(32*去盎司)位整数,我只会使用逐位移位,但是……无论如何。)

现在,我遇到困难的棘手部分是:将数组结果与当前(取消抖动的)键状态进行比较。本质上,若key_integration int的X位是1,则表示所有数组,我想将其与当前(取消公告的)key状态异或,以查看它是否发生了更改。如果key_integration int的每一位X在所有数组上都是0,我想做同样的事情。如果位X在阵列上分散为1和0,则它仍然是去抖动的,不需要进行比较


我目前对如何比较key_集成数组和debounced key state int感到困惑。我非常希望您能给我一些建议,告诉我如何A)比较它们,或者B)重构代码,以更简单的方式实现相同的结果。我绝对不能相信我所想到的是最好的方法。

你可以很容易地计算出密钥始终为零或始终为一的掩码(伪代码)

alwaysZ=-1
alwaysO=-1
对于(int i=0;i
因此,很容易确定哪些键保持不变(但在任一极性中):
stable=alwaysZ|alwaysO

尽管这需要在每个轮询时刻重新计算,但这是可以避免的。显然,如果设置第i位的次数为0或
DEBOUNCE
(可能
DEBOUNCE-1
,这取决于您定义该常数的含义,但关键是它将是0或“一切”)。所以这里有一个替代方案:保留一个计数数组,计算每个按钮在整个去盎司窗口中处于下降状态的次数。为当前按下的每个按钮添加一个按钮,从按下的每个按钮减去一个按钮,使其进入过去的步骤

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


至于次要问题,您可以使用标准技术来避免移动数据本身,只需通过调整索引来虚拟地移动数据。但这也不是免费的,因为DEBOUNCE=5我不会这么做。由于开销是恒定的,因此它可以很好地扩展到巨大的去盎司值。通常,您可以避免使用实际的模运算,因为您只需递增索引(因此,如果到达末尾,您可以递增并返回到0),而不是随机索引到缓冲区的中间。

可能重复的@JarrodRoberson不是重复的,这些问题基本上没有什么共同点,除了去抖动的总体目标。这里描述的技术似乎没有多大意义。您可能希望为每个键定义状态变量[s],以测量它们已关闭的时间量,并根据更改采取相应的行动,如果您希望完整地执行关闭、打开和重复事件。但是,如果您不需要支持同时输入、向上和向下事件以及重复,那么它就变得非常简单,因为您只需检测到第一个向下键,然后在适当的几分之一秒内忽略整个键盘即可完成去抖动。感谢您的指导和帮助!我正在稍微更改算法,以便缓冲区数组位定义“密钥是否处于与录制/广播状态不同的状态?”这样我就可以在更改“state”变量之前检查所有0。我可能会实现循环缓冲区,只是为了在任何去盎司常量中保持一致的性能,尽管会有开销。
alwaysZ = -1
alwaysO = -1
for (int i = 0; i < DEBOUNCE; i++)
    alwaysZ &= ~keys[i]
    alwaysO &= keys[i]