標(biāo)題: 關(guān)于單片機多按鍵按下的檢測程序問題 [打印本頁]

作者: 18674201426    時間: 2021-1-28 16:32
標(biāo)題: 關(guān)于單片機多按鍵按下的檢測程序問題
我是初學(xué)單片機和C語言,覺得很有意思。所以在網(wǎng)上買了套件。學(xué)到4*4矩陣鍵盤的時候,一開始就發(fā)現(xiàn)這個教程的程序太低級,用while去卡住cpu只為了檢測一個按鍵是否松開,商家說沒有更好的辦法,太扯淡了,絕不可能!
所以這幾天在找一些資料,也沒找到。自己也過一些辦法嘗試寫過,但始終無法跳出教程給的框架。
所以在論壇發(fā)了求助帖,也有大神回復(fù)了辦法,可能我悟性確實太低,沒代碼根本想不通,即使有代碼沒注釋可能也看不懂。有那么難嗎?可能我不適合學(xué)編程吧,我想我最終也能解決這個問題,不過估計是幾年后了。

1.jpg (64.59 KB, 下載次數(shù): 102)

1

1

2.jpg (53.72 KB, 下載次數(shù): 92)

2

2

3.jpg (18.48 KB, 下載次數(shù): 104)

3

3

4.jpg (74.09 KB, 下載次數(shù): 94)

4

4

作者: szb314    時間: 2021-1-28 17:04
那些客服就是糊弄人的,度娘一圈應(yīng)該能找到你想要的,不要拘泥于別人的套路,自己得思考,也不要看那些代碼寫的多高端,甚至一段時間后自己都看不懂,編譯器很可能會把那看似高級的代碼編譯成效率更低下的
作者: 18674201426    時間: 2021-1-28 17:24
szb314 發(fā)表于 2021-1-28 17:04
那些客服就是糊弄人的,度娘一圈應(yīng)該能找到你想要的,不要拘泥于別人的套路,自己得思考,也不要看那些代碼 ...

我就是找了幾天沒找到才去問的,結(jié)果商家的技術(shù)水平這么低。有點失望。其實實現(xiàn)什么功能倒是次要的,重要的是實現(xiàn)按鍵不沖突的編程思路。有些老哥回答的又看不懂,說的很簡單,但實際又寫不出來。這東西對新手太勸退了,跟著教程走一點拔高的思維都沒有,要我照本宣科,講的比他們還好些。
作者: yousir    時間: 2021-1-28 18:09
就我的認(rèn)知來說鍵盤分兩種,有些老式的電腦的鍵盤是編碼鍵盤(電路設(shè)計復(fù)雜編程簡單)早期IBM的個人計算機鍵盤是非編碼式的,現(xiàn)在的部分薄膜鍵盤也是非編碼鍵盤(電路簡單編程稍復(fù)雜)單片機使用最多的就是非編碼按鍵也就是需要行和列掃描通過電平的高低來實現(xiàn)檢測按鍵是否按下
作者: yousir    時間: 2021-1-28 18:13
還有CPU和MCU是兩個不同的東西哦,可以MCU是將計算機的CPU、RAM、ROM、定時計數(shù)器和多種I/O接口集成在一片芯片上,形成芯片級的芯片,內(nèi)部除了CPU外還有RAM、ROM,可以直接加簡單的外圍器件(電阻,電容)就可以運行代碼了。
作者: SHANWAZI    時間: 2021-1-28 18:14
也有別的辦法  多加學(xué)習(xí)已經(jīng)就知道了我也是這樣的
作者: yousir    時間: 2021-1-28 18:17
https://blog.csdn.net/andrewniu/article/details/53315881對于你說的鍵盤沖突可以參見這篇文章,講解了如何處理非編碼鍵盤的沖突
作者: 人人學(xué)會單片機    時間: 2021-1-28 18:29
不就是矩陣鍵盤嗎 你早說啊。給你一個 自己看圖片

