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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1829|回復: 7
打印 上一主題 下一主題
收起左側

一個按鍵實現長按,單擊,多擊源程序

  [復制鏈接]
跳轉到指定樓層
樓主
ID:1123636 發表于 2024-11-20 15:59 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
/*===============================================================
功能:一個按鍵實現按鍵的長按,短按,多擊
長按:按下有效,有長按,短按一般來講都是松開有效
多擊(包含單擊):松開有效

按鍵按下的觸發事件:(觸發事件可以按需求修改)
長按:點亮Led0
單擊:點亮Led1
雙擊:點亮Led2
三擊:點亮Led3
===============================================================*/

/*============================注意事項==================================
1.關于Seg的變量和ucLed可以不必理會,
前者是數碼管顯示Reg_Test_Count,后者是按鍵按下后的觸發事件。這兩個大家可以自己更改
=======================================================================*/

/* 頭文件聲明區 */
#include <STC15F2K60S2.H>//單片機寄存器專用頭文件
#include <Init.h>//初始化底層驅動專用頭文件
#include <Led.h>//Led底層驅動專用頭文件
#include <Key.h>//按鍵底層驅動專用頭文件
#include <Seg.h>//數碼管底層驅動專用頭文件

sbit KEY4 = P3^3;    //定義了一個按鍵


/* 變量聲明區 */

unsigned char Key_Slow_Down;                                                                  //按鍵減速專用變量
unsigned char Seg_Buf[8] = {10,10,10,10,10,10,10,10};                               //數碼管顯示數據存放數組
unsigned char Seg_Pos;                                                                             //數碼管掃描專用變量
unsigned int  Seg_Slow_Down;                                                                   //數碼管減速專用變量
unsigned char ucLed[8] = {0,0,0,0,0,0,0,0};                                                //Led顯示數據存放數組

/*變量*/
unsigned int Reg_Test_Count;                                                                      //測試用的一個變量,表示短按了多少次。這個可以自己定義一個
unsigned int Reg_Tick;                                                                                //表示每次按下的時間間隔是多少。初始值可以自己改,看后面的代碼就知道了
unsigned int Reg_Key_Filter_50ms;                                                                //按下時濾波,我這里濾波50ms。
unsigned int Reg_Key_10ms;                                                                        //10ms計數

/*標志位*/
unsigned char Bit_Short_Press;                                                                                                //短按標志位               
unsigned char Bit_10ms;                                                                                                        //10ms定時到達標志位
/* 鍵盤處理函數 */
void Key_Proc()
{
        static unsigned int Reg_Key_Press_Time = 0;          //請記得標為靜態變量
        if(Bit_10ms)                                                                                                                  //10ms進來一次
        {
                Bit_10ms = 0;
    if(KEY4==0)                                                                                                                           //如果按下了按鍵
                {
                        Reg_Tick = 50;                                                                                                   //給多擊的時間間隔賦初值
                        if(++Reg_Key_Press_Time <=0 ) --Reg_Key_Press_Time;                                 //計量按鍵時間,并避免數據溢出        
                        if(Bit_Short_Press == 0)                  //判斷短按標志位
                        {
                                if(++Reg_Key_Filter_50ms >= 5)                                                            //如果濾波時間到達了50ms
                                {
                                        Reg_Key_Filter_50ms = 0;                                                                    //濾波時間清0
                                        Reg_Test_Count++;                                                                                       
                                        Bit_Short_Press = 1;                                                                             //短按標志位置1
                                }
                        }               
                        if(Reg_Key_Press_Time >= 100)                                                                              //長按時間已經到達1s        
                        {
                                ucLed[0] = 1;                                                                                                //這里寫事件,我這里寫的點燈
                        }
    }
                else//松開
                {
                        Reg_Key_Filter_50ms = 0;                                                                                        //濾波的50ms只有檢測到高電平立馬清零,此次按鍵無效
                        Bit_Short_Press = 0;                                                                                                //短按標志位清零
                        Reg_Key_Press_Time = 0;                                                                                        //長按計數清零
                        if(Reg_Tick)                                                                                                        //如果多擊時間間隔不為零
                        {
                                Reg_Tick--;                                                                                                               
                        }
                        if(Reg_Tick == 0)                                                                                                //只要減到0,就說明此時我已經不再按下按鍵了,開始寫多擊事件
                        {
                                if(Reg_Test_Count == 1)                                                                                 //如果按下一次
                                {
                                        ucLed[1] = 1;                                                                                         //寫按下一次的事件,這個可以自己改,我寫的點燈
                                }
                                else if(Reg_Test_Count == 2)                                                                          //如果按下兩次
                                {
                                        ucLed[2] = 1;                                                                                          //同上
                                }
                                else if(Reg_Test_Count == 3)                                                                           //如果按下三次
                                {
                                        ucLed[3] = 1;                                                                                            //同上
                                }
                                Reg_Test_Count = 0;                                                                                                 //Reg_Test_Count清零,等待執行下一次多擊事件
                                        //到這里就完整的執行了一次多擊事件,注意Reg_Test_Count一定要清零。
                        }              
    }
        }
}

