前面一段时间在考虑矩阵键盘的驱动方式,其中,在按键长按这个点上,网上的好多思路都是建立在计时器计时和中断的基础上的,那么,能不能再不用中断和计时器的情况下,实现按键的长按和双击的判断呢。
在判断按键被按下之后,如果我们对按键释放的时间进行计时,就可以实现按键长按的判断了。建立在这个基础上,如果我们在按键释放之后,延时一段时间再一次判断同一个按键是不是被释放,是不是就可以实现双击的判断了。
有了思路之后,代码实现就比较容易了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
| uint8_t KEY_Scan(void) { static uint8_t lastKeyValue; uint16_t count; uint8_t i; uint8_t scanData = 0; uint8_t keyValue = 0; const uint8_t writeData[] = {0x0E, 0x0D, 0x0B, 0x07};
KEY_Write(0x00); count = 10000; while((KEY_Read() == 0x0F) && (count != 0)) { delay_us(1); count--; } if (count == 0) { lastKeyValue = 0; return 0; }
delay_ms(5);
for (i = 0; i < 4; i++) { KEY_Write(writeData[i]); delay_us(1); switch (KEY_Read()) { case 0x0E: scanData += 1; keyValue = scanData; break;
case 0x0D: scanData += 2; keyValue = scanData; break;
case 0x0B: scanData += 3; keyValue = scanData; break;
case 0x07: scanData += 4; keyValue = scanData; break;
default: break; } scanData += 4; } if (keyValue == 0) { lastKeyValue = 0; return keyValue; }
KEY_Write(0x00); count = 0; while ((KEY_Read() != 0x0F) && count < KEY_LONG_PRESS_MAX_TIME) { count++; delay_ms(1); }
if (count > KEY_SHORT_PRESS_MAX_TIME) { keyValue += 20; } #ifdef KEY_DOUBLE_CLICK else { delay_ms(KEY_DOUBLE_CLICK_DELAY); KEY_Write(writeData[(keyValue - 1) / 4]); delay_us(1); if (KEY_Read() == writeData[(keyValue - 1) % 4]) { keyValue += 40; delay_ms(10); KEY_Write(0x00); count = 0; while ((KEY_Read() != 0x0F) && count < 500) { count++; delay_ms(1); } } } #endif
if ((lastKeyValue == keyValue) || (lastKeyValue == keyValue + 20) || (lastKeyValue == keyValue -20)) { keyValue = 0; return 0; } lastKeyValue = keyValue;
return keyValue; }
|
end