作者: 人人學(xué)會單片機    時間: 2021-1-28 18:29
  1. u8 xdata Key4x4_Read_Byte=3;//矩陣結(jié)果輸出變量
  2. u8 code Key4x4_Buffer[4]={0xfe,0xfd,0xfb,0xf7};
  3. void Key4x4_Scan_Drive()
  4. {
  5.         static xdata u16 count=0;
  6.         u8 i,j,Value;
  7.         count++;
  8.         if(count>1000)
  9.         {
  10.                 count=0;
  11.                 IE2&=~0x08;
  12.                 for(i=0;i<4;i++)
  13.                 {
  14.                         P0=Key4x4_Buffer[i];
  15.                         Value=0x80;
  16.                         for(j=0;j<4;j++)
  17.                         {
  18.                                 if((P0&Value)==0)
  19.                                 {
  20.                                         Key4x4_Read_Byte=j*4+i+1;
  21.                                 }
  22.                                 Value>>=1;
  23.                         }
  24.                 }
  25.                 P0=0xff;
  26.                 IE2|=0x08;
  27.         }
  28. }
復(fù)制代碼

作者: 18674201426    時間: 2021-1-28 18:40
yousir 發(fā)表于 2021-1-28 18:13
還有CPU和MCU是兩個不同的東西哦,可以MCU是將計算機的CPU、RAM、ROM、定時計數(shù)器和多種I/O接口集成在一片 ...

哎。這我當(dāng)然知道,你都把重點搞錯了。重點是那個技術(shù)用這種話騙我好讓我打消問他的念頭
作者: 18674201426    時間: 2021-1-28 18:54
yousir 發(fā)表于 2021-1-28 18:09
就我的認(rèn)知來說鍵盤分兩種,有些老式的電腦的鍵盤是編碼鍵盤(電路設(shè)計復(fù)雜編程簡單)早期IBM的個人計算機 ...

按鍵檢測不是重點,重點是無沖突,和按鍵松開后的檢測問題,電腦鍵盤就可以實現(xiàn)這個功能,一般都是3鍵無沖,高級點的6鍵無沖,有的甚至是全鍵無沖。這個功能是肯定能實現(xiàn)的,而且應(yīng)該不是太難的東西。PC鍵盤的資料我也查過,都是發(fā)通斷碼的,我這里說的是燈,其實是一個道理,無非就是改燈的電平,實現(xiàn)什么功能是次要的。包括多個按鍵按下之后的檢測,看起來也是沒問題的,可是當(dāng)按鍵松開的時候,比如現(xiàn)在按順序按下123,這3個鍵,當(dāng)1鍵松開后怎么檢測是1鍵松開了,而且這時候2和3還在工作。
作者: rundstedt    時間: 2021-1-28 19:08
18674201426 發(fā)表于 2021-1-28 18:54
按鍵檢測不是重點,重點是無沖突,和按鍵松開后的檢測問題,電腦鍵盤就可以實現(xiàn)這個功能,一般都是3鍵無 ...


想要任意按鍵同時按下無沖突需要硬件支持,樓主的開發(fā)板顯然沒有。純軟件實現(xiàn)無沖突那是白日做夢。

作者: 18674201426    時間: 2021-1-28 19:39
rundstedt 發(fā)表于 2021-1-28 19:08
想要任意按鍵同時按下無沖突需要硬件支持,樓主的開發(fā)板顯然沒有。純軟件實現(xiàn)無沖突那是白日做夢。

嗯,那我知道,這種是極端情況,因為不僅要考慮軟件的沖突,還要考慮硬件的沖突,因為按鍵都是并聯(lián)的。我想知道的是,至少軟件上不能有沖突,這樣我們就能挑選出無硬件沖突的按鍵來制作擴(kuò)展功能,畢竟那個教程里面給的用while來檢測按鍵松開是不科學(xué)的。
作者: 18674201426    時間: 2021-1-28 23:21
人人學(xué)會單片機 發(fā)表于 2021-1-28 18:29
u8 xdata Key4x4_Read_Byte=3;//矩陣結(jié)果輸出變量
u8 code Key4x4_Buffer[4]={0xfe,0xfd,0xfb,0xf7};
v ...

