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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2219|回復: 12
打印 上一主題 下一主題
收起左側

求教一個單片機矩陣按鍵的程序調試問題

[復制鏈接]
跳轉到指定樓層
樓主
ID:100982 發表于 2022-7-21 08:40 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
    這段程序是摘錄的51hei單片機論壇的教程,這里有個說明中斷函數中掃描 KeyIn 輸入和切換 KeyOut 輸出的順序與前面提到的順序不同,程序中我首先對所有的 KeyIn 輸入做了掃描、消抖,然后才切換到了下一次的 KeyOut 輸出,也就是說我們中斷每次掃描的實際是上一次輸出選擇的那行按鍵,這是為什么呢?因為任何信號從輸出到穩定都需要一個時間,有時它足夠快而有時卻不夠快,這取決于具體的電路設計,我們這里的輸入輸出順序的顛倒就是為了讓輸出信號有足夠的時間(一次中斷間隔)來穩定,并有足夠的時間來完成它對輸入的影響,當你的按鍵電路中還有硬件電容消抖時,這樣處理就是絕對必要的了,雖然這樣使得程序理解起來有點繞,但它的適應性是最好的,換個說法就是,這段程序足夠“健壯”,足以應對各種惡劣情況 。
    這里我不太明白,一開始進入中斷的時候,keyout等于0,然后程序往下跑,keyout++,等于1了,case1,打開的是第二行。但是第二行并沒有被拉低為0啊,這里不知道是為什么?
        不過我查閱了別的一些51的教程,關于矩陣按鍵這塊,貌似沒看到這么操作的,很是納悶,有這個必要嗎?別的程序都沒這么寫,包括它處理按鍵去抖的這個方法,哪種才是最優的呢?是這種還是別人直接寫個delay()多少毫秒那種呢?

單片機源程序如下:
void InterruptTimer0() interrupt 1
{
unsigned char i;
static unsigned char keyout = 0; //矩陣按鍵掃描輸出索引
static unsigned char keybuf[4][4] = { //矩陣按鍵掃描緩沖區
{0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF},
{0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF}
};
TH0 = 0xFC;
TL0 = 0x67;
//重新加載初值

//將一行的 4 個按鍵值移入緩沖區
keybuf[keyout][0] = (keybuf[keyout][0] << 1) | KEY_IN_1;
keybuf[keyout][1] = (keybuf[keyout][1] << 1) | KEY_IN_2;
keybuf[keyout][2] = (keybuf[keyout][2] << 1) | KEY_IN_3;
keybuf[keyout][3] = (keybuf[keyout][3] << 1) | KEY_IN_4;
//消抖后更新按鍵狀態
for (i=0; i<4; i++) //每行 4 個按鍵,所以循環 4 次
{
if ((keybuf[keyout][ i] & 0x0F) == 0x00)
{ //連續 4 次掃描值為 0,即 4*4ms 內都是按下狀態時,可認為按鍵已穩定的按下
KeySta[keyout]
[ i] = 0;
}
else if ((keybuf[keyout]
[ i] & 0x0F) == 0x0F)
{ //連續 4 次掃描值為 1,即 4*4ms 內都是彈起狀態時,可認為按鍵已穩定的彈起
KeySta[keyout]
[ i] = 1;
[ i]}
[ i]}
//執行下一次的掃描輸出
keyout++; //輸出索引遞增
keyout = keyout & 0x03; //索引值加到 4 即歸零
switch (keyout) //根據索引,釋放當前輸出引腳,拉低下次的輸出引腳
{
case 0: KEY_OUT_4 = 1; KEY_OUT_1 = 0; break;
case 1: KEY_OUT_1 = 1; KEY_OUT_2 = 0; break;
case 2: KEY_OUT_2 = 1; KEY_OUT_3 = 0; break;
case 3: KEY_OUT_3 = 1; KEY_OUT_4 = 0; break;
default: break;
}
}  

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

使用道具 舉報

沙發
ID:224003 發表于 2022-7-21 10:27 | 只看該作者
找版主的書,這個按鍵章節部分,你再仔細看看,對照實驗,理解它
回復

使用道具 舉報

板凳
ID:100982 發表于 2022-7-21 13:56 | 只看該作者
hzxyy 發表于 2022-7-21 10:27
找版主的書,這個按鍵章節部分,你再仔細看看,對照實驗,理解它

看過了,請問有必要這么寫嗎?我看很多別 的書都不是這么寫的。
回復

使用道具 舉報

