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