研究了一下,大概看懂了,這個應(yīng)該是逐行掃描法吧。
那個count++應(yīng)該就是延時吧,每隔10ms運行一次掃描程序,然后通過Key4x4_Read_Byte來判斷鍵位,繼而可以通過數(shù)組來發(fā)送數(shù)據(jù)。
但是這個應(yīng)該還是不行,當(dāng)按下多個鍵的時候,那每隔10ms就會從最靠近第一個鍵位的地方依次連續(xù)發(fā)送多個數(shù)據(jù),而且沒有按鍵松開的檢測,那按鍵松開需要執(zhí)行的就沒法操作了。
作者: zwf33    時間: 2021-1-29 00:23
請看這個大神的貼,里面有解決方法
http://www.torrancerestoration.com/bbs/dpj-162218-1.html
作者: 梁廷明    時間: 2021-1-29 09:01
  1.                         if(key_pumb!=0) // 按鍵沒有按下的時候
  2.                         {
  3.                                 key_pumb_flag=0;// 標(biāo)志位清零
  4.                         }
  5.                 //按住開始跑燈,抽氣(與開瓶不能同時按下兼容)       
  6.                 if(key_pumb==0&&key_motor==0)
  7.                 {
  8.                         delay100us(100);// 消除抖動延時       
  9.                 if(key_pumb==0&&key_motor==0)
  10.                  {
  11.                         //while(key_pumb==0);
  12.                         L_time_all=288;
  13.                         if(key_pumb_flag==0)// 消除抖動后再次判斷按鍵是否按下
  14.                         {
  15.                                 key_pumb_num++;if(key_pumb_num>=2){key_pumb_num=0;}//按下抽氣,再按下關(guān)閉
  16.                                 if(key_pumb_num==1){work=1;pumb=1;num++;auto_led_on(4,num);led_start_68();led_start_6A();}
  17.                                 if(key_pumb_num==0){work=0;pumb=0;}
  18.                         }
  19.                         key_pumb_flag=1;// 將標(biāo)志位置1鎖住 表示已經(jīng)按下
  20.                  }
  21.                 }
復(fù)制代碼

作者: TTQ001    時間: 2021-1-29 09:19
感謝樓主的分享。 希望您很快就能解決。
作者: 龍千校    時間: 2021-1-29 09:24
樓主不必糾結(jié)了,51開發(fā)板現(xiàn)在很多都做的很全面,很顯然你買的這個牌子是個不咋樣,至于這個技術(shù)人員目前還沒法確定是不是垃圾,但溝通理解能力明顯有缺陷,他根本就沒有理解你的問題就瞎回答.
至于樓主適不適合編程這個還不能下結(jié)論,至少你能發(fā)現(xiàn)問題,沒法解決問題只是你經(jīng)驗和能力還需要積累.
WHILE做按鍵是新手入門最常用的方式,等你學(xué)多了之后這個問題自然就能理解了
作者: xianfajushi    時間: 2021-1-29 09:28
要能自主寫矩陣驅(qū)動就得充分了解工作原理才能發(fā)揮得淋漓盡致,多看看其他人寫的驅(qū)動代碼,這個看看能否有點啟示https://blog.csdn.net/xianfajushi/article/details/80884859
作者: robinsonlin    時間: 2021-1-29 11:51
你要的應(yīng)該是類似這樣的解決方案吧?
http://www.torrancerestoration.com/bbs/dpj-161402-1.html

把每個鍵都對應(yīng)一個鍵值,組合鍵也對應(yīng)一個鍵值, 沒有按鍵也對應(yīng)一個鍵值,你的問題不就解決了?
作者: 18674201426    時間: 2021-1-29 12:39
yousir 發(fā)表于 2021-1-28 18:17
https://blog.csdn.net/andrewniu/article/details/53315881對于你說的鍵盤沖突可以參見這篇文章,講解了如 ...

