矩阵键盘
一、原理图分析
红色为列,4x4=16个按键,4+4=8个IO口,4条I/O行线,4条I/O列线。
二、矩阵键盘扫描方式
矩阵键盘扫描的方式有两种: 1.行列扫描;2.逐行/逐列扫描
1.逐行/逐列扫描
寻找哪一按键按下
令第i行为低电平,其余行为高电平,逐个去看第i行的每一列是否出现0
#include <STC15F2K60S2.H>
unsigned char code SMG_duanma[18]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x80,0xc6,0xc0,0x86,0x8e,0xbf,0x7f};//有小数点
void HC138(unsigned int n)
{
switch(n)
{
case 4:
P2=P2&0x1f|0x80;//LED
break;
case 5:
P2=P2&0x1f|0xa0;//蜂鸣器和继电器
break;
case 6:
P2=P2&0x1f|0xc0;//数码管位置
break;
case 7:
P2=P2&0x1f|0xe0;//数码管数字
break;
}
}
void Delay(unsigned int x)
{
while(x--);
}
void SMG(unsigned char value)
{
HC138(6);//打开数码管位置对应的573
P0=0x01;
HC138(7);//打开数码管数字对应的573
P0=value;
}
void JuZhen()
{
P30=0;
P31=P32=P33=1;//令第i行为低电平,其余行为高电平,逐个去看第i行的每一列是否出现0
P44=P42=P35=P34=1;
if(P44==0)
{
Delay(100);
if(P44==0)
{
SMG(SMG_duanma[0]);
while(P44==0);
}
}
else if(P42==0)
{
Delay(100);
if(P42==0)
{
SMG(SMG_duanma[1]);
while(P42==0);
}
}
else if(P35==0)
{
Delay(100);
if(P35==0)
{
SMG(SMG_duanma[2]);
while(P35==0);
}
}
else if(P34==0)
{
Delay(100);
if(P34==0)
{
SMG(SMG_duanma[3]);
while(P34==0);
}
}
else
{
P31=0;
P30=P32=P33=1;//令第i行为低电平,其余行为高电平,逐个去看第i行的每一列是否出现0
P44=P42=P35=P34=1;
if(P44==0)
{
Delay(100);
if(P44==0)
{
SMG(SMG_duanma[4]);
while(P44==0);
}
}
else if(P42==0)
{
Delay(100);
if(P42==0)
{
SMG(SMG_duanma[5]);
while(P42==0);
}
}
else if(P35==0)
{
Delay(100);
if(P35==0)
{
SMG(SMG_duanma[6]);
while(P35==0);
}
}
else if(P34==0)
{
Delay(100);
if(P34==0)
{
SMG(SMG_duanma[7]);
while(P34==0);
}
}
else
{
P32=0;
P30=P31=P33=1;//令第i行为低电平,其余行为高电平,逐个去看第i行的每一列是否出现0
P44=P42=P35=P34=1;
if(P44==0)
{
Delay(100);
if(P44==0)
{
SMG(SMG_duanma[8]);
while(P44==0);
}
}
else if(P42==0)
{
Delay(100);
if(P42==0)
{
SMG(SMG_duanma[9]);
while(P42==0);
}
}
else if(P35==0)
{
Delay(100);
if(P35==0)
{
SMG(SMG_duanma[10]);
while(P35==0);
}
}
else if(P34==0)
{
Delay(100);
if(P34==0)
{
SMG(SMG_duanma[11]);
while(P34==0);
}
}
else
{
P33=0;
P30=P32=P31=1;//令第i行为低电平,其余行为高电平,逐个去看第i行的每一列是否出现0
P44=P42=P35=P34=1;
if(P44==0)
{
Delay(100);
if(P44==0)
{
SMG(SMG_duanma[12]);
while(P44==0);
}
}
else if(P42==0)
{
Delay(100);
if(P42==0)
{
SMG(SMG_duanma[13]);
while(P42==0);
}
}
else if(P35==0)
{
Delay(100);
if(P35==0)
{
SMG(SMG_duanma[14]);
while(P35==0);
}
}
else if(P34==0)
{
Delay(100);
if(P34==0)
{
SMG(SMG_duanma[15]);
while(P34==0);
}
}
}
}
}
}
void main()
{
while(1)
{
JuZhen();
}
}
2、更简便的写法
#include <STC15F2K60S2.H>
unsigned char code SMG_duanma[18]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x80,0xc6,0xc0,0x86,0x8e,0xbf,0x7f};//有小数点
void HC138(unsigned int n)
{
switch(n)
{
case 4:
P2=P2&0x1f|0x80;//LED
break;
case 5:
P2=P2&0x1f|0xa0;//蜂鸣器和继电器
break;
case 6:
P2=P2&0x1f|0xc0;//数码管位置
break;
case 7:
P2=P2&0x1f|0xe0;//数码管数字
break;
}
}
/*声明变量*/
unsigned char Key_Val,Key_Down,Key_Up,Key_Old;
/*读取按键*/
unsigned char Key_Read()
{
unsigned char temp=0;
P30=0;P31=P32=P33=1;//令第1行为低电平,其余行为高电平,逐个去看第1行的每一列是否出现0
if(P44==0)temp=1;
if(P42==0)temp=2;
if(P35==0)temp=3;
if(P34==0)temp=4;
P31=0;P30=P32=P33=1;//令第2行为低电平,其余行为高电平,逐个去看第2行的每一列是否出现0
if(P44==0)temp=5;
if(P42==0)temp=6;
if(P35==0)temp=7;
if(P34==0)temp=8;
P32=0;P31=P30=P33=1;//令第3行为低电平,其余行为高电平,逐个去看第3行的每一列是否出现0
if(P44==0)temp=9;
if(P42==0)temp=10;
if(P35==0)temp=11;
if(P34==0)temp=12;
P33=0;P31=P32=P30=1;//令第4行为低电平,其余行为高电平,逐个去看第4行的每一列是否出现0
if(P44==0)temp=13;
if(P42==0)temp=14;
if(P35==0)temp=15;
if(P34==0)temp=16;
return temp;
}
void SMG(unsigned char value)
{
HC138(6);//打开数码管位置对应的573
P0=0x01;
HC138(7);//打开数码管数字对应的573
P0=value;
}
void M()
{
if(Key_Down==1)SMG(SMG_duanma[0]);
if(Key_Down==2)SMG(SMG_duanma[1]);
if(Key_Down==3)SMG(SMG_duanma[2]);
if(Key_Down==4)SMG(SMG_duanma[3]);
if(Key_Down==5)SMG(SMG_duanma[4]);
if(Key_Down==6)SMG(SMG_duanma[5]);
if(Key_Down==7)SMG(SMG_duanma[6]);
if(Key_Down==8)SMG(SMG_duanma[7]);
if(Key_Down==9)SMG(SMG_duanma[8]);
if(Key_Down==10)SMG(SMG_duanma[9]);
if(Key_Down==11)SMG(SMG_duanma[10]);
if(Key_Down==12)SMG(SMG_duanma[11]);
if(Key_Down==13)SMG(SMG_duanma[12]);
if(Key_Down==14)SMG(SMG_duanma[13]);
if(Key_Down==15)SMG(SMG_duanma[14]);
if(Key_Down==16)SMG(SMG_duanma[15]);
}
void main()
{
HC138(4);
while(1)
{
Key_Val=Key_Read();
Key_Down=Key_Val&(Key_Val^Key_Old);
Key_Up=~Key_Val&(Key_Val^Key_Old);
Key_Old=Key_Val;
M();
}
}