国产免费AV|泡泡玛特欧洲总部将设在伦敦|中文天堂网www新版资源在线|一本久道综合在线中文|国精产品一二三产区的使用方法|香蕉鱼在线观看|www.27eee

ELEOK

標(biāo)題: 51單片機實用按鍵模塊 沒有延時 while語句,可以直接使用 [打印本頁]

作者: eng    時間: 2021-6-8 01:15
標(biāo)題: 51單片機實用按鍵模塊 沒有延時 while語句,可以直接使用
單片機實用按鍵模塊,沒有延時語句、while()語句,資源占用小??梢灾苯訌?fù)制使用與其他程序不沖突。
使用時只需要直接引用全局變量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關(guān)
}
if(key1==20) //k按鍵長按
{
   key1=0;//必須軟件清零?。。?br />    LED1=1; //0開1關(guān)
}

3、k3按鍵按下LED1亮,K4按下LED1滅,
if(key1==3) //k3按鍵按下
{
   key1=0;//必須軟件清零?。。?br />    LED1=0; //0開1關(guān)
}
if(key1==4) //k4按鍵按下
{
   key1=0;//必須軟件清零?。?!
   LED1=1; //0開1關(guān)
}

4、K3按下一次,數(shù)據(jù)m 增加1,長按k3兩秒以上每隔500ms數(shù)據(jù)m 增加10;K4按下一次,數(shù)據(jù)m 減少1,長按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; //長按k3兩秒以上每隔500ms數(shù)據(jù)m 增加10,ms1是毫秒變量,需要放在定時器1ms中斷中自加,ms1++;
}
else ms1=0;        //復(fù)位

if(key1==4) //k4按鍵按下
{
   key1=0;//必須軟件復(fù)位
   m--; //數(shù)據(jù)m -1
}
if(key2==4) //k4按鍵按下兩秒以上 ,注意key2不需要清零,key1必須清零?。。?br /> {
   if(ms2>2000&&ms2%500==0)  m=m-10; //長按k4兩秒以上每隔500ms,ms2是毫秒變量,需要放在定時器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,四個按鍵可以是任意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];//按鍵變量數(shù)組,4個按鍵互不影響,如果用key1,一次只能夠按一個按鍵,不允許同時按鍵。
u8 key1;//按鍵變量1,輸出按鍵單擊,長按。每單擊或長按一次只輸出一次,由調(diào)用函數(shù)清零。//key1=1/2/3/4是對應(yīng)的按鍵單擊,key1=10、20、30、40是對應(yīng)的按鍵長按。key1=0表示沒有按鍵按下。
//key1主要用途是:判斷某一個按鍵是單擊還是長按.注意調(diào)用函數(shù)需要將key1清零?。?!
//u8 key2[4];//按鍵變量數(shù)組,4個按鍵互不影響,如果用key2,一次只能夠按一個按鍵,不允許同時按鍵。
u8 key2;//按鍵變量2,輸出按鍵單擊,每10ms輸出一次,key1=1/2/3/4是對應(yīng)的按鍵單擊。
//key2主要用途是:長按按鍵時快速增加或減少數(shù)值。
u16 ms1,ms2;//毫秒計時
u16 m;//
void key() //按鍵處理模塊,需要放在10ms中斷中運行?。。?br /> /* 說明:1、按鍵單擊,指按下100-1000ms內(nèi)釋放,加入時間限制是為了防止干擾。
             2、按鍵長按,指按下3-10s內(nèi)釋放,加入時間限制是為了防止干擾。
              3、函數(shù)運行后,按鍵值保存在key1、key2。用戶直接調(diào)用key1、key2即可。

*/
{
  //靜態(tài)變量,必須要static
  u16 static kgr[4];    //必須要static,抗干擾時間數(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個按鍵處理,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秒,強制復(fù)位,防止誤按。
                   { anjtem[ i]=0; //按鍵釋放中間變量。與上面互鎖
                     kgr[ i]=0;
                     key1=0;
//                  key1[ i]=0;//數(shù)組,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;//數(shù)組,4個按鍵獨立
           else if(kgr[ i]>300&&kgr[ i]<1000) //按鍵間隔3000--10000毫秒才有效,防止電磁干擾。時間可以修改
                 key1=(i+1)*10;//長按,按鍵間隔3--10秒,每次釋放只寫1次。
           //key1[ i]=(i+1)*10;//數(shù)組,4個按鍵獨立
           else key1=0;    //清零。  
     }
  }

