一、先前知識
使用到的74HC138譯碼器、74HC573鎖存器和數(shù)碼管模塊等,在前面的基礎(chǔ)模塊的介紹中都有簡單介紹,這里就不再介紹了。
按鍵之矩陣鍵盤模塊
藍橋杯板子上按鍵部分的右下角有個J5模塊,用跳帽來進行獨立按鍵和矩陣鍵盤之間的切換。此次使用矩陣鍵盤的時候需要把跳帽接到1~2引腳。
矩陣鍵盤就是4×4,一共16個按鍵。其工作原理是,用跳帽將四行按鍵的左邊都與單片機的引腳相連,那么電平就為單片機引腳輸出電平。按鍵在沒有按下的時候按鍵下方的兩個觸點是沒有接在一起的,也就是說原理圖上按鍵的左邊腳始終是與單片機引腳輸出的電平相同。當(dāng)按鍵按下,按鍵下方的金屬墊片接觸時,兩個觸點接通,那么按鍵右邊的腳(也是單片機其他的引腳)就會檢測到與按鍵左邊引腳相同的電平。就是依據(jù)此特征來判斷按鍵是否被按下。
我們看到藍橋杯板子上的按鍵是有四個腳的,而上篇文章中的獨立按鍵和此次的矩陣鍵盤,似乎都只用到了兩個腳,那么是不是錯誤的呢?
其實不是,按鍵雖然有四個端口,但是按鍵內(nèi)部有兩個腳是短接的,另外兩個腳是引出腳,一個作為輸入,一個作為輸出。

