要求
在单片机训练平台上,首先将J5处的跳帽接到1、2引脚,使键盘组成4x4的键盘。
在扫描键盘的过程中,发现有按键触发信号后(不做去抖动),在按键松开后,在数码管的第一位显示相应的数字:从左到右,从上到下,依次显示0~F
电路图:
矩阵键盘的原理
思想:逐行逐行的扫描,逐列逐列的读取
如图所示,逐行扫描的时候,只能有一个低电平。第一次扫描,让第一行为低电平,得到行0111,在列得到1111;第二次扫描得到行1011,列1101,说明第二行第三列按下了。以此类推。
代码
要求
按键扫描
/*============按键扫描==============*/
unsigned char key_num;
void ScanKeyMulti()
{
//第一次
R1 = 0;
R2 = R3 = R4 =1;
C1 = C2 = C3 = C4 =1;
if(C1 ==0)
{
while(C1 == 0);
key_num = 0;
DisplayKey(SMG_duanma[key_num]);
}
else if(C2 == 0)
{
while(C2 == 0);
key_num = 1;
DisplayKey(SMG_duanma[key_num]);
}
else if(C3 == 0)
{
while(C3 == 0);
key_num = 2;
DisplayKey(SMG_duanma[key_num]);
}
else if(C4 == 0)
{
while(C4 == 0);
key_num = 3;
DisplayKey(SMG_duanma[key_num]);
}
//第二次
R2 = 0;
R1 = R3 = R4 = 1;
C1 = C2 = C3 = C4 =1;
if(C1 == 0)
{
while(C1 == 0);
key_num = 4;
DisplayKey(SMG_duanma[key_num]);
}
else if(C2 == 0)
{
while(C2 == 0);
key_num = 5;
DisplayKey(SMG_duanma[key_num]);
}
else if(C3 == 0)
{
while(C3 == 0);
key_num = 6;
DisplayKey(SMG_duanma[key_num]);
}
else if(C4 == 0)
{
while(C4 == 0);
key_num = 7;
DisplayKey(SMG_duanma[key_num]);
}
//第三次
R3 = 0;
R2 = R1 = R4 = 1;
C1 = C2 = C3 = C4 =1;
if(C1 == 0)
{
while(C1 == 0);
key_num = 8;
DisplayKey(SMG_duanma[key_num]);
}
else if(C2 == 0)
{
while(C2 == 0);
key_num = 9;
DisplayKey(SMG_duanma[key_num]);
}
else if(C3 == 0)
{
while(C3 == 0);
key_num = 10;
DisplayKey(SMG_duanma[key_num]);
}
else if(C4 == 0)
{
while(C4 == 0);
key_num = 11;
DisplayKey(SMG_duanma[key_num]);
}
//第四次
R4 = 0;
R2 = R3 = R1 = 1;
C1 = C2 = C3 = C4 =1;
if(C1 == 0)
{
while(C1 == 0);
key_num = 12;
DisplayKey(SMG_duanma[key_num]);
}
else if(C2 == 0)
{
while(C2 == 0);
key_num = 13;
DisplayKey(SMG_duanma[key_num]);
}
else if(C3 == 0)
{
while(C3 == 0);
key_num = 14;
DisplayKey(SMG_duanma[key_num]);
}
else if(C4 == 0)
{
while(C4 == 0);
key_num = 15;
DisplayKey(SMG_duanma[key_num]);
}
}
完整代码
#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};
void SelectHC138(unsigned char channel) //通过38译码器对P2口写,控制锁存器
{
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;
}
}
//数码管显示
void DisplayKey(unsigned char value)
{
P0 = 0xff;
SelectHC138(6);
P0 = 0x01; //选择第一个数码管
SelectHC138(7);
P0 = value;
}
/*============按键扫描==============*/
unsigned char key_num;
void ScanKeyMulti()
{
//第一次
R1 = 0;
R2 = R3 = R4 =1;
C1 = C2 = C3 = C4 =1;
if(C1 ==0)
{
while(C1 == 0);
key_num = 0;
DisplayKey(SMG_duanma[key_num]);
}
else if(C2 == 0)
{
while(C2 == 0);
key_num = 1;
DisplayKey(SMG_duanma[key_num]);
}
else if(C3 == 0)
{
while(C3 == 0);
key_num = 2;
DisplayKey(SMG_duanma[key_num]);
}
else if(C4 == 0)
{
while(C4 == 0);
key_num = 3;
DisplayKey(SMG_duanma[key_num]);
}
//第二次
R2 = 0;
R1 = R3 = R4 = 1;
C1 = C2 = C3 = C4 =1;
if(C1 == 0)
{
while(C1 == 0);
key_num = 4;
DisplayKey(SMG_duanma[key_num]);
}
else if(C2 == 0)
{
while(C2 == 0);
key_num = 5;
DisplayKey(SMG_duanma[key_num]);
}
else if(C3 == 0)
{
while(C3 == 0);
key_num = 6;
DisplayKey(SMG_duanma[key_num]);
}
else if(C4 == 0)
{
while(C4 == 0);
key_num = 7;
DisplayKey(SMG_duanma[key_num]);
}
//第三次
R3 = 0;
R2 = R1 = R4 = 1;
C1 = C2 = C3 = C4 =1;
if(C1 == 0)
{
while(C1 == 0);
key_num = 8;
DisplayKey(SMG_duanma[key_num]);
}
else if(C2 == 0)
{
while(C2 == 0);
key_num = 9;
DisplayKey(SMG_duanma[key_num]);
}
else if(C3 == 0)
{
while(C3 == 0);
key_num = 10;
DisplayKey(SMG_duanma[key_num]);
}
else if(C4 == 0)
{
while(C4 == 0);
key_num = 11;
DisplayKey(SMG_duanma[key_num]);
}
//第四次
R4 = 0;
R2 = R3 = R1 = 1;
C1 = C2 = C3 = C4 =1;
if(C1 == 0)
{
while(C1 == 0);
key_num = 12;
DisplayKey(SMG_duanma[key_num]);
}
else if(C2 == 0)
{
while(C2 == 0);
key_num = 13;
DisplayKey(SMG_duanma[key_num]);
}
else if(C3 == 0)
{
while(C3 == 0);
key_num = 14;
DisplayKey(SMG_duanma[key_num]);
}
else if(C4 == 0)
{
while(C4 == 0);
key_num = 15;
DisplayKey(SMG_duanma[key_num]);
}
}
void main()
{
while(1)
{
ScanKeyMulti();
}
}