找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

關(guān)于單片機獨立按鍵程序分析 純屬新手分析的理論不知道對不對歡迎指正批評

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:232366 發(fā)表于 2021-1-24 20:21 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
首先非常感謝前面通過請教論壇師傅關(guān)于獨立按鍵按下后等待松開例程的原理,后自己又繼續(xù)研究其程序原理并且舉一反三
根據(jù)前面的原理自己又在鼓搗敲了個程序并且配合軟件調(diào)試單步運行似乎也可行。下面上程序:
       static uchar   loo_go=1;//按鍵松開檢測變量
       static uchar  KEY_NUM=0;//鍵值變量
        void key_scan()
        {
                if(k1!= loo_go)
                {
                        if loo_go==0)
                        {
                                KYE_NUM1=1;        
                        }
                         loo_go=k1;        
                }
        }

下面為本人分析此程序過程:
1:當(dāng)按按鍵沒有按下時第一個if(k1!= loo_go)不成立所以不執(zhí)行后面語句直接跳出并且把看k1原本的值賦值給按鍵松開檢測變量《這個值沒有發(fā)生改變
則認(rèn)為按鍵沒有按下》 loo_go=k1;
2:當(dāng)按鍵第一次被按下時第一個if(k1!= loo_go)條件成立k1此時不等于1《因為按鍵被按下為0姑且k1不是1而是0而成立》后執(zhí)行它后面語句
繼續(xù)判斷第二個條件if (loo_go==0)此時按鍵松開檢測變量loo_go值不等于0《上面定義時默認(rèn)為1》而不執(zhí)行它后面語句直接跳出到loo_go=k1;此時
把k1的值賦值給按鍵松開檢測變量loo_go《這里的時因為是按鍵被按下k1為0所以按鍵松開檢測變量loo_go也為0》后退出按鍵掃描函數(shù)
3:在這里《假設(shè)按鍵第一次被按下后沒有松開的話當(dāng)主循環(huán)再次進入到按鍵掃描函數(shù)后》
4:再開始判斷第一個if(k1!= loo_go)條件此時判斷條件已經(jīng)改變而是要判斷按鍵不等于0時條件成立《此時因為上一次的按鍵按下后將 loo_go賦值為0所以判斷條件被改變》如果按鍵還不松開又直接跳出到loo_go=k1;此時
把k1的值賦值給按鍵松開檢測變量loo_go《這里的時因為是按鍵被按下k1為0所以按鍵松開檢測變量loo_go也為0》后退出按鍵掃描函數(shù)
5:《假設(shè)按鍵松開當(dāng)主循環(huán)再次進入到按鍵掃描函數(shù)》
6:再進入掃描函數(shù)開始判第一個if(k1!= loo_go)條件此時判斷條件已經(jīng)改變而是要判斷按鍵不等于0時條件成立
此時因為按鍵被松條件成立《因為一松開就等于1所以不等于0》后繼續(xù)執(zhí)行后面語句進入到第二個條件if loo_go==0)此時條件時成立的《因為第一次按下時此 loo_go賦值為0并且保存所以條件成立》繼續(xù)執(zhí)行下面語句將KYE_NUM1=1;鍵值變量賦值為1,《再出來把k1賦值給按鍵松開檢測變量loo_go因為按鍵已經(jīng)松開k1為1此時loo_go也等于1》完成按鍵按下后和抬起的整個過程。
7:根據(jù)上述分析過程可認(rèn)為按鍵按下并沒有給KYE_NUM1=1;鍵值變量賦值為1;而是按鍵抬起后才給賦完成了按鍵按下檢測和抬起檢測而且。
如有不對的地方歡迎各位論壇老師指證批評。。。。。。。。。。。。。。。。。!
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復(fù)

使用道具 舉報

沙發(fā)
ID:390416 發(fā)表于 2021-1-24 21:50 | 只看該作者
51單片機獨立鍵盤的短按+長按 http://www.torrancerestoration.com/bbs/dpj-201806-1.html
回復(fù)

使用道具 舉報

