久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 6941|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

51單片機控制一個按鍵實現(xiàn)短按、長按,雙擊,控制LED亮滅,請幫忙看看程序,謝謝...

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:720799 發(fā)表于 2020-4-5 16:16 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
/*******************************************************************************
* 實 驗 名                 : 動態(tài)數(shù)碼管按鍵移動顯示試驗
* 實驗說明       :
* 連接方式       : 用排線將P0口和74H573旁邊的J12連接起來
*                * 將138譯碼器的A、B、C端分別接P2.2、P2.3、P2.4
*                * 用排線將P1口和矩陣鍵盤旁邊的JP4連接起來
* 注    意                 :
*******************************************************************************/
#include<reg51.h>
/*=============  
低層按鍵(I/0)掃描函數(shù),即低層按鍵設(shè)備驅(qū)動,只返回?zé)o鍵、短按和長按。具體雙擊不在此處判斷。參考本人教材的例9-1,稍微有變化。教材中為連_發(fā)。  
===============*/  
#define uchar unsigned char
#define uint unsigned int

sbit Chrg=P1^2;
sbit Done=P1^3;
sbit S1=P1^4;
sbit USBTest=P1^5;
sbit RED=P1^1;
sbit GREEN=P1^0;
sbit BLUE=P3^7;
sbit key_input_0=P3^6;
sbit Pout=P3^2;

#define N_key    0             //無鍵  
#define S_key    1             //單鍵  
#define D_key    2             //雙鍵  
#define L_key    3             //長鍵  

#define key_state_0 0  
#define key_state_1 1  
#define key_state_2 2  
#define key_state_3 3
bit time_10ms_ok;

uchar key_driver()  
{  
    static uchar key_state=key_state_0, key_time=0;  
    uchar key_press, key_return=N_key;  
    key_press=key_input_0;                                               // 讀按鍵I/O電平
    switch(key_state)  
    {  
                case key_state_0:                          // 按鍵初始態(tài)  
                if(!key_press) key_state=key_state_1;      // 鍵被按下,狀態(tài)轉(zhuǎn)換到按鍵消抖和確認(rèn)狀態(tài)  
        break;  

              case key_state_1:                          // 按鍵消抖與確認(rèn)態(tài)  
        if(!key_press)  
        {  
                key_time=0;                     
            key_state=key_state_2;      // 按鍵仍然處于按下,消抖完成,狀態(tài)轉(zhuǎn)換到按下鍵時間的計時狀態(tài),但返回的還是無鍵事件  
        }  
        else  
            key_state=key_state_0;   // 按鍵已抬起,轉(zhuǎn)換到按鍵初始態(tài)。此處完成和實現(xiàn)軟件消抖,其實按鍵的按下和釋放都在此消抖的。  
        break;  

        case key_state_2:  
        if(key_press)  
        {  
             key_return=S_key;         // 此時按鍵釋放,說明是產(chǎn)生一次短操作,回送S_key  
             key_state=key_state_0;    // 轉(zhuǎn)換到按鍵初始態(tài)  
        }  
        else if(++key_time>=100)             // 繼續(xù)按下,計時加10ms(10ms為本函數(shù)循環(huán)執(zhí)行間隔)  
        {  
             key_return=L_key;         // 按下時間>1000ms,此按鍵為長按操作,返回長鍵事件  
             key_state=key_state_3;    // 轉(zhuǎn)換到等待按鍵釋放狀態(tài)  
        }  
        break;  

        case key_state_3:                 // 等待按鍵釋放狀態(tài),此狀態(tài)只返回?zé)o按鍵事件  
        if(key_press) key_state=key_state_0; //按鍵已釋放,轉(zhuǎn)換到按鍵初始態(tài)  
        break;  
    }  
    return key_return;  
}  

/*=============  
中間層按鍵處理函數(shù),調(diào)用低層函數(shù)一次,處理雙擊事件的判斷,返回上層正確的無鍵、單鍵、雙鍵、長鍵4個按鍵事件。  
本函數(shù)由上層循環(huán)調(diào)用,間隔10ms  
===============*/  

