按鍵長按短按


長按是在短按的基礎上,以一個很短的時間(10ms)再次判斷按鍵是否片於按下狀態,當達到一定的時間(1s)后,按鍵還處於按下狀態,說明是長按狀態,結合上一節的短按,下面實現一個從0-99的累加,短按時一次加1,長按后,進入快速累加的過程,同時使用了定時器來定時刷新數碼管,在Display的處理上就和之前的不同,原來在Display里通過循環刷新每個數碼管的顯示,現在放到了定時器定時觸發的事件里,設置定時時間為2ms,這2ms只負責刷新共陰極的8位數碼的一位,所以需要在定時事件里處理每次刷新不同位置的數碼管。

#include <reg52.h>

sbit KeyAdd = P0^0;
sbit LED = P0^1;
sbit LATCH1=P2^2;//段鎖存
sbit LATCH2=P2^3;//位鎖存

unsigned char code DuanMa[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};// 顯示段碼值0~9
unsigned char code WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//位碼
unsigned char TempData[8]; //存儲顯示值
unsigned char vT = 0;

void Delay(unsigned int t);
void Display(unsigned char Index);
void InitTime0(void);

void main(void)
{
    unsigned char numadd = 0;  // 累加的結果
    unsigned int vExtend = 0;  // 用於判斷是否滿足長按標准
    LED = 0;
    TempData[0] = DuanMa[0];  
    TempData[1] = DuanMa[0];
    InitTime0();
    while (1)
    {
        if (!KeyAdd)       // 發現按下
        {
            Delay(1500);   // 延時去抖
            if (!KeyAdd)   // 如果還處於按下
            {
                while (!KeyAdd)     //等待彈起
                {
                    Delay(100);     // 延時,這里要短一點,vExtend長些,這樣有利於精確的判斷是否放開
                    vExtend++;     // 長按計數
                    if (vExtend == 1000)   // 按下時間大約1s認為長按
                    {
                        vExtend = 0;      //清空計數初值
                        while(!KeyAdd)      // 如果按鍵還處於按下狀態,則快速增加
                        {
                            if (numadd == 99)
                                numadd = 0;
                            else
                                numadd++;
                            TempData[0] = DuanMa[numadd / 10];  
                            TempData[1] = DuanMa[numadd % 10];
                            Delay(10000); //延時讓數字顯示一段時間,否則數字不動直到放開按鈕后突然跳變
                        }    
                    }
                }
                vExtend = 0;   //設置初值,為下一次長按做准備
                if (numadd == 99)
                    numadd = 0;
                else
                    numadd++;
                TempData[0] = DuanMa[numadd / 10];  
                TempData[1] = DuanMa[numadd % 10];
            }
        }
    }
}

void Delay(unsigned int t)
{
    while (--t);
}

void Display(unsigned char Index)
{      
    P1 = 0;   //清空數據,防止有交替重影
    LATCH1 = 1;     //段鎖存
    LATCH1 = 0;

    P1 = WeiMa[Index]; //取位碼 
    LATCH2=1;     //位鎖存
    LATCH2=0;

    P1 = TempData[Index]; //取顯示數據,段碼
    LATCH1=1;     //段鎖存
    LATCH1=0;
}

void InitTime0(void)
{
    TMOD = 0x01;
    TH0 = 0xF8;    // 計數初值F830H = 2000 (65536-63536=2000 * 1us = 2ms)
    TL0 = 0x30;
    ET0 = 1;       // EA即IE^1 等於1時申請中斷定時器0中斷打開
    EA = 1;           // 總中斷打開
    TR0 = 1;       // 啟動定時器0
}

void MyInterrept(void) interrupt 1
{
    LED = !LED;
    TH0 = 0xF8;          //重新賦值 2ms
    TL0 = 0x30;
     Display(vT);
    vT++;
    if (vT == 8)
      vT = 0;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM