51單片機(jī)按鍵雙擊
//適用于CEPARK 51開(kāi)發(fā)板
本文引用地址:http://m.butianyuan.cn/article/201611/321094.htm/*****************************************************************************************************************
www.cepark.com電子園 按鍵高階攻略設(shè)計(jì)大賽
名稱(chēng):2*4矩陣鍵盤(pán)掃描(狀態(tài)機(jī))
功能:按鍵0單擊時(shí),點(diǎn)亮P0口的第1357個(gè)LED,按鍵1雙擊時(shí),點(diǎn)亮P0口的2468個(gè)LED,按鍵2三擊時(shí),點(diǎn)亮P0口的所有的LED
按鍵按下的時(shí)間間隔小于200ms。 其他鍵按下時(shí),LED狀態(tài)不變
作者:alger2009
時(shí)間:2009.12.30 星期三
版本:V1.0
其他:該開(kāi)發(fā)板的LED不是單個(gè)的LED組成,而是LED邏輯卡;看門(mén)狗程序防止程序跑飛
*****************************************************************************************************************/
#include"reg52.h"
#include"intrins.h"
#include"key2.h"
/******宏定義***************************************************************************************************/
#defineNo_key 255//無(wú)鍵按下返回值
/******定義全局變量********************************************************************************************/
unsigned charkeyread_flag=0;//矩陣鍵盤(pán)掃描標(biāo)志位
unsigned char num=0;//定時(shí)計(jì)數(shù)器計(jì)數(shù)變量
unsigned charoutdata=0;//返回值
/******2*4矩陣鍵盤(pán)掃描程序**********************************************************************************************
返回值:key_return
key_return=0 單擊
key_return=1 雙擊
key_return=2 三擊
key_return=其他,按鍵無(wú)效
************************************************************************************************************************/
unsigned char read_keyboard(void)
{
static unsigned char key_state=0,key_value,key_line;// 列讀取變量,行掃描碼
static unsigned char key_times=0;//按鍵擊打次數(shù)
static unsigned char Tcount=0;//按鍵連擊計(jì)時(shí)變量
unsigned char key_return=No_key,i;//按鍵返回值
switch(key_state)
{
case 0://key you meiyou cunzai jiancha//狀態(tài)0功能: 按鍵掃描 連擊計(jì)時(shí) 和連擊超時(shí)處理
key_line=0x10;
if(key_times!=0)Tcount++;//如果不是第一次擊打,計(jì)時(shí)變量加1
if(Tcount>20)//若連擊按鍵按下時(shí)間間隔大于200毫秒
{
key_times=0;// 按鍵擊打次數(shù)歸0
Tcount=0;// 計(jì)時(shí)變量歸0
}
for(i=0;i<2;i++)// 掃描鍵盤(pán)
{
P2=~key_line;// 輸入行掃描碼
P2=~key_line;// 重復(fù)送一次
key_value=0x0f & P2;// 讀列電平
if(key_value==0x0f)
key_line<<=1;// 沒(méi)有按鍵,繼續(xù)掃描
else
{
key_state++;// 有按鍵,停止掃描
break;// 跳出按鍵掃描
}
}
break;
case 1://狀態(tài)1功能:確認(rèn)按鍵 讀取按鍵值
if(key_value==(0x0f & P2))// 再次讀列電平,若非抖動(dòng)
{
switch(key_line|key_value)//行掃描碼和列電平,確認(rèn)按鍵
{// 鍵盤(pán)編碼,返回編碼值
case 0x1e://單擊按鍵0
key_return=1;
break;
case 0x1d:
{
if(key_times==1 && Tcount<20)
key_return=2;//雙擊按鍵1
else
key_times++;//第一次按下,計(jì)數(shù)加1
}
break;
case 0x1b:
{
if(key_times==2 && Tcount<20)
key_return=3;//三擊按鍵2
else
key_times++;//第一次或第二次按下,計(jì)數(shù)加1
}
break;
case 0x17:
key_return=4;
break;
case 0x27:
key_return=5;
break;
case 0x2b:
key_return=6;
break;
case 0x2d:
key_return=7;
break;
case 0x2e:
key_return=8;
break;
}
key_state++;// 轉(zhuǎn)入等待按鍵釋放狀態(tài)
}
else
key_state--;// 兩次列電平不同返回狀態(tài)0,(消抖處理)
break;
case 2://狀態(tài)2功能:按鍵釋放判定
P2=0x0f;// 行線(xiàn)全部輸出低電平
P2=0x0f;// 重復(fù)送一次
if((P2 & 0x0f)==0x0f)
key_state=0;// 按鍵釋放,返回狀態(tài)0
break;
}
return key_return;//返回值
}
/******定時(shí)器1 定時(shí)1毫秒******************************************************************************/
void timer1(void)interrupt 3
{
TH1=(65536-1000)/256;
TL1=(65536-1000)%256;
if(++num==10)
{keyread_flag=1;//按鍵掃描允許標(biāo)志位
num=0;
}
}
/******定時(shí)器初始化**********************************************************************************/
void timer1_initial(void)
{
TH1=(65536-1000)/256;
TL1=(65536-1000)%256; //裝初始值
IE=0x88; //開(kāi)總中斷和定時(shí)器1中斷
TMOD=0x10; //工作方式1
TR1=1; //啟動(dòng)定時(shí)器
}
/******看門(mén)狗子程序*********************************************************************************/
void clr_wdt(void)
{
WDTRST=0x1e;
WDTRST=0xe1;
}
/******主程序****************************************************************************************/
main(void)
{
P0=0xff;//初始化LED端口
timer1_initial();//定時(shí)器1初始化
while(1)
{
if(keyread_flag==1)//矩陣掃描標(biāo)志位允許
{
keyread_flag=0;
clr_wdt();//調(diào)用看門(mén)狗 (每2的14次方個(gè)機(jī)器周期內(nèi)必須調(diào)用一次,使看門(mén)狗復(fù)位)
outdata=read_keyboard();//讀取矩陣鍵盤(pán)返回值
}
if(outdata==1)
P0=0xaa;//單擊按鍵0 點(diǎn)亮第1357個(gè)LED
elseif(outdata==2)
P0=0x55;//雙擊按鍵1 點(diǎn)亮第2468個(gè)LED
elseif(outdata==3)
P0=0x00;//三擊按鍵2 點(diǎn)亮全部LED
}
}
評(píng)論