一、原理部分
由上述原理圖可知,當J5接2、3引腳時使用的時使用的是獨立按鍵,接1、2引腳時使用的是矩陣鍵盤。
1、獨立按鍵
這塊闆子有4個獨立按鍵,分别是S4、S5、S6、S7,由P33、P32、P31、P30控制,在使用獨立按鍵時應進行消抖,防止抖動導緻多次觸發。
2、矩陣鍵盤
矩陣鍵盤由P3的8個IO口控制。
通過掃描按鍵來判斷哪個按鍵按下,掃描流程為:
①R1R2R3R4=0111
②檢測C1C2C3C4是否為零,若為零,證明對應按鍵按下,比如檢測到C2為零,則證明S11按下
③R1R2R3R4=1011
④檢測C1C2C3C4是否為零,若為零,證明對應按鍵按下
⑤R1R2R3R4=1101
⑥檢測C1C2C3C4是否為零,若為零,證明對應按鍵按下
⑦R1R2R3R4=1110
⑧檢測C1C2C3C4是否為零,若為零,證明對應按鍵按下
需要注意的是,藍橋杯的闆子P36需要改成P42,P37需要改成P44,但是頭檔案“reg52.h”未定義P4口,因而需要在前面加上:
sfr P4=0xC0;
才可以定義使用P4口。
二、程式案例
1、獨立按鍵
例子:使用獨立按鍵檢測按鍵,當按鍵按下時,對應的LED燈亮起,松開按鍵,LED燈熄滅
#include "reg52.h"
sbit S7=P3^0;//更換端口名字
sbit S6=P3^1;
sbit S5=P3^2;
sbit S4=P3^3;
sbit L1=P0^0;
sbit L2=P0^1;
sbit L3=P0^2;
sbit L4=P0^3;
sbit L5=P0^4;
sbit L6=P0^5;
/*****************************************************************
*@Function: SelectHC573 //
*@Description: 鎖存器選擇 //
*@Input: channel:選擇通道//
*@Output: 無//
*@Return:無 //
*@Others: 無 //
*****************************************************************/
void SelectHC573(unsigned char channel)
{
switch(channel)
{
case 4:
P2=(P2 & 0x1f) |0x80;
break;
case 5:
P2=(P2 & 0x1f) |0xa0;
break;
case 6:
P2=(P2 & 0x1f) |0xc0;
break;
case 7:
P2=(P2 & 0x1f) |0xe0;
break;
}
}
/*****************************************************************
*@Function: Initializ //
*@Description: 關閉蜂鳴器,繼電器以及LED燈 //
*@Input:無 //
*@Output: 無//
*@Return: 無 //
*@Others: 無 //
/*****************************************************************/
void Initializ()
{
SelectHC573(5);
P0=0x00;
SelectHC573(4);
P0=0xff;
}
/*****************************************************************
*@Function: DelayKey//
*@Description: 用于按鍵消抖 //
*@Input:無 //
*@Output: 無//
*@Return: 無 //
*@Others: 無 //
/*****************************************************************/
void DelayKey(unsigned char t)
{
while(t--);
}
///*****************************************************************
*@Function: ScanKeys_Alone //
*@Description: 掃描按鍵S7S6S5S4,檢測到當按鍵按下開啟對應LED燈,松開關閉燈 //
*@Input: 無//
*@Output: 無//
*@Return: 無 //
*@Others:無 //
/*****************************************************************/
void ScanKeys_Alone()
{
if(S7==0)
{
DelayKey(100);//延時、進行消抖
if(S7==0)
{
L1=0;
while(S7==0);
L1=1;
}
}
if(S6==0)
{
DelayKey(100);
if(S6==0)
{
L2=0;
while(S6==0);
L2=1;
}
}
if(S5==0)
{
DelayKey(100);
if(S5==0)
{
L3=0;
while(S5==0);
L3=1;
}
}
if(S4==0)
{
DelayKey(100);
if(S4==0)
{
L4=0;
while(S4==0);
L4=1;
}
}
}
void main()
{
Initializ();//初始化關閉繼電器蜂鳴器以及LED燈
while(1)
{
ScanKeys_Alone();//放進主循環進行掃描
}
}
2、矩陣鍵盤
例子:按下矩陣鍵盤某個鍵,使用數位管顯示相應數字
#include "reg52.h"
sfr P4=0xC0;//定義P4口
sbit R1=P3^0;
sbit R2=P3^1;
sbit R3=P3^2;
sbit R4=P3^3;
sbit C4=P3^4;
sbit C3=P3^5;
sbit C2=P4^2;
sbit C1=P4^4;
unsigned char code SMG_duanma[18]=
{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,
0x90,0x88,0x80,0xc6,0xc0,0x86,0x8e,0xbf,0x7f};//數位管段碼表
/*****************************************************************
*@Function: SelectHc573 //
*@Description: 選擇鎖存器 //
*@Input:channel:選擇通道 //
*@Output: 無//
*@Return: 無 //
*@Others: 無 //
/*****************************************************************/
void SelectHc573(unsigned char channel)
{
switch(channel)
{
case 4:
P2=P2&0x1f|0x80;
break;
case 5:
P2=P2&0x1f|0xa0;
break;
case 6:
P2=P2&0x1f|0xc0;
break;
case 7:
P2=P2&0x1f|0xe0;
break;
}
}
/*****************************************************************
*@Function: DisplayKeyNum //
*@Description: 在第七個數位管顯示Value //
*@Input: value:數位管顯示的值//
*@Output: 無//
*@Return: 無 //
*@Others: 無 //
/*****************************************************************/
void DisplayKeyNum(unsigned char value)
{
SelectHc573(6);
P0=0x01;
SelectHc573(7);
P0=value;
}
unsigned int Key_Num;//記錄數位管顯示數字
/*****************************************************************
*@Function: ScanKeyMulti //
*@Description: 掃描矩陣鍵盤 //
*@Input: 無//
*@Output: 無//
*@Return: 無 //
*@Others: 無 //
/*****************************************************************/
void ScanKeyMulti()
{
//對應流程①②
R1=0;
R2=R3=R4=1;
C1=C2=C3=C4=1;
if(C1==0)
{
while(C1==0);
Key_Num=0;
DisplayKeyNum(SMG_duanma[Key_Num]);
}
else if(C2==0)
{
while(C2==0);
Key_Num=1;
DisplayKeyNum(SMG_duanma[Key_Num]);
}
else if(C3==0)
{
while(C3==0);
Key_Num=2;
DisplayKeyNum(SMG_duanma[Key_Num]);
}
else if(C4==0)
{
while(C4==0);
Key_Num=3;
DisplayKeyNum(SMG_duanma[Key_Num]);
}
//對應流程③④
R2=0;
R1=R3=R4=1;
C1=C2=C3=C4=1;
if(C1==0)
{
while(C1==0);
Key_Num=4;
DisplayKeyNum(SMG_duanma[Key_Num]);
}
else if(C2==0)
{
while(C2==0);
Key_Num=5;
DisplayKeyNum(SMG_duanma[Key_Num]);
}
else if(C3==0)
{
while(C3==0);
Key_Num=6;
DisplayKeyNum(SMG_duanma[Key_Num]);
}
else if(C4==0)
{
while(C4==0);
Key_Num=7;
DisplayKeyNum(SMG_duanma[Key_Num]);
}
//對應流程⑤⑥
R3=0;
R2=R1=R4=1;
C1=C2=C3=C4=1;
if(C1==0)
{
while(C1==0);
Key_Num=8;
DisplayKeyNum(SMG_duanma[Key_Num]);
}
else if(C2==0)
{
while(C2==0);
Key_Num=9;
DisplayKeyNum(SMG_duanma[Key_Num]);
}
else if(C3==0)
{
while(C3==0);
Key_Num=10;
DisplayKeyNum(SMG_duanma[Key_Num]);
}
else if(C4==0)
{
while(C4==0);
Key_Num=11;
DisplayKeyNum(SMG_duanma[Key_Num]);
}
//對應流程⑦⑧
R4=0;
R2=R3=R1=1;
C1=C2=C3=C4=1;
if(C1==0)
{
while(C1==0);
Key_Num=12;
DisplayKeyNum(SMG_duanma[Key_Num]);
}
else if(C2==0)
{
while(C2==0);
Key_Num=13;
DisplayKeyNum(SMG_duanma[Key_Num]);
}
else if(C3==0)
{
while(C3==0);
Key_Num=14;
DisplayKeyNum(SMG_duanma[Key_Num]);
}
else if(C4==0)
{
while(C4==0);
Key_Num=15;
DisplayKeyNum(SMG_duanma[Key_Num]);
}
}
void main()
{
while(1)
{
ScanKeyMulti();//放進主循環不斷掃面矩陣鍵盤
}
}
轉眼間已經2023年了
祝大家新年快樂吖~
感謝大家的觀看
歡迎大家提出問題并指正~