設(shè)計(jì)中在遇到按鍵較多,但是單片機(jī)I/O資源有限時(shí),采用矩陣鍵盤是一種很好的選擇方案。在按鍵較少時(shí),矩陣鍵盤沒有明顯的優(yōu)勢(shì),比如3×3矩陣鍵盤占用I/O口6個(gè),只支持9個(gè)按鍵;但是,按鍵較多時(shí),矩陣鍵盤的優(yōu)勢(shì)就凸顯出來了,比如5×5矩陣鍵盤占用I/O口10個(gè),可支持25個(gè)按鍵;
矩陣鍵盤的硬件設(shè)計(jì)非常簡單,如圖1以5×5矩陣鍵盤為例,藍(lán)色行線5條,綠色列線5條(加上拉電阻),用按鍵代替行列交叉的節(jié)點(diǎn)即組成了矩陣鍵盤,其中二極管處的紅色連線可用來檢測(cè)按鍵是否按下或作為中斷信號(hào)的(可以不需要,使用時(shí)沒有任何影響,本文不涉及)。
圖1:矩陣鍵盤
如圖2為單片機(jī)STM32F103CBT6的外圍電路,帶顏色的I/O口為矩陣鍵盤行線PA1~PA5(藍(lán)色),列線PA6~PA10(綠色)。為方便編程,矩陣鍵盤最好選擇同組的I/O端口。
圖2:單片機(jī)外圍電路
硬件的設(shè)計(jì)就是以上部分,接下來講解程序部分,
矩陣鍵盤的掃描方法有多種,其中很青睞的是行列反轉(zhuǎn)掃描,不僅簡單而且效率高,而且只需要掌握該方法就足夠了。
行列反轉(zhuǎn)掃描的邏輯:
①行線輸出全為0(行線PA1~PA5配置成推挽輸出,列線PA6~PA10配置成上拉輸入)
②讀入列線值
③輸出列線值(行線PA1~PA5配置成上拉輸入,列線PA6~PA10配置成推挽輸出)
④讀入行線值
⑤組合行線列線值
對(duì)于STM32的單片機(jī),直接操作寄存器會(huì)更簡單,且無需再對(duì)I/O進(jìn)行另外的配置,全部代碼如圖3所示,完全可以當(dāng)做一個(gè)模塊來使用。
圖3:矩陣鍵盤的行列反轉(zhuǎn)掃描
以下代碼與圖3里面的代碼完全一致(為方便瀏覽和拷貝)
/*----------------------
5*5矩陣鍵盤掃描函數(shù),返回掃描鍵值(行列反轉(zhuǎn)掃描)
-----------------------*/
u16 Key_Scan(void)
{
u16 cord_h,cord_l;
u16 key_value = 0xFFFF;
GPIOA->CRL = 0x88333334;
GPIOA->CRH = 0x44444888;
GPIOA->ODR = GPIOA->IDR & 0xFFC1;
cord_l = GPIOA->IDR & 0x07C0;
if(cord_l != 0x07C0)
{
delay_ms(10);
if(cord_l != 0x07C0)
{
cord_l = GPIOA->IDR & 0x07C0;
GPIOA->CRL = 0x33888884;
GPIOA->CRH = 0x44444333;
GPIOA->ODR = cord_l | 0xF83F;
delay_us(1);
cord_h = GPIOA->IDR & 0x003E;
cord_h >>= 1;
cord_l >>= 1;
key_value = (cord_l + cord_h) & 0xFFFF;
return(key_value);
}
}return(0xFFFF);
}
以下代碼為端口配置寄存器的操作,PA組I/O有16個(gè)引腳:PA0~PA15;3代表推挽輸出,4代表浮空輸入,8代表上拉輸入;
GPIOA->CRL = 0x88333334; //低8位配置
GPIOA->CRH = 0x44444888; //高8位配置
以下代碼中,GPIOA->ODR為端口輸出數(shù)據(jù)寄存器,用于寫操作;GPIOA->IDR為端口輸入數(shù)據(jù)寄存器,用于讀操作;
0xFFC1的二進(jìn)制:1111 1111 1100 0001,表示要對(duì)PA1~PA5置0。
0x07C0的二進(jìn)制:0000 0111 1100 0000,表示要對(duì)PA6~PA10讀值。
GPIOA->ODR = GPIOA->IDR & 0xFFC1;//行線輸出全為0
cord_l = GPIOA->IDR & 0x07C0; //讀入列線值
行列反轉(zhuǎn)后的原理與上面完全一樣,這里就不一一闡述了。
最后講一下組合行線列線值,假如S1按鍵按下去了,得到的二進(jìn)制為(注意黑體字)
cord_h:0000 0000 0011 1100
cord_l:0000 0111 1000 0000
cord_h >>= 1 表示右移1位得到:
0000 0000 0001 1110
cord_l >> = 1 表示右移1位得到:
0000 0011 1100 0000
組合碼(鍵值):key_value=0000 0011 1101 1110,即0x03DE;最后函數(shù)返回key_value值,該值就作為判斷S1的鍵值。
之所以右移1位,是因?yàn)镻A0沒有用于矩陣鍵盤,所得到的鍵值也就被左移了1位,事實(shí)上,也可以不用右移,只是得到的組合碼不同而已,右移是為了方便計(jì)算。
矩陣鍵盤的鍵值定義如下:
#define S1 0x03DE
#define S2 0x03BE
#define S3 0x037E
#define S4 0x02FE
#define S5 0x01FE
#define S6 0x03DD
#define S7 0x03BD
#define S8 0x037D
#define S9 0x02FD
#define S10 0x01FD
#define S11 0x03DB
#define S12 0x03BB
#define S13 0x037B
#define S14 0x02FB
#define S15 0x01FB
#define S16 0x03D7
#define S17 0x03B7
#define S18 0x0377
#define S19 0x02F7
#define S20 0x01F7
#define S21 0x03CF
#define S22 0x03AF
#define S23 0x036F
#define S24 0x02EF
#define S25 0x01EF
要點(diǎn):
①行列反轉(zhuǎn)掃描的思想是行線作為輸出時(shí),讀出列線的值;然后反過來,列線作為輸出時(shí),讀出行線的值,最后把兩個(gè)值組合起來就是該按鍵的鍵值;
②參與計(jì)算的十六進(jìn)制數(shù)一定要與行線或列線在同組端口的位置匹配,比如0xFFC1的二進(jìn)制:1111 1111 1100 0001,表示要對(duì)PA1~PA5置0。
審核編輯:郭婷
-
二極管
+關(guān)注
關(guān)注
148文章
10099瀏覽量
171581 -
單片機(jī)
+關(guān)注
關(guān)注
6067文章
44988瀏覽量
650331
原文標(biāo)題:5×5矩陣鍵盤掃描,一條龍化繁為簡,值得擁有
文章出處:【微信號(hào):FANYPCB,微信公眾號(hào):凡億PCB】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
HarmonyOS應(yīng)用自定義鍵盤解決方案
FZH182 LED驅(qū)動(dòng)控制專用電路中文手冊(cè)
LED驅(qū)動(dòng)控制專用電路FZH181中文手冊(cè)
ADP5588移動(dòng)I/O擴(kuò)展器和QWERTY鍵盤控制器技術(shù)手冊(cè)

ADP5587移動(dòng)I/O擴(kuò)展器和QWERTY鍵盤控制器技術(shù)手冊(cè)

低功耗Air724UG模組軟件指南:KEYPAD示例~

納祥科技NX1722,一種帶鍵盤掃描的8段4位 LED 驅(qū)動(dòng)控制方案

AN-660:XY矩陣鍵盤與MicroConverter的接口

嵌入式條碼掃描器的幾種掃描模式

點(diǎn)陣數(shù)碼管LED驅(qū)動(dòng)/數(shù)顯LED驅(qū)動(dòng)IC-VK1638 SOP28最大支持8×3按鍵矩陣/10×8點(diǎn)陣

大幅掃描儀掃描地圖怎么操作
MATLAB(6)--特殊矩陣
MATLAB(2)--MATLAB矩陣的表示
MATLAB中的矩陣索引

評(píng)論