新聞中心

        51單片機按鍵雙擊

        作者: 時間:2016-11-25 來源:網(wǎng)絡(luò) 收藏
        //hnrain 改

        //適用于CEPARK 51開發(fā)板

        本文引用地址:http://www.104case.com/article/201611/321094.htm

        /*****************************************************************************************************************
        www.cepark.com電子園 按鍵高階攻略設(shè)計大賽

        名稱:2*4矩陣鍵盤掃描(狀態(tài)機)
        功能:按鍵0單擊時,點亮P0口的第1357個LED,按鍵1雙擊時,點亮P0口的2468個LED,按鍵2三擊時,點亮P0口的所有的LED
        按鍵按下的時間間隔小于200ms。 其他鍵按下時,LED狀態(tài)不變
        作者:alger2009
        時間:2009.12.30 星期三
        版本:V1.0
        其他:該開發(fā)板的LED不是單個的LED組成,而是LED邏輯卡;看門狗程序防止程序跑飛

        *****************************************************************************************************************/

        #include"reg52.h"
        #include"intrins.h"
        #include"key2.h"


        /******宏定義***************************************************************************************************/
        #defineNo_key 255//無鍵按下返回值


        /******定義全局變量********************************************************************************************/
        unsigned charkeyread_flag=0;//矩陣鍵盤掃描標(biāo)志位
        unsigned char num=0;//定時計數(shù)器計數(shù)變量
        unsigned charoutdata=0;//返回值

        /******2*4矩陣鍵盤掃描程序**********************************************************************************************
        返回值:key_return
        key_return=0 單擊
        key_return=1 雙擊
        key_return=2 三擊
        key_return=其他,按鍵無效
        ************************************************************************************************************************/
        unsigned char read_keyboard(void)
        {
        static unsigned char key_state=0,key_value,key_line;// 列讀取變量,行掃描碼
        static unsigned char key_times=0;//按鍵擊打次數(shù)
        static unsigned char Tcount=0;//按鍵連擊計時變量
        unsigned char key_return=No_key,i;//按鍵返回值
        switch(key_state)
        {
        case 0://key you meiyou cunzai jiancha//狀態(tài)0功能: 按鍵掃描 連擊計時 和連擊超時處理
        key_line=0x10;
        if(key_times!=0)Tcount++;//如果不是第一次擊打,計時變量加1
        if(Tcount>20)//若連擊按鍵按下時間間隔大于200毫秒
        {
        key_times=0;// 按鍵擊打次數(shù)歸0
        Tcount=0;// 計時變量歸0
        }
        for(i=0;i<2;i++)// 掃描鍵盤
        {
        P2=~key_line;// 輸入行掃描碼
        P2=~key_line;// 重復(fù)送一次
        key_value=0x0f & P2;// 讀列電平
        if(key_value==0x0f)
        key_line<<=1;// 沒有按鍵,繼續(xù)掃描
        else
        {
        key_state++;// 有按鍵,停止掃描
        break;// 跳出按鍵掃描
        }
        }
        break;
        case 1://狀態(tài)1功能:確認按鍵 讀取按鍵值
        if(key_value==(0x0f & P2))// 再次讀列電平,若非抖動
        {
        switch(key_line|key_value)//行掃描碼和列電平,確認按鍵
        {// 鍵盤編碼,返回編碼值
        case 0x1e://單擊按鍵0
        key_return=1;
        break;
        case 0x1d:
        {
        if(key_times==1 && Tcount<20)
        key_return=2;//雙擊按鍵1
        else
        key_times++;//第一次按下,計數(shù)加1
        }
        break;
        case 0x1b:
        {
        if(key_times==2 && Tcount<20)
        key_return=3;//三擊按鍵2
        else
        key_times++;//第一次或第二次按下,計數(shù)加1
        }
        break;
        case 0x17:
        key_return=4;
        break;
        case 0x27:
        key_return=5;
        break;
        case 0x2b:
        key_return=6;
        break;
        case 0x2d:
        key_return=7;
        break;
        case 0x2e:
        key_return=8;
        break;
        }
        key_state++;// 轉(zhuǎn)入等待按鍵釋放狀態(tài)
        }
        else
        key_state--;// 兩次列電平不同返回狀態(tài)0,(消抖處理)
        break;
        case 2://狀態(tài)2功能:按鍵釋放判定
        P2=0x0f;// 行線全部輸出低電平
        P2=0x0f;// 重復(fù)送一次
        if((P2 & 0x0f)==0x0f)
        key_state=0;// 按鍵釋放,返回狀態(tài)0
        break;
        }
        return key_return;//返回值
        }


        /******定時器1 定時1毫秒******************************************************************************/
        void timer1(void)interrupt 3
        {
        TH1=(65536-1000)/256;
        TL1=(65536-1000)%256;
        if(++num==10)
        {keyread_flag=1;//按鍵掃描允許標(biāo)志位
        num=0;
        }
        }


        /******定時器初始化**********************************************************************************/
        void timer1_initial(void)
        {
        TH1=(65536-1000)/256;
        TL1=(65536-1000)%256; //裝初始值
        IE=0x88; //開總中斷和定時器1中斷
        TMOD=0x10; //工作方式1
        TR1=1; //啟動定時器
        }


        /******看門狗子程序*********************************************************************************/
        void clr_wdt(void)
        {
        WDTRST=0x1e;
        WDTRST=0xe1;
        }


        /******主程序****************************************************************************************/
        main(void)
        {
        P0=0xff;//初始化LED端口
        timer1_initial();//定時器1初始化
        while(1)
        {
        if(keyread_flag==1)//矩陣掃描標(biāo)志位允許
        {
        keyread_flag=0;
        clr_wdt();//調(diào)用看門狗 (每2的14次方個機器周期內(nèi)必須調(diào)用一次,使看門狗復(fù)位)
        outdata=read_keyboard();//讀取矩陣鍵盤返回值
        }

        if(outdata==1)
        P0=0xaa;//單擊按鍵0 點亮第1357個LED
        elseif(outdata==2)
        P0=0x55;//雙擊按鍵1 點亮第2468個LED
        elseif(outdata==3)
        P0=0x00;//三擊按鍵2 點亮全部LED
        }
        }



        關(guān)鍵詞: 51單片機按鍵雙

        評論


        技術(shù)專區(qū)

        關(guān)閉
        主站蜘蛛池模板: 彭州市| 渑池县| 东乌珠穆沁旗| 隆安县| 东乡族自治县| 乌海市| 荣昌县| 原平市| 宝清县| 柞水县| 大同县| 商丘市| 三穗县| 时尚| 滦平县| 讷河市| 陵川县| 华坪县| 长寿区| 香格里拉县| 唐河县| 宜兴市| 北票市| 房山区| 嵩明县| 紫金县| 黑水县| 威海市| 公主岭市| 萨迦县| 临安市| 旺苍县| 射阳县| 枣阳市| 繁峙县| 长兴县| 遂溪县| 宜君县| 专栏| 报价| 新河县|