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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3128|回復(fù): 1
打印 上一主題 下一主題
收起左側(cè)

進一步完善的可在任何系統(tǒng)上移植的按鍵操作系統(tǒng),包含單擊、雙擊、多擊、N擊、長按...

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:391730 發(fā)表于 2019-12-17 16:41 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
這個系統(tǒng)可以近似的看成是按鍵并發(fā)操作,單擊、雙擊等一系列的動作都已經(jīng)定義過。以下是頭文件:

#define BaseTime 10   //時基,由單片機時鐘中斷精準產(chǎn)生
#define number_init          0xfffffffd  //對任何時間變量需要初始化的地方預(yù)設(shè)的初始化值


typedef  unsigned char         uchar  ;
typedef  unsigned int         uint         ;
typedef  unsigned long   ulong         ;
typedef  unsigned long   utime  ;


enum ButtonModel{noneClick=0,singalClick,doubleClick,repeatClick,longPress};
enum ButtonStaus{nonePress=1,pressDown,pressUp,pressDownHold};       


struct button
{
    uchar outPutEn:1;       //發(fā)送數(shù)據(jù)使能
    uchar lastButton:1;     //緩存按鍵上次變動后的狀態(tài)
    uchar init_leavel:1;    //設(shè)置默認按鍵電平
        uchar longPressFlag:1;        //長按釋放標志 默認0,一旦開始長按則置1
        uchar Gpio_level :3;     //讀取IO口電平
        uchar applyUseOpenAPI:1;         //在關(guān)機狀態(tài)下,若本按鍵按下啟動了系統(tǒng),則需要申請全局變量標明,禁止其他按鍵關(guān)閉被本按鍵打開的系統(tǒng)(自己打開自己負責(zé)關(guān)閉)

        uchar ticks;            //按鍵按下次數(shù)
    enum ButtonStaus lastButtonStaus;   //緩存按鍵上個循環(huán)的狀態(tài)
    enum ButtonStaus thisButtonStaus;   //緩存按鍵本循環(huán)的狀態(tài)
    enum ButtonModel lastButtonModel; //緩存按鍵上個循環(huán)所處的模式
    enum ButtonModel thisButtonModel; //緩存按鍵本循環(huán)應(yīng)該所處的模式

    uint changeModelTime;  //10ms基準 多擊時間定義
    uint pressLongTime;    //10ms基準 長按時間定義

    utime lastPressDownMoment;     //上次按鍵按下所處的時刻
    utime thisPressDownMoment;     //本次按鍵按下所處的時刻
    uint tempTime;                //緩存按鍵兩次按下之間的時長

    utime buttonConfir;     //按鍵防抖時長


    utime getTimer; //獲取時鐘精準時刻,用于設(shè)定按鍵掃描周期
    utime acquisitionMoment; //獲取時鐘精準時刻,用于記錄相同按鍵狀態(tài)持續(xù)時長

    uchar  (*read_gpio)(void); //獲取按鍵狀態(tài)方法
};

void Button_init(struct button *Key,uchar(*get_leavel)(),bit init_button_leavel,uint LongPressTimes,uint changeModelTime);  //按鍵初始化
void Scan_key(struct button *Key,utime timer ,uint enOutTime ,uint noiseProofTime);  //按鍵掃描函數(shù)

以下是DEMO:
#include"button.h"

struct button button1,button2;

uchar keyCounter=0;
uint Pwm=0;
utime COLCK=0;

inline uchar Get_gpio_level1(void)//獲取開關(guān)的電平,特別注意:如果一個IO口下有三四十個按鈕,用ADC掃描不同的電壓值來判斷是哪個按鈕動作時,要注意程序嵌套層數(shù),層數(shù)太多會有棧溢出的問題,暫時無解
{
    return P10;   //P10是單片機接開關(guān)的IO口
}
inline uchar Get_gpio_level2(void)
{
    return P11;   //P11是單片機接開關(guān)的IO口
}
uchar Pwm_excute(uchar pwmDuty); //pwm示例程序,不填充
void Get_button_model(struct button* ); //對掃描到的單擊,雙擊,長按動作響應(yīng)

