普通情况下一个按键可用普通IO口或者ADC端口做按键扫描。两种原理图如下:
AD按键扫描与长短按键可以用如下的C代码实现:
typedef unsigned char u8;
typedef unsigned int u16;
void AdcInit(void);
u16 AdcConverts(unsigned char Channel);
u8 KeyRead(void)//读取键的状态
{
u16 keyAdcValue = 0;
keyAdcValue = AdcConverts(KEY_CHANNEL);
if ((keyAdcValue < (KEY0_ADC + KEY_ADC_DELTA)) && (keyAdcValue >(KEY0_ADC - KEY_ADC_DELTA))){
return KEY_0;
}
else if ((keyAdcValue < (KEY1_ADC + KEY_ADC_DELTA)) && (keyAdcValue >(KEY1_ADC - KEY_ADC_DELTA))){
return KEY_1;
}
else if........
}
else{
return KEY_NULL;
}
}
void KeyScan(void)
{
static unsigned char g_ucLastKeypad, KeyNum, ShortKey, LongKey;
static unsigned char KeyValue = KEY_NULL;
unsigned char KeyStatus = 0;
KeyStatus = KeyRead();
ShortKey = ShortKey;
LongKey = LongKey;
if(g_ucLastKeypad == KEY_NULL && KeyStatus != g_ucLastKeypad){ //按键刚被按下
KeyNum = 0;
ShortKey = 0;
LongKey = 0;
KeyValue = KEY_NULL;
}
else if(KeyStatus == g_ucLastKeypad && KeyStatus != KEY_NULL){ //按键正被按着
KeyNum++;
if(KeyNum == KEY_LONG_TIMES){
ShortKey = 0;
LongKey = 1;
KeyValue = g_ucLastKeypad;
}
}
else if(KeyStatus == KEY_NULL && KeyStatus != g_ucLastKeypad){ //按键被放开
if(KeyNum < KEY_LONG_TIMES && KeyNum > KEY_SHORT_TIMES){
KeyNum = 0;
ShortKey = 1;
LongKey = 0;
KeyValue= g_ucLastKeypad;
}
}
else{
KeyNum = 0;
ShortKey = 0;
LongKey = 0;
KeyValue = KEY_NULL;
}
g_ucLastKeypad = KeyStatus;
}
普通IO口的按键的长短按也可以利用AD的识别来做,唯一不同就是按键扫描方式不一样。下面给出一个按键识别实例。
u8 KeyScan(void)//0为无按键按下,1为短按,2为长按。
{
static u8 Press_Flag=0,g_Press_Flag=0,ReturnFlag=0;
static u16 KeyNum=0;
u8 KeyStatus=0;
KeyStatus=ReadGPIOKey();
if(Press_Flag==0)
{
if(KeyNum<1)
{
KeyNum++;
if(KeyStatus==0) KeyNum=0;
return 0;
}
else
{
KeyNum=0;
Press_Flag=1;
return 0;
}
}
else
{
if(KeyNum <= 15)
{
if(KeyStatus==1)
{
KeyNum++;
return 0;
}
if(g_Press_Flag<1)
{
if(KeyStatus==0) g_Press_Flag++;
}
else
{
Press_Flag=0;
g_Press_Flag=0;
KeyNum=0;
return 1;
}
}
else if(KeyNum < 400 && KeyNum >15)
{
if(KeyStatus==1)
{
KeyNum++;
return 0;
}
if(g_Press_Flag<1)
{
if(KeyStatus==0) g_Press_Flag++;
}
else
{
Press_Flag=0;
g_Press_Flag=0;
KeyNum=0;
return 2;
}
}
else if(KeyNum >= 400)
{
if(KeyStatus==1)
{
if(ReturnFlag==0)
{
KeyNum++;
ReturnFlag=1;
return 3;
}
}
if(g_Press_Flag<1)
{
if(KeyStatus==0) g_Press_Flag++;
}
else
{
Press_Flag=0;
g_Press_Flag=0;
ReturnFlag=0;
KeyNum=0;
return 0;
}
}
return 0;
}
}