板凳
ID:213173 發(fā)表于 2021-1-25 09:04 | 只看該作者
樓主的探索精神可嘉。這個程序從邏輯上看沒有問題,但用于實際電路就會發(fā)現(xiàn)響應(yīng)慢和容易出錯。
1.因為鍵按下loo_go只記憶了操作行為,必須等按鍵松手后才能響應(yīng)按鍵功能。
2.常用的按鍵等機械開關(guān),在翻轉(zhuǎn)瞬間觸點是抖動不穩(wěn)定的,會產(chǎn)生噪波,持續(xù)時間幾ms。為此需要外部硬件濾波或軟件消抖。所以此函數(shù)還要進一步完善。
但軟件消抖并不是在任何使用環(huán)境都必須的。如果按鍵掃描函數(shù)放在循環(huán)周期大于10ms的主函數(shù)或中斷函數(shù)中運行就不必消抖。給你一個獨立按鍵示例,非常簡單?炊院罂梢院芊奖愕臄U展成多按鍵,組合鍵,長短按鍵。
  1. #include<reg51.h>

  2. sbit key=P3^0;
  3. sbit LED=P1^0;

  4. unsigned char Temp;
  5. unsigned char Record;

  6. void key_scan()
  7. {
  8.         unsigned char ReadData = key ^ 0x01;
  9.         Temp = ReadData & (ReadData ^ Record);
  10.         if(Temp)LED=~LED;
  11.         Record = ReadData;
  12. }

  13. void main()
  14. {
  15.         while(1)
  16.         {
  17.                 key_scan();
  18.                 //延時10ms
  19.         }
  20. }
復(fù)制代碼

回復(fù)

使用道具 舉報

地板
ID:592807 發(fā)表于 2021-1-25 09:19 | 只看該作者
       static uchar   loo_go=1;//按鍵松開檢測變量
       static uchar  KEY_NUM=0;//鍵值變量
        void key_scan()
        {
                if(k1!= loo_go)
                {
                        if (loo_go==0)(這里缺個括號,給你補上)
                        {
                                KYE_NUM1=1;        
                        }
                         loo_go=k1;        
                }
        }if (loo_go==0)表示loo_go代表按下按鍵。
loo_go的定義是static uchar   loo_go=1;
也就是說開機后loo_go = 1;

k1 !=  1,表示按下按鍵那進入if(k1!= loo_go)判斷后
if (loo_go==0)這個判斷你仍然無法進入,而是直接執(zhí)行下一條代碼loo_go=k1 ;

如此時不松開按鍵的話if(k1!= loo_go)這條判斷你也無法被再次觸發(fā)
因為此時loo_go=k1 = 0;
松開按鍵后if(k1!= loo_go)再次被觸發(fā)if (loo_go==0)也被觸發(fā),完成KYE_NUM1=1 賦值。


這個如果非要說什么缺點就是必須要等按鍵松開才能觸發(fā)相應(yīng)的功能,以及必須進入兩次以上按鍵掃描代碼才能完成賦值
還有就是有些按鍵按下后它的電平變化不是穩(wěn)定的gnd或者vcc而是波浪形的,最好幾個延時防止誤觸發(fā)

回復(fù)

使用道具 舉報

5#
ID:871393 發(fā)表于 2021-1-25 12:48 | 只看該作者
我個人不建議把讀取按鍵狀態(tài)的函數(shù)宏定義成k1這種像變量名一樣的形式,
會讓人誤解k1是個變量, 好像由賦值語句獲取的,
這樣就會誤認(rèn)為每次使用k1需要先k1=read(pin)賦一個新值,
而實際上卻是#define k1 read(pin), 很容易誤會,


我一般寫成#define read_k1() read(pin),
用的時候也是if(read_k1() == 0){}
讓讀者明白這句話是個函數(shù)過程, 而不是變量
回復(fù)

使用道具 舉報

6#
ID:232366 發(fā)表于 2021-1-26 14:57 | 只看該作者
77599585 發(fā)表于 2021-1-25 12:48
我個人不建議把讀取按鍵狀態(tài)的函數(shù)宏定義成k1這種像變量名一樣的形式,
會讓人誤解k1是個變量, 好像由賦值 ...

感謝糾正
回復(fù)

使用道具 舉報

7#
ID:232366 發(fā)表于 2021-1-26 15:02 | 只看該作者
黃youhui 發(fā)表于 2021-1-25 09:19
static uchar   loo_go=1;//按鍵松開檢測變量
       static uchar  KEY_NUM=0;//鍵值變量
       ...

感謝回復(fù)糾正后續(xù)會多加學(xué)習(xí)
回復(fù)

使用道具 舉報

8#
ID:232366 發(fā)表于 2021-1-26 15:06 | 只看該作者
wulin 發(fā)表于 2021-1-25 09:04
樓主的探索精神可嘉。這個程序從邏輯上看沒有問題,但用于實際電路就會發(fā)現(xiàn)響應(yīng)慢和容易出錯。
1.因為鍵按 ...

