標(biāo)題: 三行按鍵 單片機(jī)程序分析 [打印本頁]
作者: RMLS 時(shí)間: 2019-9-8 16:48
標(biāo)題: 三行按鍵 單片機(jī)程序分析
今天寫一個(gè)進(jìn)階級(jí)的帖子分享一下,記錄過程。
三行按鍵由煙臺(tái)南山學(xué)院-零點(diǎn)工作室原創(chuàng),如轉(zhuǎn)載,請標(biāo)明出處,并附本鏈接。
我看CSDN上有三行按鍵相關(guān)的分析,但并不是原創(chuàng)作者以及我們工作室相關(guān)學(xué)長。
三行按鍵從出生到現(xiàn)在已經(jīng)很多個(gè)年頭了,經(jīng)過幾代優(yōu)化,現(xiàn)在有兩個(gè)版本,今天分析一下,也在本論壇擴(kuò)充一下資源。
我在本論壇搜索三行按鍵,并沒有相關(guān)的帖子。
首先說明一下什么是三行按鍵,有什么用,什么好處,以及弊端。
三行按鍵,顧名思義,代碼只有三行;
用處:在咱日常生活中,運(yùn)用按鍵時(shí)(矩陣按鍵除外),例如四個(gè)獨(dú)立按鍵甚至八個(gè)。完全可以使用。
最大的好處就是,平時(shí)按鍵會(huì)有長按和短按,不難理解,一個(gè)是觸發(fā)就松手,另一就是按下不松手,第二個(gè)針對按下就執(zhí)行某個(gè)程序,松開就停止執(zhí)行,比如手表上調(diào)時(shí)間的按鈕,分鐘在長按0.8s之后自己會(huì)自加,當(dāng)松開按鈕時(shí),停止自加。
好處:代碼簡介,但是分析過程比較困難,接下來會(huì)進(jìn)行分析。
弊端:下面兩種方法都有各自的弊端,在下面有詳細(xì)說明。
首先寫出三行按鍵的兩個(gè)版本:
void Threekey(uchar *Trg,uchar *Cont)
{
unsigned char ReadData = (P3 & 0x0f) ^ 0xff;
(*Trg) = ReadData & (ReadData ^ (*Cont));
(*Cont) = ReadData;
}
void ThreeKey(void)
{
unsigned char ReadDat = (P3 ^ 0xff) & 0x0f;
Trg = (ReadDat ^ Cont)& ReadDat;
Cont = ReadDat;
}
最大的區(qū)別不在指針,而是在相與以及或運(yùn)算的先后順序。
導(dǎo)致最后當(dāng)按鍵觸發(fā),運(yùn)算出來的結(jié)果不相同,。
代碼分析如下:
//第一種程序解析
/*******************************************/
void key(void)
{
unsignedchar ReadData = (P3 & 0x0f)^ 0xff;
Trg)=ReadData & (ReadData^ Cont);
Cont)=ReadData;
}
//短按
//沒有按下情況下:
ReadData= (0xff & 0x0f) ^ 0xff = 0xf0
Trg= 0xf0 & (0xf0 ^ 0x00) = 0xf0
Cont= 0xf0
//第二次掃描未按下
ReadData= (0xff & 0x0f) ^ 0xff = 0xf0
Trg= 0xf0 & ( 0xf0 ^ 0xf0) = 0x00
Count= 0xf0
//第三次掃描未按下
ReadData= (0xff & 0x0f) ^ 0xff = 0xf0
Trg= 0xf0 & (0xf0 ^ 0xf0) = 0x00
Cont= 0xf0
//當(dāng)?shù)谝粋(gè)按鍵按下情況
ReadData= (0xfe & 0x0f) ^ 0xff = 0xf1
Trg= 0xf1 & ( 0xf1 ^ 0xf0) = 0x01
Cont= 0xf1
//長按
//當(dāng)按鍵按下并且不放手情況
ReadData= (0xfe & 0x0f ) ^ 0xff = 0xf1
Trg= 0xf1 & (0xf1 ^ 0xf1 ) = 0x00
Cont= 0xf1
//按鍵松手
ReadData= (0xff & 0x0f) ^ 0xff = 0xf0
Trg= 0xf0 & (0xf0 ^ 0x00) = 0xf0
Cont= 0xf0
以此類推 短按情況下 Trg = 0x01
0x02
0x04
0x08
長按情況下 Count = 0xf1
0xf2
0xf4
0xf8
弊端:當(dāng)按鍵沒有按下,第一次掃描的Trg第一次會(huì)有一個(gè)值的變化,Trg= 0xf0;現(xiàn)在還沒有試出來對執(zhí)行程序有什么影響。
//第二種程序解析
/*******************************************/
void ThreeKey(void)
{
unsignedchar ReadDat = (P3 ^ 0xff)& 0x0f;
Trg= (ReadDat ^ Cont)&ReadDat;
Cont= ReadDat;
}
//短按
//按鍵沒有按下情況
ReadDat= (0xff ^ 0xff) & 0x0f = 0x00
Trg= (0x00 ^ 0x00 ) & 0x00 = 0x00
Cont= 0x00
//按鍵按下情況 第一個(gè)按鍵按下
ReadDat= (0xfe ^ 0xff) & 0x0f = 0x01
Trg= (0x01 ^ 0x00) & 0x01 = 0x01
Cont= 0x01
//長按
//按鍵按下沒有松手情況
ReadDat= (0xfe ^ 0xff ) & 0x0f = 0x01
Trg= (0x01 ^ 0x01) & 0x01 = 0x00
Cont= 0x01
//按鍵松手
ReadDat= (0xff ^ 0xff) & 0x0f = 0x00
Trg= (0x00 ^ 0x01) & 0x00 = 0x00
Count = 0x00
以此類推 短按情況下 Trg = 0x01
0x02
0x04
0x08
長按情況下 Count = 0x01
0x02
0x04
0x08
弊端:短按Trg和長按Count運(yùn)算結(jié)果是一樣的,也就是說當(dāng)執(zhí)行程序的時(shí)候需要分明。第二種比較好用。
附件文件和本文程序一樣。
主要就是講這個(gè)算法如何用,而不是拿現(xiàn)成的程序來給你們,這樣這段算法的意義并不大。
說明一下,第二個(gè)代碼的Trg以及Count是全局變量,可以在執(zhí)行按鍵的函數(shù)里面進(jìn)行調(diào)用。
這段例程里面,按鍵可以放在P30,P31,P32,P33口,四個(gè)按鍵進(jìn)行舉例的。
0.png (113.8 KB, 下載次數(shù): 52)
下載附件
2019-9-8 22:21 上傳
完整的pdf格式文檔51黑下載地址:
三行按鍵.pdf
(128.32 KB, 下載次數(shù): 30)
2019-9-8 16:26 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
作者: m182892 時(shí)間: 2019-9-9 08:30
有沒有人在項(xiàng)目中用到這個(gè)按鍵
作者: bhjyqjs 時(shí)間: 2019-9-9 08:37
第二種方法我一直在用,實(shí)用性較高。
作者: bhjyqjs 時(shí)間: 2019-9-9 08:43
void ThreeKey()
{
ReadData = ~ReadData; // 1
Trg = ReadData & ~Cont; // 2 注“~”優(yōu)先級(jí)高于& ;ReadData為本次鍵狀態(tài),Cont為上次鍵狀態(tài)
Cont = ReadData; // 3
}
這是改進(jìn)版,更好理解。編譯后代碼量一樣。
作者: HSZ 時(shí)間: 2019-9-9 21:54
優(yōu)秀啊
作者: zhangjianhu 時(shí)間: 2019-11-16 09:30
在實(shí)際項(xiàng)目中,實(shí)際使用下。
| 歡迎光臨 (http://www.denmoz.com/bbs/) |
Powered by Discuz! X3.1 |