通过检测K1、K2、K3、K4,4个按键是否按下来控制跑马灯的速度,从而使跑马灯达到4个按键4级变速的效果。但按键按下时可能会有抖动的情况,每次按下时,可能会发生了人难以觉察到的多次抖动,相当于一下子按下了很多次。这会导致程序无法识别出您真正的按键意图。但是抖动一般都是发生在刚按下键和松开键的时候,所以,我们只要避开这一段时间,等键稳定按下或者松开时,再去读它的值,一般就可以正确读取了。所以,当读到第一次按键的值时,要延时等待一会,再处理。在松开后,也延时一会,免得检测到松开的抖动以为又有按键。
另外,因为程序是循环运行的,当一次按键处理后,又会再循环回来继续检测,如果您的按键这时还没有松开,又会被读到一次新的按键,并做处理。所以我们还要做一个特殊的处理,识别到一个按键并处理完成之后,还要等待这个按键松开后,再继续循环运行。
#include <reg51.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
uchar speed = 10;
bit delay = 0;
sbit K1= P3^0;
sbit K2= P3^1;
sbit K3= P3^2;
sbit K4= P3^3;
/*******************************************************************************
* 函数名 : Delay1ms()
* 函数功能 : 延时函数,延时1ms
* 输入 : 无
* 输出 : 无
*******************************************************************************/
void Delay1ms(uint x)
{
uint y;
for(x; x > 0; x--)
for(y = 110; y > 0; y--);
}
/*******************************************************************************
* 函数名 : ClearShake()
* 函数功能 : 按键消抖,并检查按键,设置对应的跑马速度
* 输入 : k,按键号,s,跑马灯速度
* 输出 : 无
*******************************************************************************/
void ClearShake(bit k, uchar s)
{
uchar i;
if(k == 0)
{
Delay1ms(10);
if(k == 0)
{
speed = s;
while((i < 50) && (k == 0))
{
Delay1ms(10);
i++;
}
i = 0;
}
}
}
/*******************************************************************************
* 函数名 : TimerConfiguration()
* 函数功能 : 配置定时器值
* 输入 : 无
* 输出 : 无
*******************************************************************************/
void TimerConfiguration()
{
TMOD = 0x01; //选择工作方式1
TH0 = 0x28; //设置初始值
TL0 = 0x83;
EA = 1; //打开总中断
ET0 = 1; //打开定时器0中断
TR0 = 1; //启动定时器0
}
void main()
{
P0 = 0x01;
TimerConfiguration();
while(1)
{
if(delay)
{
delay = 0;
P0 = _crol_(P0,1);
}
ClearShake(K1,72); //检查到按键,设置对应的跑马速度
ClearShake(K2,36);
ClearShake(K3,18);
ClearShake(K4,9);
}
}
/*******************************************************************************
* 函数名 : Timer0()
* 函数功能 : 定时器0中断函数
* 输入 : 无
* 输出 : 无
*******************************************************************************/
void Time0() interrupt 1
{
uchar t;
t++;
if((t == speed) || t > 30)
{
t = 0;
delay = 1;
}
}