|
用狀態(tài)機(jī)處理按鍵,終于把這個功能實(shí)現(xiàn)了;實(shí)驗(yàn)板上測試通過。
/* ********************************************************************************************* */
// 處理器 : STC89C52RC
// 編譯環(huán)境 : Keil4 C51
// 系統(tǒng)時鐘 : 11.0592MHZ
// 簡單描述 : 1個獨(dú)立按鍵,短按開關(guān)LED燈,長按調(diào)光,如果按住按鍵不放,LED亮度從 亮-->暗,暗-->亮,循環(huán)。
/* ********************************************************************************************* */
#include<reg52.h>
typedef unsigned char uChar8;
typedef unsigned int uInt16;
/*初始狀態(tài) 確認(rèn)狀態(tài) 單擊狀態(tài) 連發(fā)狀態(tài) */
typedef enum KeyState{StateInit,StateAffirm,StateSingle,StateRepeat};//鍵值狀態(tài)值
uChar8 pwm_led_val = 0; //LED占空比值 0-20 0最亮
uChar8 pwm_t; //周期
sbit KEY1 = P3^0; //定義按鍵端口
sbit LED = P1^0; //定義LED燈端口
void Timer0Init(void)
{
TMOD |= 0x02; //設(shè)置定時器0工作模式2,8位自動重裝
TH0 = 240; //定時器裝初值
TL0 = 240; //11.0592M晶振下占空比最大比值是20,輸出2880HZ
EA = 1; //開總中斷
ET0 = 1; //開定時器0中斷
TR0 = 1; //啟動定時器0
}
void Timer1Init(void)
{
TMOD |= 0x10; // 設(shè)置定時器1工作模式1,16位計(jì)數(shù)器
TH1 = 0xDC; // 賦初始值
TL1 = 0x00; // 11.0592M晶振下,定時10ms
TR1 = 1; // 啟動定時器1
}
/* ***************************************************** */
// 函數(shù)名稱: Init()
// 函數(shù)功能: 初始化
// 入口參數(shù): 無
// 出口參數(shù): 無
/* ***************************************************** */
void Init() //初始化
{
Timer0Init();
Timer1Init();
}
//定時器0中斷
void timer0() interrupt 1
{
pwm_t++;
if(pwm_t == 20)
{
pwm_t = 0; LED = 1;
}
if(pwm_led_val == pwm_t)
LED = 0;
}
/* ***************************************************** */
// 函數(shù)名稱:KeyScan(void)
// 函數(shù)功能:掃描按鍵
// 入口參數(shù):無
// 出口參數(shù):鍵值(num)
/* ***************************************************** */
void KeyScan(void)
{
static uChar8 KeyStateTemp1 = 0; //按鍵狀態(tài)臨時存儲值1
static uChar8 KeyTime = 0; //按鍵延時時間
bit KeyPressTemp1; //按鍵是否按下存儲值1
bit falg; //亮度標(biāo)志
KeyPressTemp1 = KEY1; //讀取I/O口的鍵值
switch(KeyStateTemp1)
{
case StateInit: //按鍵初始狀態(tài)
if(!KeyPressTemp1) //當(dāng)按鍵按下,狀態(tài)切換到確認(rèn)態(tài)
KeyStateTemp1 = StateAffirm;
break;
case StateAffirm: //按鍵確認(rèn)態(tài)
if(!KeyPressTemp1)
{
KeyTime = 0;
KeyStateTemp1 = StateSingle; //切換到單次觸發(fā)態(tài)
}
else KeyStateTemp1 = StateInit; //按鍵已抬起,切換到初始態(tài)
break;
case StateSingle: //按鍵單發(fā)態(tài)
if(KeyPressTemp1) //按下時間小于1s
{
KeyStateTemp1 = StateInit; //按鍵釋放,則回到初始態(tài)
TR0 = !TR0;
LED = 1; //關(guān)閉LED
}
else if(++KeyTime > 100) //按下時間大于1s(100*10ms)
{
KeyStateTemp1 = StateRepeat; //狀態(tài)切換到連發(fā)態(tài)
KeyTime = 0;
}
break;
case StateRepeat: //按鍵連發(fā)態(tài)
if(KeyPressTemp1)
KeyStateTemp1 = StateInit; //按鍵釋放,則進(jìn)初始態(tài)
else //按鍵未釋放
{
if(++KeyTime > 10) //按鍵計(jì)時值大于100ms(10*10ms)
{
KeyTime = 0;
if(falg == 0)
{
if(pwm_led_val < 20)
{
pwm_led_val++; //亮度變暗
if(pwm_led_val==20)
falg = 1;
}
}
if( falg ==1 )
{
if(pwm_led_val > 0)
{
pwm_led_val--; //亮度變亮
if(pwm_led_val==0)
falg = 0;
}
}
}
break;
}
break;
default: KeyStateTemp1 = KeyStateTemp1 = StateInit; break;
}
}
/* ***************************************************** */
// 函數(shù)名稱:ExecuteKeyNum(void)
// 函數(shù)功能:按鍵值來執(zhí)行相應(yīng)的動作
// 入口參數(shù):無
// 出口參數(shù):無
/* ***************************************************** */
void ExecuteKeyNum(void)
{
if(TF1) //定時器1溢出
{
TF1 = 0;
TH1 = 0xDC;
TL1 = 0x00;
KeyScan();
}
}
void main()
{
Init(); //首先初始化各數(shù)據(jù)
while(1) //進(jìn)入主程序大循環(huán)
{
ExecuteKeyNum(); //不停的檢測按鍵是否被按下
}
}
|
評分
-
查看全部評分
|