通過檢測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;
}
}