本帖最后由 hhh402 于 2021-6-13 12:55 編輯
單片機實用按鍵模塊,沒有延時語句、while()語句,資源占用小。可以直接復制使用與其他程序不沖突。
使用時只需要直接引用全局變量key1和key2就可以。舉例:
1、k1按鍵按下LED1亮,再次按下LED1滅,
if(key1==1) //k1按鍵按下
{
key1=0;//必須軟件清零!!!
LED1=~LED1;
}
2、k2按鍵按下LED1亮,K2長按LED1滅,
if(key1==2) //k2按鍵按下
{
key1=0;//必須軟件清零!!!
LED1=0; //0開1關
}
if(key1==20) //k按鍵長按
{
key1=0;//必須軟件清零!!!
LED1=1; //0開1關
}
3、k3按鍵按下LED1亮,K4按下LED1滅,
if(key1==3) //k3按鍵按下
{
key1=0;//必須軟件清零!!!
LED1=0; //0開1關
}
if(key1==4) //k4按鍵按下
{
key1=0;//必須軟件清零!!!
LED1=1; //0開1關
}
4、K3按下一次,數據m 增加1,長按k3兩秒以上每隔500ms數據m 增加10;K4按下一次,數據m 減少1,長按k4兩秒以上每隔500ms數據m 減少10;
if(key1==3) //k3按鍵按下
{
key1=0;//必須軟件復位
m++; //數據m 增加1
}
if(key2==3) //k3按鍵按下兩秒以上,注意key2不需要清零,key1必須清零!!!
{
if(ms1>2000&&ms1%500==0) m=m+10; //長按k3兩秒以上每隔500ms數據m 增加10,ms1是毫秒變量,需要放在定時器1ms中斷中自加,ms1++;
}
else ms1=0; //復位
if(key1==4) //k4按鍵按下
{
key1=0;//必須軟件復位
m--; //數據m -1
}
if(key2==4) //k4按鍵按下兩秒以上 ,注意key2不需要清零,key1必須清零!!!
{
if(ms2>2000&&ms2%500==0) m=m-10; //長按k4兩秒以上每隔500ms,ms2是毫秒變量,需要放在定時器1ms中斷中自加,ms2++;
}
else ms2=0;//復位
//下面是完整程序代碼:
#include "stc8.h"
#include "intrins.h"
#define u8 unsigned char
#define u16 unsigned int
sbit k1=P0^0;//按鍵1,四個按鍵可以是任意I/O口。按鍵按下時k1=0,按鍵釋放k1=1
sbit k2=P0^1;//按鍵2
sbit k1=P0^2;//按鍵3
sbit k1=P0^3;//按鍵4
sbit LED1=P1^0;//LED1
//u8 key1[4];//按鍵變量數組,4個按鍵互不影響,如果用key1,一次只能夠按一個按鍵,不允許同時按鍵。
u8 key1;//按鍵變量1,輸出按鍵單擊,長按。每單擊或長按一次只輸出一次,由調用函數清零。//key1=1/2/3/4是對應的按鍵單擊,key1=10、20、30、40是對應的按鍵長按。key1=0表示沒有按鍵按下。
//key1主要用途是:判斷某一個按鍵是單擊還是長按.注意調用函數需要將key1清零!!!
//u8 key2[4];//按鍵變量數組,4個按鍵互不影響,如果用key2,一次只能夠按一個按鍵,不允許同時按鍵。
u8 key2;//按鍵變量2,輸出按鍵單擊,每10ms輸出一次,key1=1/2/3/4是對應的按鍵單擊。
//key2主要用途是:長按按鍵時快速增加或減少數值。
u16 ms1,ms2;//毫秒計時
u16 m;//
void key() //按鍵處理模塊,需要放在10ms中斷中運行!!!
/* 說明:1、按鍵單擊,指按下100-1000ms內釋放,加入時間限制是為了防止干擾。
2、按鍵長按,指按下3-10s內釋放,加入時間限制是為了防止干擾。
3、函數運行后,按鍵值保存在key1、key2。用戶直接調用key1、key2即可。
*/
{
//靜態變量,必須要static
u16 static kgr[4]; //必須要static,抗干擾時間數組
u8 static kanggr[4]; //中間變量1
u8 static anjtem[4]; //按鍵釋放中間變量。
u8 i;
u8 L_anj[4];
L_anj[0]=k1;
L_anj[1]=k2;
L_anj[2]=k3;
L_anj[3]=k4;
for(i=0;i<3;i++) //4個按鍵處理,key1,
{
if(L_anj[ i]==0) //按鍵按下
{ if(kanggr[ i]==0) //中間變量1,與下面互鎖
{ kgr[ i]=0; //抗干擾時間清零,每次按鍵只寫1次。
kanggr[ i]=1; //中間變量1
anjtem[ i]=1; //按鍵釋放中間變量。與下面互鎖
}
if(anjtem[ i]==1)
{
kgr[ i]++;//10毫秒計時。
if(kgr[ i]>1000) //按鍵按下大于10秒,強制復位,防止誤按。
{ anjtem[ i]=0; //按鍵釋放中間變量。與上面互鎖
kgr[ i]=0;
// key1[ i]=0;//數組,4個按鍵獨立
}
}
}
else //按鍵釋放
{ kanggr[ i]=0; //中間變量1,與上面互鎖
if(kgr[ i]>9&&kgr[ i]<99) //按鍵間隔100--1000毫秒才有效,防止電磁干擾。時間可以修改
key1=i+1; //單擊,按鍵間隔100--1000毫秒,每次釋放只寫1次。一次只能夠按一個按鍵,不允許同時按鍵。
//key1[ i]=i+1;//數組,4個按鍵獨立
else if(kgr[ i]>300&&kgr[ i]<1000) //按鍵間隔3000--10000毫秒才有效,防止電磁干擾。時間可以修改
key1=(i+1)*10;//長按,按鍵間隔3--10秒,每次釋放只寫1次。
//key1[ i]=(i+1)*10;//數組,4個按鍵獨立
}
}
//下面是處理:key2是有按鍵按下就輸出鍵值。
for(i=0;i<3;i++)
{ if(L_anj[ i]==0)
key2=i+1;//一次只能夠按一個按鍵,不允許同時按鍵。
//key2[ i]=i+1;//數組,4個按鍵獨立.
}
}
void timer0() interrupt 1 //計時器T0中斷1ms。
{
//靜態變量,必須要static
u8 static time=0; //毫秒變量。
time++;//毫秒計時。
if(time>9) //10ms運行一次按鍵處理函數,不需要防抖程序。
{
time=0;
key();//按鍵處理模塊,需要放在10ms中斷中運行!!!
}
//下面的語句不是按鍵模塊需要的,可以刪除。
ms1++;ms2++;//毫秒計時
}
void main()
{
//1毫秒@12.000MHz,下面是STC單片機定時器0代碼,如果是別的單片機請根據手冊修改
AUXR |= 0x80; //定時器時鐘1T模式
TMOD &= 0xF0; //設置定時器模式
TL0 = 0x20; //設置定時初值,1毫秒@12.000MHz
TH0 = 0xD1; //設置定時初值,1毫秒@12.000MHz
TF0 = 0; //清除TF0標志
ET0 = 1; //使能定時器中斷
EA = 1; //打開總中斷
TR0 = 1; //定時器0開始計時
while(1)
{
//1、k1按鍵按下LED1亮,再次按下LED1滅,
if(key1==1) //k1按鍵按下
{
key1=0;//必須軟件清零!!!
LED1=~LED1;
}
//2、k2按鍵按下LED1亮,K2長按LED1滅,
if(key1==2) //k2按鍵按下
{
key1=0;//必須軟件清零!!!
LED1=0; //0開1關
}
if(key1==20) //k按鍵長按
{
key1=0;//必須軟件清零!!!
LED1=1; //0開1關
}
//3、k3按鍵按下LED1亮,K4按下LED1滅,
if(key1==3) //k3按鍵按下
{
key1=0;//必須軟件清零!!!
LED1=0; //0開1關
}
if(key1==4) //k4按鍵按下
{
key1=0;//必須軟件清零!!!
LED1=1; //0開1關
}
//4、K3按下一次,數據m 增加1,長按k3兩秒以上每隔500ms數據m 增加10;K4按下一次,數據m 減少1,長按k4兩秒以上每隔500ms數據m 減少10;
//m的范圍:0-60000
if(key1==3) //k3按鍵按下
{
key1=0;//必須軟件清零!!!
if(m<60000) m++; //數據m 增加1
}
if(key2==3) //k3按鍵按下兩秒以上,注意key2不需要清零,key1必須清零!!!
{
if(ms1>2000&&ms1%500==0)
{if(m<=59990) m=m+10;} //長按k3兩秒以上每隔500ms數據m 增加10,ms1是毫秒變量,需要放在定時器1ms中斷中自加,ms1++;
}
else ms1=0; //復位
if(key1==4) //k4按鍵按下
{
key1=0;//必須軟件復位
if(m>0) m--; //數據m -1
}
if(key2==4) //k4按鍵按下兩秒以上 ,注意key2不需要清零,key1必須清零!!!
{
if(ms2>2000&&ms2%500==0)
{if(m>9) m=m-10;} //長按k4兩秒以上每隔500ms,ms2是毫秒變量,需要放在定時器1ms中斷中自加,ms2++;
}
else ms2=0;//復位
}
}
|