main()
{
    Button_init(&button1,Get_gpio_level1,1,300,100);// 默認開關(guān)不動作時是高電平,定義長按時長為300個10ms,定義多擊時長為100個10ms
    Button_init(&button2,Get_gpio_level2,1,300,100);

    /*記得開COLCK所在的中斷!這個時間中斷程序就不填充了*/
    while(1)
    {
        Scan_key(&button1,COLCK,50,20); //定義50ms 掃描一次,定義按鍵防抖時間20ms
        Scan_key(&button2,COLCK,50,20);
        Get_button_model(&button1); //對按鍵動作響應(yīng)
        Get_button_model(&button2);
    }
}

void Get_button_model(struct button* Key  )
/*注意啦!多按鍵會存在資源競爭的風(fēng)險,比如按鍵1打開了某個操作只能由按鍵1關(guān)閉,
如果不仔細設(shè)計會存在按鍵2執(zhí)行某個動作時關(guān)閉掉按鍵1打開的操作,遇到這個問題記得applyUseOpenAPI這個玩意來申請權(quán)限,然后用全局變量標識這個操作已經(jīng)被占用,
目前在本DEMO例程中沒有用到這么復(fù)雜的設(shè)計
*/
{
    if(Key->outPutEn)
    {
        switch(Key->thisButtonModel)
        {
            switch noneClick:
                {
                    /*
                    最精華的部分,在按鍵無動作的時候該處理那些數(shù)據(jù),

                    */
                    break;
                }
            switch singalClick:
                {
                    Pwm++;
                    if(Pwm>255)
                        Pwm=255;
                    Pwm_excute(Pwm); //這個函數(shù)沒有填充,每個單片機的PWM定義不一樣,甚至不是PWM的動作,單擊執(zhí)行什么動作,自己發(fā)揮
                    break;
                }
            switch doubleClick:
                {
                   /*

                   */

                   break;
                }
            switch repeatClick:
                {

                    /*

                    */
                    break;
                }
            switch longPress:
                {

                    /*

                    */
                    break;
                }

        }

        Key->outPutEn=0;  //單片機運行的速度太快,但是按鍵掃描又設(shè)置的固定多長時間掃描一次,為了解決矛盾,才有的這么個參數(shù)
    }
}

EXN interrupt N  //定時器中斷
{
    /*
    */
    COLCK++; //每10ms加1
}




PS:公司的項目非常復(fù)雜,用的是多按鍵并發(fā),等過段時間我整一張原理圖上來。當然,公司項目的源程序有5千行,處于保密需求是不可能上傳的。

按鍵驅(qū)動.zip

5.07 KB, 下載次數(shù): 34, 下載積分: 黑幣 -5

程序

評分

參與人數(shù) 1黑幣 +100 收起 理由
admin + 100 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏6 分享淘帖 頂 踩
回復(fù)

使用道具 舉報

沙發(fā)
ID:391730 發(fā)表于 2019-12-17 16:46 | 只看該作者
Get_button_model函數(shù)中的SWITCH 下面一系列的SWITCH應(yīng)該是CASE。沒處理,自己發(fā)揮。
回復(fù)

使用道具 舉報

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

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 一区二区福利视频 | 久草黄色 | 性视频在线 | 亚洲免费精品 | 亚洲色在线视频 | 国产激情一区二区三区 | 91av在线看 | 亚洲激情视频 | 国产理论在线观看 | 久精品视频 | 欧美不卡 | 成人a毛片| 日韩有码av | 欧美色综合天天久久综合精品 | 午夜在线观看视频网站 | 91激情视频 | 一级国产片 | 日日操日日射 | 色一情一乱一乱一区91av | 在线播放av网站 | 国产精品成人国产乱一区 | 国产精自产拍久久久久久蜜 | www超碰| 国产suv一区二区 | a视频在线免费观看 | 成人网在线 | 男男成人高潮片免费网站 | 麻豆视频一区二区 | 久久久久久久久国产 | 91成人免费版| 嫩草视频在线观看 | 91禁蘑菇在线看 | 欧美激情视频在线 | 日本黄页视频 | 精品国产乱码一区二区三 | 老女人性生活视频 | 欧美xxx视频| 香蕉视频国产 | 久久精品伊人 | 国产成人在线免费视频 | 欧美在线观看一区 |