看了楼主的贴子对按键消抖又有了新的理解 |
贴上宋学松的程序片段:此程序在1毫秒中断程序中执行 //将一行的 4 个按键值移入缓冲区 keybuf[keyout][0] = (keybuf[keyout][0] << 1) | KEY_IN_1; keybuf[keyout][1] = (keybuf[keyout][1] << 1) | KEY_IN_2; keybuf[keyout][2] = (keybuf[keyout][2] << 1) | KEY_IN_3; keybuf[keyout][3] = (keybuf[keyout][3] << 1) | KEY_IN_4; //消抖后更新按键状态 for (i=0; i<4; i++) //每行 4 个按键,所以循环 4 次 { if ((keybuf[keyout][i] & 0x0F) == 0x00) { //连续 4 次扫描值为 0,即 4*4ms 内都是按下状态时,可认为按键已稳定的按下 KeySta[keyout][i] = 0; } else if ((keybuf[keyout][i] & 0x0F) == 0x0F) { //连续 4 次扫描值为 1,即 4*4ms 内都是弹起状态时,可认为按键已稳定的弹起 KeySta[keyout][i] = 1; } } //执行下一次的扫描输出 keyout++; //输出索引递增 keyout = keyout & 0x03; //索引值加到 4 即归零 switch (keyout) //根据索引,释放当前输出引脚,拉低下次的输出引脚 { case 0: KEY_OUT_4 = 1; KEY_OUT_1 = 0; break; case 1: KEY_OUT_1 = 1; KEY_OUT_2 = 0; break; case 2: KEY_OUT_2 = 1; KEY_OUT_3 = 0; break; case 3: KEY_OUT_3 = 1; KEY_OUT_4 = 0; break; default: break; } |
看了一下,你的状态机消抖,你key_press!=0xff时,表明有键按下,赋key_state=1,则执行case=1语句,再判断key_press!=0xff,就几条语句,也就几个微秒而已,延时很短的,这有问题。 还是手把手教你学51单片机 宋学松处理阵列按键程序来得好。 它的思路是:采用中断的形式,1毫秒中断,在1毫秒中断中,使某一行为低电平,其它为高电平。然后把这一行中的按键状态缓存在状态字节数组中(4*4的二维数组中),有四行,则要执行4次,花4毫秒才能把各个按键的状态存储一遍。存储的字节先左移一位,然后从最低位移入状态位(列状态),1为按键没按下,0表示按下。通过16次,16毫秒扫描,就存储了四次矩阵按键状态,这样存储在字节的低四位中。 假设4次都是1,表明已稳定弹起,假设4次都为0,表明稳定键下,如果不全是1或是0,则在按键过渡期。只要把这16这字节的数组与0x0f按位与,就能判断是不是稳定按下,或是稳定弹出,如果是,就返回某按键值为1或是0,使代表按键消抖状态的二维数组中的某个数为1或是0 |
写的非常详细 |
程序啰里啰唆,采样后仅判断2次,完全没这个必要的逻辑,后面的keycode重新赋值也根本没必要,采样出来本来已经是按键值,没必要再次转换。除非还有其他的采样,要放在一个8位的byte里面去识别。 |
使用硬件去抖动电路:1)RS触发器去抖动,2)单稳触发器——74HC221,3)同相器组成的积分去抖动电路。 |
哎呀,你为什么把每个按键都定义呢,直接横扫纵扫不就行了 |
谢谢大佬 |
楼主写的非常详细 好资料,51黑有你更精彩!!! |
很棒的分析,感谢分享。 |
分析很透,佩服这些大神 |
分析很透彻!好办法! |
感谢楼主,非常好的资料,很有用。 |
oh,在不解压下可以打开,解压了反而打不开了,是我的原因。 |
不错,万丈高楼平地起,越是看似简单的东西,越要用心去学。谢谢楼主分享。 |
非常好的资料,谢谢楼主 |
楼主写的很好,先收藏研究一下 |
楼主写的非常详细 好资料,51黑有你更精彩!!! |