一个定时器负责扫描按键按下的时间长短,一个定时器负责实现具体的led特效功能,主函数循环扫描按键,避免了占用cpu资源过多,导致程序堵塞,无法扫描到按键等问题;还可以通过定时器来扫描按键按下,时长等,想要实现的程序放在主函数中执行。新人第一次写博客,不足之处欢迎指正,感谢!
主函数部分:
#include <REGX52.H>
#include "DELAY.h"
#include "INTRINS.h"
#include "BEEP.h"
#define LED P2
sbit KEY = P3^0;
unsigned char D1 = 0xFE;
unsigned char D2 = 0xFD;
unsigned char D3 = 0xFB;
unsigned char D4 = 0xF7;
unsigned char num,compare;
unsigned char Flag1,Flag2;
unsigned int counter,time,a,b,c,d;
/**************************************
通过定时器来实现一个按键,单击闪烁灯,双击跑马灯,三击呼吸灯,长按流星灯
并且每次切换模式伴随不同的音效。(连击4下为无效指令)
***************************************/
void TimerInit(void) //@11.0592MHz
{
TMOD=0x11;
TL0 = 0x00; //设置定时初值
TH0 = 0xDC; //设置定时初值
TL1 = 0xA4; //设置定时初值
TH1 = 0xFF; //设置定时初值
TF0 = 0;
TF1 = 0;
TR0 = 0;
TR1 = 0;
EA = 1;
ET1 = 1;
ET0 = 1;
PT0 = 1;
}
void key_count()
{
if(KEY==0) //按键按下
{
Delayms(5) ; //消抖
// TR1 = 0; //可选择按键按下时停止任何功能
if(KEY==0)
{
TR0 = 1 ; //开始计时
while(KEY==0);
TR0 = 0 ; //结束计时
}
}
if(KEY==1) //松手检测
{
if(counter>=100) //按下超过时间
{
TR1 = 0; //防止呼吸灯模式之间切换造成的影响
Beep_voice(6);
LED = 0xFF; //重置LED状态
Flag1 = 4;
TR1 = 1;
}
else if((counter>1)&&(counter<100)) //每次按下不超过1秒
{
num ++; //按键次数加1
time = 7000; //如果此时按键再次按下会被重新赋予6000
}
counter = 0; //按下检测时间清0
if(time) //大于0,减少
{
time--; //通过自减来计时
if(time==0) //计时结束,开始判断
{
LED = 0xFF;
switch(num) //判断按下几次
{
case 1: //单击开启定时器模式一
{
TR1 = 0;
Beep_voice(1);
LED = 0xFF;
Flag1 = 1;
TR1 = 1;
break ;
}
case 2: //双击开启定时器模式二
{
TR1 = 0;
Beep_voice(3);
LED = 0xFF;
Flag1 = 2;
TR1 = 1;
break ;
}
case 3: //三击开启定时器模式三
{
TR1 = 0;
Beep_voice(4);
LED = 0xFF;
Flag2 = 0;
Flag1 = 3;
TR1 = 1;
break ;
}
}
time=0;
num=0; //按键按下次数清0
}
}
}
}
void main() //实现一个按键按下:单击闪烁灯,双击跑马灯,三级呼吸灯,长按流星灯
{
TimerInit();
LED = 0xFF;
while(1)
{
key_count();
}
}
void Time0() interrupt 1 //定时器10ms进入一次中断扫描,计数值加1
{
counter ++;
TL0 = 0x00; //设置定时初值
TH0 = 0xDC; //设置定时初值
}
void Time1() interrupt 3
{
TR1=0;
if(Flag1==4) //流星灯
{
static unsigned int count,d;
count ++ ;
d++ ;
if(count>=1600)
{
D1 = _crol_(D1,1);
D2 = _crol_(D2,1);
D3 = _crol_(D3,1);
D4 = _crol_(D4,1);
count = 0;
}
d%=100;
if(d<=5)LED &= D1;
else LED |= ~D1;
if(d<=10)LED &= D2;
else LED |= ~D2;
if(d<=40)LED &= D3;
else LED |= ~D3;
if(d<=100)LED &= D4;
else LED |= ~D4;
TL1 = 0xA4; //设置定时初值
TH1 = 0xFF; //设置定时初值
}
if(Flag1==3) //呼吸灯
{
d++;
c ++ ;
c %= 100 ;//到达100后清0
if(d==50)
{
compare ++;
d=0;
if(compare==100){Flag2=~Flag2;compare=0;}
}
if(Flag2!=0xFF)
{
if(c>compare)
{
P2_0 = 1;
}
else
{
P2_0 = 0;
}
}
if(Flag2==0xFF)
{
if(c>compare)
{
P2_0 = 0;
}
else
{
P2_0 = 1;
}
}
TL1 = 0xA4 ; //100us
TH1 = 0xFF ;
}
if(Flag1==2) //跑马灯
{
b++;
if(b==200)
{
LED = D1;
D1 = _crol_(D1,1);
b=0;
}
TL1 = 0x66; //设置定时初值1ms
TH1 = 0xFC; //设置定时初值
}
if(Flag1==1) //闪烁灯
{
a++;
if(a==300)
{
a=0;
LED = ~LED;
}
TL1 = 0x66; //设置定时初值1ms
TH1 = 0xFC; //设置定时初值
}
TR1=1;
}
蜂鸣器部分:
#include <REGX52.H>
#include "DELAY.h"
sbit Beep = P2^5;
void Beep_voice(unsigned int e)
{
unsigned int j ;
for(j=0;j<400;j++)
{
Beep = ~Beep ;
Delayus(e);
}
}
延时函数部分:
#include<intrins.h>
void Delayus(unsigned int xus) //@11.0592MHz
{
unsigned char i;
while(xus--)
{
_nop_();
i = 25;
while (--i);
}
}
void Delayms(unsigned int xms)
{
unsigned char i, j;
while(xms--)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}
}