圖一、按鍵模塊
部分代碼解釋
就第一行按鍵部分的代碼而言(其他行按鍵的代碼類似):
在矩陣鍵盤中要判斷哪一個按鍵按下需要用到掃描的思想,從上到下依次給每一行低電平,當(dāng)某一列檢測到低電平的時候,就可以用坐標(biāo)的思想,找到是哪一個按鍵被按下。一次只能把一行給低電平,掃哪一行哪一行就是低電平。
? ? R1 = 0;? ? ? ? ? ? ? ? // 先檢測第一行按鍵是否被按下,那么就給第一行低電平
R2 = R3 = R4 = 1;? ? ? // 其他行給高電平
C1 = C2 = C3 = C4 = 1;?// 先初始化默認每一列的按鍵都沒有被按下
if( C1 == 0 ) // 第一行第一列被按下,S7
{
while( C1 == 0 );
Key_Num = 7;
}
else if( C2 == 0 ) // 第一行第二列被按下,S11
{
while( C2 == 0 );
Key_Num = 11;
}
else if( C3 == 0 ) // 第一行第三列被按下,S15
{
while( C3 == 0 );
Key_Num = 15;
}
else if( C4 == 0 ) // 第一行第四列被按下,S19
{
while( C4 == 0 );
Key_Num = 19;
}
二、模塊控制實現(xiàn)過程簡述
先把按鍵的跳帽接到1~2引腳上,然后定義輸出行和輸入行,再用掃描的方法控制矩陣鍵盤。
三、所要實現(xiàn)的功能
首先上電之后數(shù)碼管的后兩位顯示00,然后根據(jù)板子上矩陣鍵盤的每個按鍵的名稱,當(dāng)按鍵被按下后在數(shù)碼管上顯示相應(yīng)的數(shù)字。(也就是如果某個按鍵上標(biāo)的數(shù)是S07,那么該按鍵按下后數(shù)碼管的后兩位就顯示07,如果某個按鍵上標(biāo)的數(shù)是S16,那么該按鍵按下后數(shù)碼管的后兩位就顯示16)程序循環(huán)實現(xiàn)上述功能。
四、代碼實現(xiàn)
①引腳以及參數(shù)定義
// 矩陣鍵盤定義輸入行
sbit R1 = P3^0;
sbit R2 = P3^1;
sbit R3 = P3^2;
sbit R4 = P3^3;
// 矩陣鍵盤定義輸出列
sbit C1 = P4^4;
sbit C2 = P4^2;
sbit C3 = P3^5;
sbit C4 = P3^4;
// 參數(shù)定義
unsigned char Key_Num; // 按鍵角標(biāo)
②數(shù)碼管段碼
// 數(shù)碼管段碼
unsigned char code SMG_Duanma[18] =
{
0xc0 , 0xf9 , 0xa4 , 0xb0 , 0x99 , 0x92 , 0x82 , 0xf8 , 0x80 ,
0x90 , 0x88 , 0x80 , 0xc6 , 0xc0 , 0x86 , 0x8e , 0xbf , 0x7f
}; // 0~F - .
③138譯碼器通道選擇函數(shù)
// 通道選擇
void HC138_Init( unsigned char channel )
{
switch( channel )
{
case 0:
P2 = (P2 & 0x1f) | 0x00; // 0
break;
case 4:
P2 = (P2 & 0x1f) | 0x80; // Y4C
break;
case 5:
P2 = (P2 & 0x1f) | 0xa0; // Y5C
break;
case 6:
P2 = (P2 & 0x1f) | 0xc0; // Y6C
break;
case 7:
P2 = (P2 & 0x1f) | 0xe0; // Y7C
break;
}
}
④初始化系統(tǒng)-關(guān)閉目前不需要的蜂鳴器和繼電器
// 初始化系統(tǒng)
void Init_System(void)
{
// 關(guān)閉LED燈
HC138_Init( 4 );
P0 = 0xff
// 關(guān)閉蜂鳴器和繼電器
HC138_Init( 5 );
P0 = 0xaf; // 1010 1111
HC138_Init( 0 ); // 關(guān)閉通道選擇
}
⑤單個數(shù)碼管點亮函數(shù)
// 單個數(shù)碼管點亮
void SMG_Light( unsigned char pos , unsigned char dat )
{
HC138_Init( 6 );
P0 = 0x01 << pos; // 某個數(shù)碼管處于準(zhǔn)備階段
HC138_Init( 7 );
P0 = dat; // 顯示數(shù)值
}
⑥數(shù)碼管顯示函數(shù)
// 數(shù)碼管顯示
void SMG_Show( unsigned char num )
{
SMG_Light( 0 , 0xff );? ? // 不用的數(shù)碼管就關(guān)閉
Delay_tms( 10 );
SMG_Light( 1 , 0xff );
Delay_tms( 10 );
SMG_Light( 2 , 0xff );
Delay_tms( 10 );
SMG_Light( 3 , 0xff );
Delay_tms( 10 );
SMG_Light( 4 , 0xff );
Delay_tms( 10 );
SMG_Light( 5 , 0xff );
Delay_tms( 10 );
SMG_Light( 6 , SMG_Duanma[ num / 10 ] );
Delay_tms( 10 );
SMG_Light( 7 , SMG_Duanma[ num % 10 ] );
Delay_tms( 10 );
}
⑦按鍵掃描函數(shù)
// 按鍵掃描
void Key_Scan(void)
{
// 第一行
R1 = 0;
R2 = R3 = R4 = 1;
C1 = C2 = C3 = C4 = 1;
if( C1 == 0 ) // S7
{
while( C1 == 0 );
Key_Num = 7;
}
else if( C2 == 0 ) // S11
{
while( C2 == 0 );
Key_Num = 11;
}
else if( C3 == 0 ) // S15
{
while( C3 == 0 );
Key_Num = 15;
}
else if( C4 == 0 ) // S19
{
while( C4 == 0 );
Key_Num = 19;
}
// 第二行
R2 = 0;
R1 = R3 = R4 = 1;
C1 = C2 = C3 = C4 = 1;
if( C1 == 0 ) // S6
{
while( C1 == 0 );
Key_Num = 6;
}
else if( C2 == 0 ) // S10
{
while( C2 == 0 );
Key_Num = 10;
}
else if( C3 == 0 ) // S14
{
while( C3 == 0 );
Key_Num = 14;
}
else if( C4 == 0 ) // S18
{
while( C4 == 0 );
Key_Num = 18;
}
// 第三行
R3 = 0;
R2 = R1 = R4 = 1;
C1 = C2 = C3 = C4 = 1;
if( C1 == 0 ) // S5
{
while( C1 == 0 );
Key_Num = 5;
}
else if( C2 == 0 ) // S9
{
while( C2 == 0 );
Key_Num = 9;
}
else if( C3 == 0 ) // S13
{
while( C3 == 0 );
Key_Num = 13;
}
else if( C4 == 0 ) // S17
{
while( C4 == 0 );
Key_Num = 17;
}
// 第四行
R4 = 0;
R2 = R3 = R1 = 1;
C1 = C2 = C3 = C4 = 1;
if( C1 == 0 ) // S4
{
while( C1 == 0 );
Key_Num = 4;
}
else if( C2 == 0 ) // S8
{
while( C2 == 0 );
Key_Num = 8;
}
else if( C3 == 0 ) // S12
{
while( C3 == 0 );
Key_Num = 12;
}
else if( C4 == 0 ) // S16
{
while( C4 == 0 );
Key_Num = 16;
}
}
⑧延時函數(shù)文章來源:http://www.zghlxwxcb.cn/news/detail-775463.html
void Delay_tms( unsigned int t )
{
int i;
while( t-- )
{
for( i=115 ; i>0 ; i-- )
{
}
}
}
⑨整個函數(shù)展示文章來源地址http://www.zghlxwxcb.cn/news/detail-775463.html
#include <STC15F2K60S2.H>
#include "Delay_ms.h"
// 矩陣鍵盤定義輸入行
sbit R1 = P3^0;
sbit R2 = P3^1;
sbit R3 = P3^2;
sbit R4 = P3^3;
// 矩陣鍵盤定義輸出列
sbit C1 = P4^4;
sbit C2 = P4^2;
sbit C3 = P3^5;
sbit C4 = P3^4;
// 參數(shù)定義
unsigned char Key_Num; // 按鍵角標(biāo)
// 數(shù)碼管段碼
unsigned char code SMG_Duanma[18] =
{
0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,
0x90,0x88,0x80,0xc6,0xc0,0x86,0x8e,0xbf,0x7f
}; // 0~F - .
// 通道選擇
void HC138_Init( unsigned char channel )
{
switch( channel )
{
case 0:
P2 = (P2 & 0x1f) | 0x00; // 0
break;
case 4:
P2 = (P2 & 0x1f) | 0x80; // Y4C
break;
case 5:
P2 = (P2 & 0x1f) | 0xa0; // Y5C
break;
case 6:
P2 = (P2 & 0x1f) | 0xc0; // Y6C
break;
case 7:
P2 = (P2 & 0x1f) | 0xe0; // Y7C
break;
}
}
// 初始化系統(tǒng)
void Init_System(void)
{
// 關(guān)閉LED燈
HC138_Init( 4 );
P0 = 0xff
// 關(guān)閉蜂鳴器和繼電器
? ? HC138_Init( 5 );
P0 = 0xaf; // 1010 1111
HC138_Init( 0 ); // 關(guān)閉通道選擇
}
// 單個數(shù)碼管點亮
void SMG_Light( unsigned char pos , unsigned char dat )
{
HC138_Init( 6 );
P0 = 0x01 << pos; // 某個數(shù)碼管處于準(zhǔn)備階段
HC138_Init( 7 );
P0 = dat; // 顯示數(shù)值
}
// 數(shù)碼管顯示
void SMG_Show( unsigned char num )
{
SMG_Light( 0 , 0xff );
Delay_tms( 10 );
SMG_Light( 1 , 0xff );
Delay_tms( 10 );
SMG_Light( 2 , 0xff );
Delay_tms( 10 );
SMG_Light( 3 , 0xff );
Delay_tms( 10 );
SMG_Light( 4 , 0xff );
Delay_tms( 10 );
SMG_Light( 5 , 0xff );
Delay_tms( 10 );
SMG_Light( 6 , SMG_Duanma[ num / 10 ] );
Delay_tms( 10 );
SMG_Light( 7 , SMG_Duanma[ num % 10 ] );
Delay_tms( 10 );
}
// 按鍵掃描
void Key_Scan(void)
{
? ? // 第一行
R1 = 0;
R2 = R3 = R4 = 1;
C1 = C2 = C3 = C4 = 1;
if( C1 == 0 ) // S7
{
while( C1 == 0 );
Key_Num = 7;
}
else if( C2 == 0 ) // S11
{
while( C2 == 0 );
Key_Num = 11;
}
else if( C3 == 0 ) // S15
{
while( C3 == 0 );
Key_Num = 15;
}
else if( C4 == 0 ) // S19
{
while( C4 == 0 );
Key_Num = 19;
}
? ? // 第二行
R2 = 0;
R1 = R3 = R4 = 1;
C1 = C2 = C3 = C4 = 1;
if( C1 == 0 ) // S6
{
while( C1 == 0 );
Key_Num = 6;
}
else if( C2 == 0 ) // S10
{
while( C2 == 0 );
Key_Num = 10;
}
else if( C3 == 0 ) // S14
{
while( C3 == 0 );
Key_Num = 14;
}
else if( C4 == 0 ) // S18
{
while( C4 == 0 );
Key_Num = 18;
}
? ? // 第三行
R3 = 0;
R2 = R1 = R4 = 1;
C1 = C2 = C3 = C4 = 1;
if( C1 == 0 ) // S5
{
while( C1 == 0 );
Key_Num = 5;
}
else if( C2 == 0 ) // S9
{
while( C2 == 0 );
Key_Num = 9;
}
else if( C3 == 0 ) // S13
{
while( C3 == 0 );
Key_Num = 13;
}
else if( C4 == 0 ) // S17
{
while( C4 == 0 );
Key_Num = 17;
}
? ? // 第四行
R4 = 0;
R2 = R3 = R1 = 1;
C1 = C2 = C3 = C4 = 1;
if( C1 == 0 ) // S4
{
while( C1 == 0 );
Key_Num = 4;
}
else if( C2 == 0 ) // S8
{
while( C2 == 0 );
Key_Num = 8;
}
else if( C3 == 0 ) // S12
{
while( C3 == 0 );
Key_Num = 12;
}
else if( C4 == 0 ) // S16
{
while( C4 == 0 );
Key_Num = 16;
}
}
int main(void)
{
Init_System(); // 初始化系統(tǒng)
while(1)
{
Key_Scan(); // 按鍵掃描
SMG_Show( Key_Num ); // 數(shù)碼管顯示
}
}
五、運行圖片

到了這里,關(guān)于藍橋杯單片機開發(fā)及應(yīng)用-基礎(chǔ)模塊06-矩陣鍵盤的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!