一、原理部分
由上述原理图可知,当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年了
祝大家新年快乐吖~
感谢大家的观看
欢迎大家提出问题并指正~