自己习作,所有按键相关处理在定时中断中进行,主循环可释放出来。
当然,也就“绝对不会产生抖动”了,呵呵。
下面,贴上全部程序。不喜勿喷
/***************************************************
工程名:独立按键(状态机)控制 LED_之二
作 者:老芹
***************************************************/
#include "STC15F2K60S2.H"
#define uchar unsigned char
#define uint unsigned int
void LED_ON();
void LED_OFF();
sbit K1 = P1^4; //定义按键
sbit LED = P0^0;
void KEY_Scan(); //检测按键
void Timer0_Init(); //定时器初始化
bit key;
void main()
{
Timer0_Init();
while(1)
{
if(key) //按键按下,LED点亮
LED_ON(); //点亮LED
else
LED_OFF(); //关闭LED
}
}
void KEY_Scan() //检测按键
{
static uchar i,j,k;
static uchar KeyStatus = 0; //按键状态
if(K1==0) j=1; //按键首次按下,键按下标志置位
if((K1==1)&&(j==0)) return;
switch (KeyStatus)
{
case 0: //初始状态下,KeyStatus=0
if(k<8)
{
k++;
if(!K1)
i++;
if(i!=k)
{
KeyStatus=0; //是干扰,退回初始状态
i=0; //键按下标志复位
k=0;
k=0;
}
break;
}
i=0;
k=0;
KeyStatus++;
break;
case 1:
key = !key; //按键有效
KeyStatus++; //转到下一状态,等待按键释放
break;
case 2:
if(K1==0) //键仍然按下
break;
else //键松开
{
//key = !key; //键松开执行
KeyStatus = 0; //键释放,退回初始状态
i=0;
j=0;
k=0;
}
break;
}
}
void Timer0_Init() //定时器初始化
{ //2毫秒@11.0592MHz
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x9A; //设置定时初值
TH0 = 0xA9; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0 =1;
EA = 1;
}
void Timer0() interrupt 1 //定时器中断
{ //16位自动重装模式,无需重赋初值
static bit i;
if(key) //按键按下,LED点亮
LED_ON(); //点亮LED
else
LED_OFF(); //关闭LED
i = !i;
if(i) //每4Ms执行一次键盘扫描程序
KEY_Scan();
}
/*点亮LED*/
void LED_ON()
{
LED=0;
}
/*关闭LED*/
void LED_OFF()
{
LED=1;
}
|