10/22/2008

AT89S5X EASY KEY SCAN USER POLLING

做一個簡易KEY
1個IO做1個輸入
使用POLLING的方式
如此即可處理彈跳問題
又不會讓程式停下來
感覺寫的不是很好
如果有人發現更好的方法
請告訴我 謝謝



/*
AT89SX EASY KEY FIRST VER 1.0
KEY PORT P2
KEY INPUT P2_0~P2_3
USER POLLING
SHOW LED FOR PORT P0

BRIAN @ taiwan
*/

#include "AT89X52.H"

#define Key_port P2 //設定要讀取的port(set your read port)
#define Mark_Key 0x0F //設定要mark的key(set your mark key)
#define DebounceReg 20//設定初始化彈跳時間 (set your default debounce time)

#define b_Debounce 0x01 //set debounce flag for key_flag
#define b_Pressed 0x02 //set pressed flag for key_flag
#define b_Release 0x04 //set release flag for key_flag

void sys_init(void); //system_init function
char GetKey(void); //get press key number
unsigned char Get_KeyStatus(void); //get press key or release key
void Key_Loop(void); //scan key user polling

char Key_flag; //0x01 = Debounce 0x02 =press 0x04= release
char R_DebounceReg; //KEY DEBOUNCE COUNG
char R_KeyBuffer; //KEY BUFFER SAVE INPUT KEY
char First_key; //memory first pressed key
char Port_buffer; // memory port status

void main(void)
{
char PressKey,KeyStatus;
char Led_count;

sys_init();

Led_count=0;

while(1)
{
KeyStatus = Get_KeyStatus();

if(KeyStatus==0x02) //pressed key
{
PressKey=GetKey();
switch(PressKey)
{
case 1:
P0=0x1<<Led_count;
P0= ~P0;
Led_count++;
if(Led_count>7)
Led_count=0;
break;
//...........
}

}
else if(KeyStatus==0x04) //release key
{
PressKey=GetKey();
switch(PressKey)
{
default:
P0=0xFF;
break;
//...........
}
}

Key_Loop();
}

}

void sys_init(void)
{
Key_flag = 0;
R_DebounceReg = 0;
R_KeyBuffer = 0;
First_key = 0;
Port_buffer=0;
//ALL SYSTEM REG SET
Key_port=0x00;

}

void Key_Loop(void)
{
char Key;
char Key_chang;

if(Key_flag & b_Debounce)
{
R_DebounceReg--;
if(R_DebounceReg != 0) //debounce 時間內就離開 以過了debounce 就在讀取一次
return;
}

Key_chang = Key_port & Mark_Key; //讀取input key port

if(Key_chang != Port_buffer) //當port內的值有改變 而且是key 值
{
Port_buffer = Key_port; //memory port value
First_key = Port_buffer & Mark_Key; //memory user touch key
Key_flag = b_Debounce; //set flag
R_DebounceReg = DebounceReg; //set debounce time value
return;
}

if(Key_flag & b_Debounce) //當debounce 結束後
{
Key = Key_port & Mark_Key;//在取一次port的值
if(Key & First_key)//二次相同 , 設為按下
{
Key_flag = b_Pressed; //set flag
R_KeyBuffer = Key; //set touch key value
}
else
{
Key_flag = b_Release; //set flag
}
}
else
{
Key_flag=0;
}

}

unsigned char Get_KeyStatus(void)
{
return Key_flag;
}

char GetKey(void)
{
return R_KeyBuffer;
}

沒有留言: