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;
}
沒有留言:
張貼留言