這個我很早就看過了,他這主要講的是PC鍵盤與PC機的PS2通信協(xié)議,然后大概的講了一下沖突的產(chǎn)生原因,但是并沒有講解如何從軟件和硬件層面去解決這個問題,如果我現(xiàn)在連軟件層面的問題都解決不了,贏了做了也沒用。
作者: sync763    時間: 2021-1-29 14:23
不考慮硬件沖突的原因,但從軟件方面說可以嘗試將讀回來的鍵值放在一個變量里。讓這個變量每一位代表一個按鍵,然后判斷每一位的變化,應(yīng)該可以實現(xiàn)。
作者: 18674201426    時間: 2021-1-29 16:10
robinsonlin 發(fā)表于 2021-1-29 11:51
你要的應(yīng)該是類似這樣的解決方案吧?
http://www.torrancerestoration.com/bbs/dpj-161402-1.html

昨天有個老鐵也說用標(biāo)識位的方式試試,通過數(shù)組對應(yīng)按鍵,但是沒有辦法解決按鍵松開的問題,并且多鍵位按下時掃描鍵盤狀態(tài)會順序發(fā)送按鍵值,但是他的示例給了我一些靈感,好像有點眉目,所以我也還在考慮標(biāo)識位這種方式。
作者: 18674201426    時間: 2021-1-29 16:12
xianfajushi 發(fā)表于 2021-1-29 09:28
要能自主寫矩陣驅(qū)動就得充分了解工作原理才能發(fā)揮得淋漓盡致,多看看其他人寫的驅(qū)動代碼,這個看看能否有點啟 ...

就是因為目前想不出又找不到這個原理,所以才來問,你發(fā)的那些都是基礎(chǔ)的按鍵檢測方式,和教程一樣的。
作者: 18674201426    時間: 2021-1-29 16:20
zwf33 發(fā)表于 2021-1-29 00:23
請看這個大神的貼,里面有解決方法
http://www.torrancerestoration.com/bbs/dpj-162218-1.html

嗯,這個我很早就看過了,他的示例是有借鑒的價值的。
作者: sync763    時間: 2021-1-30 12:36
18674201426 發(fā)表于 2021-1-29 16:10
昨天有個老鐵也說用標(biāo)識位的方式試試,通過數(shù)組對應(yīng)按鍵,但是沒有辦法解決按鍵松開的問題,并且多鍵位按 ...

可以檢測的,當(dāng)按鍵按下的時候相應(yīng)位是0,松開后相應(yīng)位變?yōu)?,你只需要檢測相應(yīng)的位的變化就可以了。只要和前一次的不同就說明按鍵有變化了。
作者: tyrl800    時間: 2021-1-31 16:10
送你一個程序,可以滿足你的按鍵要求
#include<reg51.h>
#define uchar unsigned char
#define keyport P1

void scan1(void);

/****************************************************************/
void        tim0()        interrupt    1       
{            
         TH0=(65536-10000)/256;
     TL0=(65536-10000)%256;
         scan1();
          
}
       
/****************************************************************/                       
unsigned tmp[4];               

/****************************************************************/
void scan1(void)       
{  unsigned        char j;
   unsigned int itmp=0;
   for(j=0;j<4;j++)       
   {keyport=~(0x10<<j);       
        tmp[j]=~(keyport&0x0f)&0x0f;
        itmp=itmp|(tmp[j]<<(4*j));
        }
        itmp=~itmp;
        P0=itmp;
        P2=itmp>>8;               
                    
}                       
/****************************************************************/                       

void main(void)
  {        TH0=(65536-10000)/256;
    TL0=(65536-10000)%256;
        TMOD=0x01;
        EA=ET0=TR0=1;
       
        while(1);
  }
/****************************************************************/





歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1