//下面是處理:key2是有按鍵按下就輸出鍵值。        
    for(i=0;i<3;i++)
         { if(L_anj[ i]==0)
           key2=i+1;//一次只能夠按一個按鍵,不允許同時按鍵。
         //key2[ i]=i+1;//數(shù)組,4個按鍵獨立.
         }
}


void timer0() interrupt 1                 //計時器T0中斷1ms。
{
  //靜態(tài)變量,必須要static
  u8  static time=0;   //毫秒變量。
  time++;//毫秒計時。
  if(time>9) //10ms運行一次按鍵處理函數(shù),不需要防抖程序。
  {
       time=0;
        key();//按鍵處理模塊,需要放在10ms中斷中運行?。。?br />   }
//下面的語句不是按鍵模塊需要的,可以刪除。
    ms1++;ms2++;//毫秒計時
}

void main()
{
//1毫秒@12.000MHz,下面是STC單片機定時器0代碼,如果是別的單片機請根據(jù)手冊修改
        AUXR |= 0x80;                //定時器時鐘1T模式
        TMOD &= 0xF0;                //設(shè)置定時器模式
        TL0 = 0x20;                //設(shè)置定時初值,1毫秒@12.000MHz
        TH0 = 0xD1;                //設(shè)置定時初值,1毫秒@12.000MHz
        TF0 = 0;                //清除TF0標(biāo)志        
        ET0 = 1;        //使能定時器中斷
       EA = 1;                    //打開總中斷
        TR0 = 1;                //定時器0開始計時
while(1)
  {
//1、k1按鍵按下LED1亮,再次按下LED1滅,
    if(key1==1)        //k1按鍵按下
     {
       key1=0;//必須軟件清零?。。?br />        LED1=~LED1;
     }

//2、k2按鍵按下LED1亮,K2長按LED1滅,
    if(key1==2) //k2按鍵按下
     {
       key1=0;//必須軟件清零!??!
       LED1=0; //0開1關(guān)
     }
   if(key1==20) //k按鍵長按
     {
       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,長按k3兩秒以上每隔500ms數(shù)據(jù)m 增加10;K4按下一次,數(shù)據(jù)m 減少1,長按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;} //長按k3兩秒以上每隔500ms數(shù)據(jù)m 增加10,ms1是毫秒變量,需要放在定時器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;} //長按k4兩秒以上每隔500ms,ms2是毫秒變量,需要放在定時器1ms中斷中自加,ms2++;
    }
   else ms2=0;//復(fù)位
}
}
這是按鍵檢測模塊函數(shù):要認(rèn)真看才能夠理解。
void key() //按鍵處理模塊,需要放在10ms中斷中運行?。?!
/* 說明:1、按鍵單擊,指按下100-1000ms內(nèi)釋放,加入時間限制是為了防止干擾。
             2、按鍵長按,指按下3-10s內(nèi)釋放,加入時間限制是為了防止干擾。
             3、函數(shù)運行后,按鍵值保存在key1、key2。用戶直接調(diào)用key1、key2即可。
*/
{
  u16 static kgr[4];    //必須要static,抗干擾時間數(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個按鍵處理,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秒,強制復(fù)位,防止誤按。
                   { anjtem[ i]=0; //按鍵釋放中間變量。與上面互鎖
                     kgr[ i]=0;
                     key1=0;
                   }
           }
         }

     else    //按鍵釋放
     { kanggr[ i]=0;           //中間變量1,與上面互鎖
           if(kgr[ i]>9 && kgr[ i]<99) //按鍵間隔100--1000毫秒才有效,防止電磁干擾。時間可以修改
                 key1=i+1;   //單擊,按鍵間隔100--1000毫秒,每次釋放只寫1次。一次只能夠按一個按鍵,不允許同時按鍵。
           else if(kgr[ i]>300 && kgr[ i]<1000) //按鍵間隔3000--10000毫秒才有效,防止電磁干擾。時間可以修改
                 key1=(i+1)*10;//長按,按鍵間隔3--10秒,每次釋放只寫1次。
           else key1=0;    //清零。  
     }
  }

//下面是處理:key2是有按鍵按下就輸出鍵值。        
    for(i=0;i<3;i++)
         { if(L_anj[ i]==0)
           key2=i+1;//一次只能夠按一個按鍵,不允許同時按鍵。
         }
}







歡迎光臨 ELEOK (http://m.afoofa.cn/) Powered by Discuz! X5.0