求解释单片机键盘扫描的一段程序(关键是松手那块不明白)

求解释单片机键盘扫描的一段程序(关键是松手那块不明白),第1张

松手检测也就是消抖嘛,在你这程序中就是

if

(key==0xff){

//如果读取不到P0口的值,比如是干扰,我们不做键值处理,返回

SPK=1

//按键有松开,停止蜂鸣器响

return

}

主要作用就是防止其他干扰信号误判成按键信号。

另一个就是假如你长按不放的话就要使它在那等待你放开才会执行程序,所以这在你这的程序就是

if(l_keyold==key)

{

//检测按键放开否,如果一样表明没放开,

return

}

其实这个return可以不要,直接用分号等待也行,还有什么不懂的吗?

0x10折成二进制是00010000,高四位是列,那么程序就是逐列扫描的了,这是从最低列扫起,用它作为掩码,只留下一位。

P1 = 0xf0// 发全0行扫描码,这句就是让所有的列先置高,行置低,是初始值,建议你把电路图对着看,可以在脑子里假设一个钮按下的状态再分析程序。

if ((P1&0xf0)!=0xf0) // 若有键按下,这句如果为真,就说明至少有一列中有键按下了,但是它是区别不出来是哪一列的,只能证明有键按下,当然就更分不出来是哪行了。

scancode = 0xfe//这句是给扫描码置一个初值,0xfe就是二进制的11111110,接着看后边。

while((scancode&0x10)!=0) // 逐行扫描,刚才说过,这个0x10就是二进制的00010000,和扫描码11111110做与之后留下00010000,那么这时如果在最低列中有键按下,表达式就为假了,没有键按下时才会为真,也就是继续扫描。这种方式不能处理多个键按下的情形,会低位优先,因为一旦有键按下了就不再扫后边的了。而此时注意scancode本身中是行的值。

P1 = scancode// 输出行扫描码,注意扫描码中的值并未改变,是11111110。

if ((P1&0xf0)!=0xf0) // 本行有键按下,这个判断中对P1做与,如果没有键按下,那么P1应该是和scancode中的值一样的,和0xf0做与之后就是留下高四位得到11110000,一旦有按下的键,相应的位会被拉低,肯定就不等于11110000了,比如说11100000,那么表达式就为真了。

tmpcode = (P1&0xf0)|0x0f//这句将P1与上的值与0x0f做或运算,得到低4位为全1的列扫描码。

return((~scancode)+(~tmpcode))//由于其它的位都被填了1,每次招描的结果都只有1个0,取反输出就得到了只有一个1的码。

else scancode = (scancode<<1)|0x01// 行扫描码左移一位,这样就是将scancode中的11111110变成11111100,而且还要或上0x01保持最低位被补1变成11111101,依次后边会变成11111011和11110111,完成四个行的扫描。

重复上述过程完成所有的扫描。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/12194908.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-21
下一篇 2023-05-21

发表评论

登录后才能评论

评论列表(0条)

保存