找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4461|回復(fù): 15
收起左側(cè)

請教關(guān)于MCU單個(gè)按鍵實(shí)現(xiàn)不同次數(shù)的點(diǎn)擊對應(yīng)不同功能的處理思想

[復(fù)制鏈接]
ID:258164 發(fā)表于 2018-11-29 10:37 | 顯示全部樓層 |閱讀模式
現(xiàn)在我有一個(gè)按鍵(通過MCU IO口判斷電平的),有長按和短按兩種方式,現(xiàn)在長短按功能實(shí)現(xiàn)了,但是現(xiàn)在我遇到一個(gè)新的問題:我這個(gè)按鍵可能需要按1次到多次,然后不同的次數(shù)對應(yīng)不同的功能。因?yàn)槲椰F(xiàn)在的短按時(shí)間設(shè)定的是50ms-2s,在多次檢查按鍵連續(xù)短按的時(shí)候,請問我該怎么處理,才能保證我可以識別具體按鍵的次數(shù)呢?

具體的實(shí)例可以參考現(xiàn)實(shí)生活中的電磁爐,菜單鍵按一次到多次,切換到不同的功能。

希望做過類似功能邏輯的壇友提供點(diǎn)思路,謝謝!
回復(fù)

使用道具 舉報(bào)

ID:94031 發(fā)表于 2018-11-29 11:34 | 顯示全部樓層
設(shè)一個(gè)變量存放在一定時(shí)間內(nèi)點(diǎn)擊次數(shù),根據(jù)這個(gè)變量決定程序走向。
回復(fù)

使用道具 舉報(bào)

ID:410399 發(fā)表于 2018-11-29 14:20 | 顯示全部樓層
設(shè)置一個(gè)標(biāo)志號,長按一次加一,標(biāo)志=1對應(yīng)一個(gè)功能,=2對應(yīng)一個(gè)功能等等,再設(shè)置另外一個(gè)標(biāo)志,短按一次加一,同理
回復(fù)

使用道具 舉報(bào)

ID:435739 發(fā)表于 2018-11-29 14:48 | 顯示全部樓層
設(shè)定每次按鍵間隔時(shí)間,統(tǒng)計(jì)按鍵的次數(shù),超時(shí)后重新計(jì)數(shù)
回復(fù)

使用道具 舉報(bào)

ID:424598 發(fā)表于 2018-11-29 15:24 來自手機(jī) | 顯示全部樓層
如需要實(shí)現(xiàn)一個(gè)按鍵5種功能,那就初始變量為0,按一次就+1,然后判斷變量的值是多少就執(zhí)行指定的程序。當(dāng)累加超過5時(shí),將變量重置為0
回復(fù)

使用道具 舉報(bào)

ID:435828 發(fā)表于 2018-11-29 16:06 | 顯示全部樓層
呃  如需要實(shí)現(xiàn)一個(gè)按鍵5種功能,那就初始變量為0,按一次就+1,然后判斷變量的值是多少就執(zhí)行指定的程序。當(dāng)累加超過5時(shí),將變量重置為0
回復(fù)

使用道具 舉報(bào)

ID:435826 發(fā)表于 2018-11-29 16:29 | 顯示全部樓層
短按只需設(shè)置防抖時(shí)間,程序要做成識別下降沿及上升沿,一個(gè)下降沿+一個(gè)上升沿為一個(gè)按鍵事件的觸發(fā),需不需要設(shè)置全局變量記錄觸發(fā)的次數(shù),看你的目的需求是以按下次數(shù)表示功能的切換,還是按一次功能響應(yīng)切換一次,個(gè)人建議后者
回復(fù)

使用道具 舉報(bào)

ID:258164 發(fā)表于 2018-11-29 16:33 | 顯示全部樓層
xuyaqi 發(fā)表于 2018-11-29 11:34
設(shè)一個(gè)變量存放在一定時(shí)間內(nèi)點(diǎn)擊次數(shù),根據(jù)這個(gè)變量決定程序走向。

我的問題不在這,我想問的是:我怎么保證我的第一次短按和第二次 第三次 ...第n次都檢測到,因?yàn)槲业某绦蜻有別的很多功能。
回復(fù)

使用道具 舉報(bào)

ID:258164 發(fā)表于 2018-11-29 16:34 | 顯示全部樓層
ssk7793 發(fā)表于 2018-11-29 15:24
如需要實(shí)現(xiàn)一個(gè)按鍵5種功能,那就初始變量為0,按一次就+1,然后判斷變量的值是多少就執(zhí)行指定的程序。當(dāng)累 ...

