适用于如下电路的按键检测,定时调用ReadKey()函数查询按键状态,将返回按键动作中KEY_UP、KEY_PRESSED、KEY_DOWN、KEY_REPEATED、KEY_RELEASED五种状态。要检测多个按键时,需要为每个按键分配一个tagKEYSTATE结构,tagKEYSTATE中的nRepeatDelay属性可以设置按键自动重复功能和重复速率。
左右两个电路作用一样,区别是左边CPU的输入端常态为高电位,按下按键时为低电位;右边的常态为低电位,按下按键是高电位。对于按下为低电位的按键电路,应该把I/O端口的值取反后再调用ReadKey()函数。
Keys.h代码
#define KEY_UP 0 #define KEY_PRESSED 1 #define KEY_DOWN 2 #define KEY_RELEASED 3 #define KEY_REPEATED 4 typedef struct tagKEYSTATE { unsigned char nPinState; unsigned char nPinStateBuff; unsigned char nCounter; unsigned char nRepeatDelay; } KEYSTATE; unsigned char ReadKey(unsigned char nPinState, KEYSTATE * KeyState);
Keys.c代码
#include "Keys.h" unsigned char ReadKey(unsigned char nPinState, KEYSTATE * KeyState) { unsigned char ks = KEY_UP; if (KeyState->nPinState == nPinState) { if (KeyState->nPinStateBuff == KeyState->nPinState) { if (KeyState->nPinStateBuff == 1) { if (KeyState->nRepeatDelay != 0) { if (KeyState->nCounter == 0) { KeyState->nCounter = KeyState->nRepeatDelay; ks = KEY_REPEATED; } else { KeyState->nCounter --; ks = KEY_DOWN; } } } } else { KeyState->nPinStateBuff = KeyState->nPinState; if (KeyState->nPinStateBuff == 1) { KeyState->nCounter = KeyState->nRepeatDelay; ks = KEY_PRESSED; } else ks = KEY_RELEASED; } } else { if (KeyState->nPinState == 0) ks = KEY_UP; else ks = KEY_DOWN; KeyState->nPinState = nPinState; } return ks; }