地板
ID:491577 發表于 2022-7-22 10:13 | 只看該作者
樓主是做工控的吧對按鍵抗干擾有要求,樓主只是考慮了按下的情況,按鍵釋放沒有考慮,同時按鍵也沒有考慮,我寫有一個按鍵檢測程序,你參考一下。
這是按鍵檢測模塊函數:要認真看才能夠理解。
void key() //按鍵處理模塊,需要放在10ms中斷中運行!!!
/* 說明:1、按鍵單擊,指按下100-1000ms內釋放,加入時間限制是為了防止干擾。
             2、按鍵長按,指按下3-10s內釋放,加入時間限制是為了防止干擾。
             3、函數運行后,按鍵值保存在key1、key2。用戶直接調用key1、key2即可。
*/
{
  u16 static kgr[4];    //必須要static,抗干擾時間數組
  u8  static kanggr[4]; //中間變量1
  u8  static anjtem[4]; //按鍵釋放中間變量。
  u8 i;
  u8 L_anj[4];
  L_anj[0]=k1;
  L_anj[1]=k2;
  L_anj[2]=k3;
  L_anj[3]=k4;
  for(i=0;i<3;i++)  //4個按鍵處理,key1,
   {
         if(L_anj[ i]==0)        //按鍵按下                                       
          { if(kanggr[ i]==0)        //中間變量1,與下面互鎖
             { kgr[ i]=0;                //抗干擾時間清零,每次按鍵只寫1次。
               kanggr[ i]=1;         //中間變量1
               anjtem[ i]=1;         //按鍵釋放中間變量。與下面互鎖
            }

           if(anjtem[ i]==1)
           {
                  kgr[ i]++;//10毫秒計時。
                  if(kgr[ i]>1000) //按鍵按下大于10秒,強制復位,防止誤按。
                   { anjtem[ i]=0; //按鍵釋放中間變量。與上面互鎖
                     kgr[ i]=0;
                   }
           }
         }

     else    //按鍵釋放
     { kanggr[ i]=0;           //中間變量1,與上面互鎖
           if(kgr[ i]>9 && kgr[ i]<99) //按鍵間隔100--1000毫秒才有效,防止電磁干擾。時間可以修改
                 key1=i+1;   //單擊,按鍵間隔100--1000毫秒,每次釋放只寫1次。一次只能夠按一個按鍵,不允許同時按鍵。
           else if(kgr[ i]>300 && kgr[ i]<1000) //按鍵間隔3000--10000毫秒才有效,防止電磁干擾。時間可以修改
                 key1=(i+1)*10;//長按,按鍵間隔3--10秒,每次釋放只寫1次。
     }
  }

//下面是處理:key2是有按鍵按下就輸出鍵值。        
    for(i=0;i<3;i++)
         { if(L_anj[ i]==0)
           key2=i+1;//一次只能夠按一個按鍵,不允許同時按鍵。
         }
}

完整的程序參考:http://www.zg4o1577.cn/bbs/dpj-208253-1.html

評分

參與人數 1黑幣 +15 收起 理由
wpppmlah + 15 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

5#
ID:100982 發表于 2022-7-22 16:35 | 只看該作者
hhh402 發表于 2022-7-22 10:13
樓主是做工控的吧對按鍵抗干擾有要求,樓主只是考慮了按下的情況,按鍵釋放沒有考慮,同時按鍵也沒有考慮, ...

哈,謝謝,不過你的變量全部都是漢語拼音,有點意思。
回復

使用道具 舉報

6#
ID:491577 發表于 2022-7-23 13:54 | 只看該作者
本帖最后由 hhh402 于 2022-7-23 14:01 編輯
wifen 發表于 2022-7-22 16:35
哈,謝謝,不過你的變量全部都是漢語拼音,有點意思。

不會英語,不過單片機C語言英文不多,編程核心還是算法,怎么通過已知的幾個變量計算出所需要的量。
回復

使用道具 舉報

7#
ID:100982 發表于 2022-7-25 07:53 | 只看該作者
hzxyy 發表于 2022-7-21 10:27
找版主的書,這個按鍵章節部分,你再仔細看看,對照實驗,理解它

看了也理解了,就是不知道這種寫法優勢何在,實際工程中的寫法是怎樣的呢?
回復

使用道具 舉報

8#
ID:190577 發表于 2022-7-25 08:05 | 只看該作者
wifen 發表于 2022-7-21 13:56
看過了,請問有必要這么寫嗎?我看很多別 的書都不是這么寫的。

小宋老師的書寫的比較好的,他是利用狀態機的思想來寫的,釋放了單片機,不是用延時函數完成的。每個人的程序寫法都是不一樣的,沒必要糾結,只要別人的程序來過來會改加工完成自己的功能就OK了。
回復

使用道具 舉報

9#
ID:190577 發表于 2022-7-25 08:08 | 只看該作者
wifen 發表于 2022-7-25 07:53
看了也理解了,就是不知道這種寫法優勢何在,實際工程中的寫法是怎樣的呢?