這個(gè)我知道,但是我的問題不是這個(gè)。請看看我對一樓的回復(fù),我的問題所在
回復(fù)

使用道具 舉報(bào)

ID:213173 發(fā)表于 2018-11-29 20:48 | 顯示全部樓層
給你寫一個(gè)單鍵長短按實(shí)現(xiàn)多任務(wù)的示例程序

#include <REG51.H>
#define uint unsigned int                         //宏定義數(shù)據(jù)類型uint
#define uchar unsigned char                 //宏定義數(shù)據(jù)類型uchar
#define key_S 10                                                //宏定義短按(10ms)
#define key_L key_S*100                                //宏定義長按(1s)

sbit key1=P3^7;
//sbit key2=P3^6;
sbit LED1=P1^0;
sbit LED2=P1^2;
sbit LED3=P1^4;
sbit LED4=P1^6;
uchar KeySec=0;
uchar num=0;
void Timer0Init()//1毫秒@12.000MHz
{
        TMOD= 0x01;                //設(shè)置定時(shí)器模式
        TL0 = 0x18;                //設(shè)置定時(shí)初值
        TH0 = 0xFC;                //設(shè)置定時(shí)初值
        TF0 = 0;                        //清除TF0標(biāo)志
        TR0 = 1;                        //定時(shí)器0開始計(jì)時(shí)
        EA=1;                                //開總中斷
        ET0=1;                        //開定時(shí)器0中斷
}

void keyscan()                                                        //按鍵掃描
{
        static uint count1=0;                        //計(jì)數(shù)變量
//        static uint count2=0;                        //計(jì)數(shù)變量
        if(!key1)   
        {  
                count1++;  
                if(count1==key_L)                                //長按
                        KeySec=4;                                        //輸出鍵值4
                if(count1>key_L)                                //防止count溢出
                        count1=key_L+1;          
        }  
        else                                                                        //按鍵抬起
        {  
                if(count1>key_S && count1<key_L)//短按
                {                       
                        num++;
                        if(num==4)
                                num=1;
                        KeySec=num;                                        //輸出鍵值num
                }       
                count1=0;                                        //count清0
        }   
/*        if(!key2)   
        {  
                count2++;  
                if(count2==key_L)                                //長按
                        KeySec=4;                                        //輸出鍵值4
                if(count2>key_L)                                //防止count溢出
                        count2=key_L+1;          
        }  
        else                                                                        //按鍵抬起
        {  
                if(count2>key_S && count2<key_L)//短按
                        KeySec=3;                                        //輸出鍵值3
                        count2=0;                                        //count清0
        }*/   
}

void key_service()                                        //按鍵服務(wù)程序
{
        switch(KeySec)                                                //按鍵服務(wù)狀態(tài)切換
        {
                case 1:LED1=~LED1;KeySec=0;break;
                case 2:LED2=~LED2;KeySec=0;break;
                case 3:LED3=~LED3;KeySec=0;break;
                case 4:LED4=~LED4;KeySec=0;break;
                default: break;
        }
}

void main()
{
        Timer0Init();                //初始化定時(shí)器
        while(1)
        {
                key_service();        //按鍵服務(wù)程序
        }
}
void timer0() interrupt        1//1毫秒@12.000MHz
{
        TL0 = 0x18;                //設(shè)置定時(shí)重裝值
        TH0 = 0xFC;                //設(shè)置定時(shí)重裝值
        keyscan();                //按鍵掃描程序
}
回復(fù)

使用道具 舉報(bào)

ID:424598 發(fā)表于 2018-11-30 07:48 來自手機(jī) | 顯示全部樓層
HelloPan111 發(fā)表于 2018-11-29 16:34
這個(gè)我知道,但是我的問題不是這個(gè)。請看看我對一樓的回復(fù),我的問題所在

還是看你變量的應(yīng)用和判斷的寫法,如果要區(qū)分長按和短按的累計(jì),那就分成二個(gè)變量,分別在長按和短按的判斷中進(jìn)行累計(jì)
回復(fù)

使用道具 舉報(bào)

ID:258164 發(fā)表于 2018-11-30 09:31 | 顯示全部樓層
wulin 發(fā)表于 2018-11-29 20:48
給你寫一個(gè)單鍵長短按實(shí)現(xiàn)多任務(wù)的示例程序

#include

謝謝,我的長短按程序已經(jīng)實(shí)現(xiàn)了。之前的問題是怎么處理兩次短按的間隔問題,不過我自己想到了解決的辦法,還是謝謝你的回復(fù)
回復(fù)

使用道具 舉報(bào)

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

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表