單片機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;	
	}	
}




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章