单片机C51 - 4按键4级变速跑马灯

       通过检测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;	
	}	
}




  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值