#include "global.h"
/*******************************************************************
按键控制流程
stateaction
0检测是否有按下
1消抖
2检测是否有按下
行扫描,列读取出健值,送出键值,并移至高4位
3行扫描,列读取出健值跟上一次比较.相同计时(2s)加一.计满转下一个状态(长按);
不同则转到1(组合键可以在这一状态下判断)
4行扫描,列读取出健值跟上一次比较.相同计时(100ms)加一.计满送出键值,不同则转到1
5按键弹起处理
**********************************************************************/
#define LPT 1200
#define LPT_SEND_DATA200
#define JUDGE_KEY_DOWN0
#define WAIT_KEY_STATE1
#define SEND_KEY_VALUE2
#define JUDGE_LOONG_PRESS3
#define LOONG_PRESS_ACTION4
#define KEY_UP_STATE5
#define key_port PORTC
#define key_dd DDRC
#define key_in PINC
#define key_IO 0xF0
//备配IO的输入输出.1为输出.O为输入
#define key_L 0xF0
//列输出来,低位输出
#define key_R 0x0F
//行输入,高位读入
unsigned char key_pin[]={0x10,0x20,0x40,0x80};
const unsigned char key_table[]={
0x00,0x01,0x02,0xff,0x03,0xff,0xff,0xff,0x04,0xff,0xff,0xff,0xff,0xff,0xff,0xff,//第一行
0x10,0x05,0x06,0xff,0x07,0xff,0xff,0xff,0x08,0xff,0xff,0xff,0xff,0xff,0xff,0xff,//第二行
0x20,0x09,0x0a,0xff,0x0b,0xff,0xff,0xff,0x0c,0xff,0xff,0xff,0xff,0xff,0xff,0xff,//第三行
0x30,0x0d,0x0e,0xff,0x0f,0xff,0xff,0xff,0x10,0xff,0xff,0xff,0xff,0xff,0xff,0xff//第四行
};
volatile unsigned char key_value_old;
volatile unsigned int key_time;
volatile unsigned char state;
volatile unsigned char j;
unsigned char key_scan(void)
{
unsigned char j;
for(j=0;j<4;j++)
{
key_port =key_pin[j];
key_port = key_pin[j];
//_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
if( (key_in & key_R)!= 0x00 )
{
//return (key_table[j + key_in]);//i=0,5,10,15
//PORTD = key_table[i <<4 + key_in];
//PORTD = key_in;
//key_port = 0x0f;
//return j;
switch(key_in)
{
case 0b00010001: return 0;
break;
case 0b00100001: return 1;
break;
case 0b01000001: return 2;
break;
case 0b10000001: return 3;
break;
case 0b00010010: return 4;
break;
case 0b00100010: return 5;
break;
case 0b01000010: return 6;
break;
case 0b10000010: return 7;
break;
case 0b00010100: return 8;
break;
case 0b00100100: return 9;
break;
case 0b01000100: return 10;
break;
case 0b10000100: return 11;
break;
case 0b00011000: return 12;
break;
case 0b00101000: return 13;
break;
case 0b01001000: return 14;
break;
case 0b10001000: return 15;
break;
default:break;
}
}
}
key_port = key_IO;
return 0x00;
}
void key_deal(void)
{
key_port = key_IO;
key_dd = key_IO;
key_port = key_IO;
key_port = key_IO;
_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
if( (key_in & key_R) !=0x00 )
{
switch(state)
{
case JUDGE_KEY_DOWN:
key_time = 0;
key_value= 0;
key_value_old = 0;
if(key_scan() != 0x00)//判断键有按下
{
state =WAIT_KEY_STATE;
}
else
{
state=KEY_UP_STATE;
}
break;
case WAIT_KEY_STATE :
if(key_f1ms_flag ==1)//消抖
{
key_f1ms_flag = 0;
key_time++;
if(key_time>10)
{
key_time=0;
state=SEND_KEY_VALUE;
}
}
break;
case SEND_KEY_VALUE:
if(key_value = key_scan())//送出键值
{
key_value_old = key_value;
state=JUDGE_LOONG_PRESS;
}
else
{
state=KEY_UP_STATE;
}
break;
case JUDGE_LOONG_PRESS:
if(key_value_old == key_scan())//判断键值是否相同
{
if(key_f1ms_flag ==1)
{
key_f1ms_flag = 0;
key_time++;
if(key_time >LPT)//长按计时
{
key_time=0;
state = LOONG_PRESS_ACTION;
}
}
}
else
{
state = JUDGE_KEY_DOWN;//键值不同重新判断
}
break;
case LOONG_PRESS_ACTION:
if(key_value_old == key_scan())
{
if(key_f1ms_flag ==1)
{
key_f1ms_flag =0;
key_time++;
if(key_time >LPT_SEND_DATA)
{
key_time=0;
key_value=key_value_old;//每100ms送出键值
}
}
}
else
{
state=JUDGE_KEY_DOWN;
}
break;
case KEY_UP_STATE:
key_time = 0;
//key_value= 0;
key_value_old = 0;
state = JUDGE_KEY_DOWN;
default:break;
}
}
else
{
key_time = 0;
//key_value= 0;
key_value_old = 0;
state = JUDGE_KEY_DOWN;
}
}