非常感謝指正和耐心回復(fù) 和糾正!回復(fù)慢了一點因為前面帖子突然找不到的被不知道移哪去了
回復(fù)

使用道具 舉報

9#
ID:702386 發(fā)表于 2021-1-26 17:22 | 只看該作者
wulin 發(fā)表于 2021-1-25 09:04
樓主的探索精神可嘉。這個程序從邏輯上看沒有問題,但用于實際電路就會發(fā)現(xiàn)響應(yīng)慢和容易出錯。
1.因為鍵按 ...

感謝分享。這種方法真的簡潔又好用。Record相當(dāng)于記錄按鍵的狀態(tài),按下后直到松開的整個區(qū)間都是1。Temp相當(dāng)于一個trigger,只在按下后的第一次掃描時是1,確保一次按鍵周期內(nèi)只執(zhí)行一次動作。
回復(fù)

使用道具 舉報

10#
ID:412460 發(fā)表于 2021-1-27 12:18 | 只看該作者
  • static uchar  loo_go =1;    //按鍵狀態(tài)保存  
  • static uchar  key_value =0;  
  • static uchar  cnt = 0;      //去抖動  
  • void key_scan()  
  • {  
  •     uchar val_temp = 0;  
  •     val_temp = k1;              //使用臨時變量先保存IO狀態(tài),因為IO是隨時可變的,不可控吧!  
  •                                 //例如:loo_go = val_temp;  之前的語句執(zhí)行的過程中,IO剛好變了會有什么后果?   
  •     if(val_temp != loo_go)  
  •     {  
  •         if(++cnt >= 4)   //假如8ms掃描一次按鍵 32ms防抖時間很好,這是個經(jīng)驗值吧  
  •         {  
  •             cnt = 0;  
  •             if(0 == loo_go)  
  •             {  
  •                 key_value = 1;   //松開鍵值  
  •             }  
  •             else  
  •             {  
  •                 key_value = 2;   //按下鍵值  
  •             }  
  •             loo_go = val_temp;  
  •         }  
  •     }  
  •     else  
  •     {  
  •         cnt = 0;  
  •     }  
  • }  

評分

參與人數(shù) 1黑幣 +20 收起 理由
admin + 20 回帖助人的獎勵!

查看全部評分

回復(fù)

使用道具 舉報

11#
ID:332444 發(fā)表于 2021-1-28 12:44 | 只看該作者
那么喜歡分析真好學(xué),丟一個給你玩玩: void main()         //主函數(shù) {   unsigned char aa=0,xd=0;         unsigned int i=0;         bit k=0; //        zdsz();         while(1)         {                 if(!k&&++xd==0&&k1==0)k=1;                 if(k&&++xd==0&&k2==0)k=0;                 if(k&&++i==0)                         QuDong595(aa++);         } }
回復(fù)

使用道具 舉報

12#
ID:332444 發(fā)表于 2021-1-28 12:48 | 只看該作者

回復(fù)

使用道具 舉報

13#
ID:232366 發(fā)表于 2021-1-28 14:06 來自手機 | 只看該作者
DKC_LIN_123 發(fā)表于 2021-1-27 12:18
  • static uchar  loo_go =1;    //按鍵狀態(tài)保存  
  • static uchar  key_value =0;  [/bac ...

  • 感謝回復(fù)和建議
    回復(fù)

    使用道具 舉報

    14#
    ID:232366 發(fā)表于 2021-1-28 14:08 來自手機 | 只看該作者
    xianfajushi 發(fā)表于 2021-1-28 12:44
    那么喜歡分析真好學(xué),丟一個給你玩玩: void main()         //主函數(shù) {   unsigned char aa=0,xd=0;         unsign ...

    感謝回復(fù)  和建議!
    回復(fù)

    使用道具 舉報

    15#
    ID:332444 發(fā)表于 2021-1-28 15:32 | 只看該作者
    因為今天剛好回復(fù)有關(guān)2個按鍵問題,本案例不待按鍵釋放.
    回復(fù)

    使用道具 舉報

    16#
    ID:232366 發(fā)表于 2021-1-28 18:15 來自手機 | 只看該作者
    xianfajushi 發(fā)表于 2021-1-28 15:32
    因為今天剛好回復(fù)有關(guān)2個按鍵問題,本案例不待按鍵釋放.

    不知您的意思是?
    回復(fù)

    使用道具 舉報

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

    本版積分規(guī)則

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

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

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