uchar key_read()  
{  
    static uchar key_m=key_state_0, key_time_1=0;  
    uchar key_return=0,key_temp;  

    key_temp=key_driver();  

    switch(key_m)  
    {  
        case key_state_0:  
            if(key_temp==S_key)  
            {  
                 key_time_1=0;               // 第1次單擊,不返回,到下個狀態(tài)判斷后面是否出現(xiàn)雙擊  
                 key_m=key_state_1;  
            }  
            else  
                 key_return=key_temp;        // 對于無鍵、長鍵,返回原事件  
            break;  

        case key_state_1:  
            if(key_temp==S_key)             // 又一次單擊(間隔肯定<500ms)  
            {  
                 key_return=D_key;          // 返回雙擊鍵事件,回初始狀態(tài)  
                 key_m=key_state_0;  
            }  
            else                                 
            {                                // 這里500ms內(nèi)肯定讀到的都是無鍵事件,因為長鍵>1000ms,在1s前低層返回的都是無鍵  
                 if(++key_time_1>=50)  
                 {  
                      key_return=S_key;      // 500ms內(nèi)沒有再次出現(xiàn)單鍵事件,返回上一次的單鍵事件  
                      key_m=key_state_0;     // 返回初始狀態(tài)  
                 }  
             }  
             break;  
    }
    return key_return;  
}   



void delay_ms(uint sec)
  {
   uint i;
   while(sec--)
     {
            for(i=0;i<1000;i++)
              {
                     ;//_nop();
                     }
           }
   }

/*
下面,根據(jù)程序分析按鍵事件的反映時間:  
1。對于長鍵,按下超過1s馬上響應(yīng),反映最快  
2。對于雙鍵,第2次按鍵釋放后馬上得到反映。  
3。對于單鍵,釋放后延時拖后500ms才能響應(yīng),反映最慢。這個與需要判斷后面是否有雙擊操作有關(guān),只能這樣。實際應(yīng)用中,可以調(diào)整兩次單擊間隔時間定義,比如為300ms,這樣單擊的響應(yīng)回快一點,單按鍵操作人員需要加快按鍵的操作過程。如果產(chǎn)品是針對老年人的,這個時間不易太短,因為年紀(jì)大的人,反映和動作都比較慢。  

   當(dāng)然,上面兩段可以合在一起。我這樣做的目的,是為了可以方便的擴展為N擊(當(dāng)然,需要做修改)。可是最底層的就是最基本的操作處理短按和長按,不用改動的。至于雙擊,還是N擊,在中間層處理。這就是程序設(shè)計中分層結(jié)構(gòu)的優(yōu)點。  

測試代碼環(huán)境如下:   
*/

void main()   
{
        uchar key;  
          TMOD=0x01;                 //定時器模式選擇,選擇T0定時器,方式1
          TR0=1;                         //1 打開定時器0
          ET0=1;                           //定時器0中斷使能位
          EA=1;                             //使能全局中斷
        TH0=(65536-10000)/256;
        TL0=(65536-10000)%256;  
    while(1)   
    {   
                       
        if(time_10ms_ok)            //每10ms執(zhí)行一次,   
        {   
             time_10ms_ok=0;
             key=key_read();       //《====== 10ms一次調(diào)用按鍵中間層函數(shù),根據(jù)返回鍵值,點亮不同的LED燈,全面測試按鍵操作是否正常   
             if(key==L_key)   
                           RED=1;Pout=0;                                                 
             if(key==D_key)   
                                                               GREEN=1;Pout=1;
             if(key==S_key)   
                           BLUE=1;Pout=0;
         }   
    }   
}

void time0() interrupt 1      // 定時器10ms中斷服務(wù)  
{  
        TH0=(65536-10000)/256;
        TL0=(65536-10000)%256;
        time_10ms_ok=1;
}   



分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 亚洲一区二区三区四区视频 | 亚洲国产小视频 | 国产欧美一区二区久久性色99 | 在线一区二区三区 | 久久久999国产精品 中文字幕在线精品 | 中文字幕亚洲无线 | 亚洲区一区二区 | 伊人春色成人网 | 午夜国产 | 亚洲黄色av网站 | 久久久视频在线 | 国产精品一区二区av | 国产精品成人国产乱一区 | 国产一区二区三区久久久久久久久 | 福利视频网站 | 中文字幕av在线一二三区 | 日韩播放 | 国产亚洲一区二区在线观看 | 成人免费视频在线观看 | 成年人在线观看视频 | 九九导航| 亚洲国产激情 | 日本一区二区三区四区 | 成人国产精品久久 | 国产资源在线观看 | 亚洲综合色视频在线观看 | 成人在线观看免费 | 欧美中文字幕在线观看 | 欧美一级免费看 | 久久久在线视频 | 欧美成年黄网站色视频 | 91www在线观看 | av黄色国产 | 午夜亚洲 | 国产精品96久久久久久 | 日韩色视频 | 欧美激情一区二区三区 | 最新中文字幕 | 欧美天堂 | 亚洲一区导航 | 久久中文视频 |