关于蓝桥杯单片机官方例程矩阵按键消抖原理解释
项目场景:
芯片:IAP15F2K60S
蓝桥杯原书41页官方例程
问题描述
最开始我以为这款开发板有硬件消抖,对于下面这部分代码一直当作固定格式写,最近回看,发现其中另有“玄机”。
......
ucKey_Val = Key_Read();
ucKey_Down = ucKey_Val & (ucKey_Old ^ ucKey_Val);
ucKey_Old = ucKey_Val;
......
原因分析:
这里默认大家看过并且会了 = = 之前的按键扫描例程了
众所周知,“ ^ ” 符号在C语言中是按位取 “ 异或 ” 的意思,并且,“ & ” 符号是按位取 “ 与 ”的意思。
这段代码的含义是获取扫描后的案件值然后进行消抖处理,我所截取的这一段代码是只保留了单边沿的。
详解:
首先,对于后面的异或,其作用到了ucKey_Old和ucKey_Val,其中ucKey_Old是上一次扫描按键获取的数值,包括获取到0,而ucKey_Val是这一次扫描按键获取的数值。如果二者不同,则会产生 “ 非零 ” 的结果,将代码改成如下。
......
ucKey_Val = Key_Read();
ucKey_Down = (ucKey_Old ^ ucKey_Val);
ucKey_Old = ucKey_Val;
if(ucKey_Down)
{
......
}
......
只要本次接收与上一次接收的按键值不同,ucKey_Down就会存储下“非零”的数值。回想一下,我们按键其实是有两个沿的,一次下降沿,一次上升沿。
更具体地针对官方例程来说,如果我按下4按键,那么他检测到的数值会出现两段变化,一次是ucKey_Val 从0到4的变化,另一次是其从4到0 的变化。
这样就会导致我的ucKey_Down在这两次变化过后都会有一次 “ 非零 ” 数值的出现,所以反应在我的输出上,就会将后面紧随的 if 代码段执行两次,这说明我们的 " ^ " 取异或只实现了部分的消抖功能,还需要保留单边沿,而非双边。
没错,我们的 “ & ” 取与符号就是实现的这个功能。我们分段讨论下0–4–0这个连续变化。
首先是 0–4,这段变化中,
我的 ucKey_Old = 0x00, 我的 ucKey_Val = 0x04;
因为这是从0到4的不同数值的变化,所以后面的取异或符号运算结束后一定是一个 “ 非零 ” 的量,并且结果一定是与 ucKey_Val 的数值相等!又加之与一个非零的 ucKey_Val 取与,那不就是 ucKey_Val 本身求与嘛!!!这就使得 ucKey_Down 最后的结果为 “ 非零 ” 的 ucKey_Val本身!!!这样解释了为什么后面会有
switch(ucKey_Down)
{
......
}
的出现,原来我们仅凭借ucKey_Down的数值就可以判断我按下的是什么键。
-------------分隔符--------------
接下来是4–0这一段的变化,
我的 ucKey_Old = 0x40, 我的 ucKey_Val = 0x00;
之前说到如果是不同数值之间的变化必然会导致异或的结果为 “ 非零 ” 数值,所以这一段就很好明白了,我加上取与符号后,实现了ucKey_Val & “ 非零 ”,其中ucKey_Val为0,会将我的ucKey_Down,结果变成 0,这就实现了我取单边沿的效果。文章来源:https://www.toymoban.com/news/detail-401598.html
总结
异或 “ ^ ” 是用来消抖的,只有扫描到不同的数值之后我才会发生变化。
取余 “ & ”是用来保留单边沿的,因为单单使用"^" 时,笨蛋机器不能判断是哪两个数值之间的变化,究竟是0–4还是4–0呢?当我加上 “ & ” 之后就可以消除一个沿。
PS:文中我们是以下降沿为例说明的,其实保留上升沿的话取个 “ ~ ” 就可以了,具体为啥,大家想想吧。文章来源地址https://www.toymoban.com/news/detail-401598.html
到了这里,关于关于蓝桥杯单片机 官方例程 矩阵按键 消抖原理 ‘s 解释的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!