/***********************************************************************
这是可以用于实战的独立按键程序,有详细注释,你看懂就进入中级阶段了。
加电LED1~LED4全亮,key1~key4分别控制LED1~LED4熄灭1~4秒,各通路独立控
制互不影响,延时期间重复按键无效。摒弃严重影响运行效率的Delay软件延时。
按键和LED端口定义可根据实际电路自行更改
************************************************************************/
#include <reg51.h>
#define uint unsigned int //宏定义无符号整型数据
#define uchar unsigned char //宏定义无符号字符型数据
sbit key1=P3^4; //按键端口定义
sbit key2=P3^5;
sbit key3=P3^6;
sbit key4=P3^7;
sbit LED1=P1^0; //LED端口定义
sbit LED2=P1^1;
sbit LED3=P1^2;
sbit LED4=P1^3;
void key_scan(); //按键扫描程序声明
void Timer0Init(); //初始化定时器程序声明
bit key1_sign=0,key2_sign=0,key3_sign=0,key4_sign=0;//按键自锁标志
uint sec5ms1=0,sec5ms2=0,sec5ms3=0,sec5ms4=0;//5ms中断变量
/*******************
主程序
********************/
void main()
{
LED1=0; //初始化LED
LED2=0;
LED3=0;
LED4=0;
Timer0Init(); //初始化定时器程序
while(1)
{
key_scan(); //按键扫描程序
}
}
/**************************************************
按键扫描程序
**************************************************/
void key_scan() //键扫描程序
{
static uchar count1=0,count2=0,count3=0,count4=0;//消抖计数变量
if(key1==0) //按键1按下
{
count1++; //消抖计数1自+1
if(count1>=100) //100次检测按键如果为0
{
count1=100; //防止溢出
if(key1_sign==0) //按键1自锁标志为0
{
key1_sign=1; //按键1自锁标志置1
LED1=1; //LED1熄灭
}
}
}
else count1=0; //按键1抬起计数1清0
if(key2==0) //按键2按下
{
count2++; //消抖计数2自+1
if(count2>=100) //100次检测按键如果为0
{
count2=100; //防止溢出
if(key2_sign==0) //按键2自锁标志为0
{
key2_sign=1; //按键2自锁标志置1
LED2=1; //LED2熄灭
}
}
}
else count2=0; //按键2抬起计数2清0
if(key3==0) //按键3按下
{
count3++; //消抖计数3自+1
if(count3>=100) //100次检测按键如果为0
{
count3=100; //防止溢出
if(key3_sign==0) //按键3自锁标志为0
{
key3_sign=1; //按键3自锁标志置1
LED3=1; //LED3熄灭
}
}
}
else count3=0; //按键3抬起计数3清0
if(key4==0) //按键4按下
{
count4++; //消抖计数4自+1
if(count4>=100) //100次检测按键如果为0
{
count4=100; //防止溢出
if(key4_sign==0) //按键4自锁标志为0
{
key4_sign=1; //按键4自锁标志置1
LED4=1; //LED4熄灭
}
}
}
else count4=0; //按键4抬起计数4清0
}
/**************************************************
初始化定时器程序 12T 5毫秒@12.000MHz
**************************************************/
void Timer0Init(void) //5毫秒@12.000MHz
{
TMOD = 0x01; //设置定时器模式
TL0 = 0x78; //设置定时初值
TH0 = 0xEC; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
EA=1; //开总中断
ET0=1; //开定时器0中断
}
/**************************************************
定时器0中断服务程序
**************************************************/
void timer0() interrupt 1 //定时器0中断服务程序
{
TL0 = 0x78; //设置定时重载值
TH0 = 0xEC; //设置定时重载值
if(key1_sign==1) //允许1秒延时计时
{
sec5ms1++; //sec5ms1自+1
if(sec5ms1>=200) //1秒
{
sec5ms1=0; //sec5ms1清0
key1_sign=0; //按键1自锁标志清0
LED1=0; //LED1亮
}
}
if(key2_sign==1) //允许2秒延时计时
{
sec5ms2++; //sec5ms2自+1
if(sec5ms2>=400) //2秒
{
sec5ms2=0; //sec5ms2清0
key2_sign=0; //按键2自锁标志清0
LED2=0; //LED2亮
}
}
if(key3_sign==1) //允许3秒延时计时
{
sec5ms3++; //sec5ms3自+1
if(sec5ms3>=600) //3秒
{
sec5ms3=0; //sec5ms3清0
key3_sign=0; //按键3自锁标志清0
LED3=0; //LED3亮
}
}
if(key4_sign==1) //允许4秒延时计时
{
sec5ms4++; //sec5ms4自+1
if(sec5ms4>=800) //4秒
{
sec5ms4=0; //sec5ms4清0
key4_sign=0; //按键4自锁标志清0
LED4=0; //LED4亮
}
}
}
|