這種寫法就是釋放了單片機,單片機有更多的時間去干別的事情,而不是在延時等待,啥事也不干,實際的工程,實時要求不要就用delay函數就行了,對系統實時要求比較高的,就需要用狀態機思想編程。
回復

使用道具 舉報

10#
ID:1040470 發表于 2022-7-25 14:40 | 只看該作者
我只會按行按列掃描寫的這種,新手勿嘲請教一下大神們上述矩陣按鍵代碼是提高穩定性而加的判斷嘛?#include <REGX52.H>
#include "Delay.h"
unsigned char MatrixKey()
{
        unsigned char KeyNumber=0;
        P1=0xFF;
        P1_3=0;
        if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=1;}
        if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=5;}
        if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=9;}
        if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=13;}
        P1_2=0;
        if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=2;}
        if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=6;}
        if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=10;}
        if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=14;}
        P1_1=0;
        if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=3;}
        if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=7;}
        if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=11;}
        if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=15;}
        P1_0=0;
        if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=4;}
        if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=8;}
        if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=12;}
        if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=16;}
        return KeyNumber;
}
       
回復

使用道具 舉報

11#
ID:100982 發表于 2022-7-25 19:22 | 只看該作者
wuwuwuwuwukk 發表于 2022-7-25 14:40
我只會按行按列掃描寫的這種,新手勿嘲請教一下大神們上述矩陣按鍵代碼是提高穩定性而加的判斷嘛?#i ...

你這個寫法有點繁瑣啊
回復

使用道具 舉報

12#
ID:213173 發表于 2022-7-25 21:07 | 只看該作者
wifen 發表于 2022-7-25 19:22
你這個寫法有點繁瑣啊

給你一個簡單、實用、可靠、易懂的4*4矩陣按鍵程序參考。
  1. void key_scan()                                        //4*4矩陣按鍵掃描程序
  2. {
  3.         static bit sign=0;                        //按鍵狀態標志位變量
  4.         static unsigned int count=0;//計數變量
  5.         P3=0xf0;                                        //賦值P3 1111 0000
  6.         if(P3!=0xf0)                                //檢測有按鍵按下
  7.         {
  8.                 if(++count>=10 && sign==0)//消抖(根據實際應用場景調整計數值,控制在10~20ms)
  9.                 {                       
  10.                         sign=1;                        //按鍵狀態標志置1
  11.                         switch(P3)
  12.                         {
  13.                                 case(0Xe0):KeyValue = 1;break;
  14.                                 case(0Xd0):KeyValue = 2;break;
  15.                                 case(0Xb0):KeyValue = 3;break;
  16.                                 case(0X70):KeyValue = 4;break;
  17.                         }
  18.                         P3=0x0f;                        //賦值P3 0000 1111
  19.                         switch(P3)
  20.                         {
  21.                                 case(0X0e):KeyValue+= 0;break;
  22.                                 case(0X0d):KeyValue+= 4;break;
  23.                                 case(0X0b):KeyValue+= 8;break;
  24.                                 case(0X07):KeyValue+=12;break;
  25.                         }
  26.                 }
  27.         }
  28.         else                                                //鍵抬起
  29.         {
  30.                 sign=0;                                //按鍵狀態標志清0
  31.                 count=0;                                //消抖計數清0
  32.         }
  33. }
復制代碼
回復

使用道具 舉報

13#
ID:190577 發表于 2022-7-25 21:45 | 只看該作者
wuwuwuwuwukk 發表于 2022-7-25 14:40
我只會按行按列掃描寫的這種,新手勿嘲請教一下大神們上述矩陣按鍵代碼是提高穩定性而加的判斷嘛?#i ...

這種寫法,容易理解
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 91国产精品 | 欧美韩一区二区 | 一级黄色夫妻生活 | 久久99国产精品久久99果冻传媒 | 欧美专区在线 | 三级免费毛片 | 欧洲妇女成人淫片aaa视频 | 精精国产xxxx视频在线播放 | 国产免费福利在线 | 国产一区欧美一区 | 在线观看免费av网 | 日韩免费在线视频 | 欧美二区在线 | 91欧美精品 | 中文成人在线 | 欧美精品a∨在线观看不卡 国产精品久久国产精品 | 亚洲精选一区二区 | 日韩中文字幕 | 2022精品国偷自产免费观看 | 少妇午夜一级艳片欧美精品 | 日韩资源 | 久久91av| 久艹网站 | 无码一区二区三区视频 | 福利影院在线看 | 999在线精品 | 日本三级日产三级国产三级 | 91伊人| 亚洲高清视频一区 | 99视频网站 | 男女羞羞免费视频 | 亚洲视频三| 91久久久精品国产一区二区蜜臀 | 99免费精品 | 一级在线观看 | 国产精品国产自产拍高清 | 国产亚洲欧美在线 | 久草热视频 | www国产成人| 夏同学福利网 | av av在线 |