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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2053|回復: 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 共享資料的黑幣獎勵!

查看全部評分

回復

使用道具 舉報

ID:143767 發表于 2024-11-21 11:07 | 顯示全部樓層
真的很好,好好學習一下,感謝樓主奉獻
回復

使用道具 舉報

ID:143767 發表于 2024-11-21 11:18 | 顯示全部樓層
請問樓主,四個led接在單片機的哪個端口上了,謝謝
回復

使用道具 舉報

ID:229502 發表于 2024-11-21 13:32 | 顯示全部樓層
按鍵代碼處理,值得參考
回復

使用道具 舉報

ID:143767 發表于 2024-11-21 16:25 | 顯示全部樓層
請問樓主,四個led接在單片機的哪個端口上了,P00-P07還是其他的IO口,謝謝
回復

使用道具 舉報

ID:1123636 發表于 2024-11-21 17:50 | 顯示全部樓層
dj3365191 發表于 2024-11-21 11:18
請問樓主,四個led接在單片機的哪個端口上了,謝謝

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

使用道具 舉報

ID:1143011 發表于 2025-1-28 10:47 | 顯示全部樓層

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

使用道具 舉報

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 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产精品成人一区二区 | 黄色在线 | 亚洲国产成人在线 | 亚洲网址| 国产精品久久福利 | 欧美激情欧美激情在线五月 | 国产乱码精品一区二区三区中文 | 国产乱码精品一区二区三区五月婷 | 免费成人高清在线视频 | 国产欧美二区 | 免费看黄视频网站 | 国产成人精品免费视频大全最热 | 91www在线观看 | 北条麻妃一区二区三区在线视频 | 日本亚洲精品成人欧美一区 | 在线精品一区二区三区 | 久久久精品网站 | 成人免费视频网站在线观看 | 精品一级| 亚洲国产精品精华素 | 精品一区二区三区91 | 国产日韩欧美在线观看 | 一级午夜aaa免费看三区 | 一级a爱片性色毛片免费 | 午夜丰满寂寞少妇精品 | 毛片网站免费观看 | 久久精品国产99国产 | 欧美性网站| 精品一区二区三区在线观看国产 | 久久电影一区 | 拍拍无遮挡人做人爱视频免费观看 | 日日夜夜精品视频 | 免费一级大片 | 天天影视综合 | 国产精品一区二区三区在线 | 久久精品综合 | 欧美日韩在线观看视频 | 精品国产一区二区三区免费 | 精品一区国产 | 久久在线免费 | 精品九九 |