/* 信息處理函數 */
void Seg_Proc()
{
        if(Seg_Slow_Down) return;
        Seg_Slow_Down = 1;//數碼管減速程序
        Seg_Buf[0] = Reg_Test_Count%10;
}


/* 定時器0中斷初始化函數 */
void Timer0Init(void)                //1毫秒@12.000MHz
{
        AUXR &= 0x7F;                //定時器時鐘12T模式
        TMOD &= 0xF0;                //設置定時器模式
        TL0 = 0x18;                //設置定時初始值
        TH0 = 0xFC;                //設置定時初始值
        TF0 = 0;                //清除TF0標志
        TR0 = 1;                //定時器0開始計時
        ET0 = 1;    //定時器中斷0打開
        EA = 1;     //總中斷打開
}


/* 定時器0中斷服務函數 */
void Timer0Server() interrupt 1
{  
        if(++Key_Slow_Down == 10) Key_Slow_Down = 0;//鍵盤減速專用
        if(++Seg_Slow_Down == 100) Seg_Slow_Down = 0;//數碼管減速專用
        if(++Seg_Pos == 8) Seg_Pos = 0;//數碼管顯示專用
        if(++Reg_Key_10ms >= 10)
        {
                Reg_Key_10ms = 0;
                Bit_10ms = 1;
        }
        Seg_Disp(Seg_Pos,Seg_Buf[Seg_Pos],Seg_Point[Seg_Pos]);
        Led_Disp(Seg_Pos,ucLed[Seg_Pos]);
}

/* Main */
void main()
{
        System_Init();
        Timer0Init();
        
        while (1)
        {
                Key_Proc();
                Seg_Proc();
               
        }
}

評分

參與人數 2黑幣 +55 收起 理由
STC莊偉 + 5 很給力!
admin + 50 共享資料的黑幣獎勵!

查看全部評分

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

使用道具 舉報

沙發
ID:143767 發表于 2024-11-21 11:07 | 只看該作者
真的很好,好好學習一下,感謝樓主奉獻
回復

使用道具 舉報

板凳
ID:143767 發表于 2024-11-21 11:18 | 只看該作者
請問樓主,四個led接在單片機的哪個端口上了,謝謝
回復

使用道具 舉報

地板
ID:229502 發表于 2024-11-21 13:32 | 只看該作者
按鍵代碼處理,值得參考
回復

使用道具 舉報

5#
ID:143767 發表于 2024-11-21 16:25 | 只看該作者
請問樓主,四個led接在單片機的哪個端口上了,P00-P07還是其他的IO口,謝謝
回復

使用道具 舉報

6#
ID:1123636 發表于 2024-11-21 17:50 | 只看該作者
dj3365191 發表于 2024-11-21 11:18
請問樓主,四個led接在單片機的哪個端口上了,謝謝

任意IO就行,這個Led只是觸發事件
回復

使用道具 舉報

7#
ID:1143011 發表于 2025-1-28 10:47 | 只看該作者

真的很好,好好學習一下,感謝樓主奉獻
回復

使用道具 舉報

8#
ID:595237 發表于 2025-2-2 20:19 | 只看該作者
dj3365191 發表于 2024-11-21 16:25
請問樓主,四個led接在單片機的哪個端口上了,P00-P07還是其他的IO口,謝謝

#include <Led.h>//Led底層驅動專用頭文件-------四個led接在這個led.h的端口上了-
#include <Key.h>//按鍵底層驅動專用頭文件
#include <Seg.h>//數碼管底層驅動專用頭文件

缺少Led,按鍵,數碼管
回復

使用道具 舉報

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

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 亚洲 中文 欧美 日韩 在线观看 | 欧美xxxx日本 | 久久久久一区二区三区 | 91精品国产91久久综合桃花 | 国产成人一区二区 | 老头搡老女人毛片视频在线看 | 国产98色在线 | 日韩 | 久久美女网 | 午夜激情一区 | 91精品国产自产在线老师啪 | avhd101在线成人播放 | 夜夜骑首页 | 国产盗摄视频 | www.久久99| 美日韩免费 | 日本高清在线一区 | 国产乱码久久久久久一区二区 | 欧美精品在线一区 | 午夜欧美 | 久久99视频精品 | 国产精品成人一区二区三区 | av综合站 | 欧美精品一区二区三区一线天视频 | 中文字幕免费视频 | 免费国产一区 | 久久99蜜桃综合影院免费观看 | 五月婷婷激情 | 欧美日韩一区二区三区四区 | 日韩一级黄色毛片 | 久久五月婷 | 日韩欧美在线视频 | 国内久久 | 高清色| 国产成人精品一区二区三区在线观看 | av在线播放国产 | 极品销魂美女一区二区 | 亚洲精品大片 | 成人一区二区三区在线观看 | 亚洲综合精品 | 91在线资源 | 99精品视频一区二区三区 |