实验目的:理解并掌握矩阵键盘的工作原理;
实验模块:核心板+矩阵键盘+数码管模块;
实验内容:数码管与矩阵键盘对应显示,即将键盘从左到右,从上到下依次命名
为“0--F”;
拓展任务:数码管与按键对应显示,做乘法显示;
模块连接图:
电路原理图:
矩阵键盘工作原理:在矩阵式键盘中,每条水平线和垂直线在交叉处不直
接连通,而是通过一个按键加以连接。这样,一个端口(如 P3 口)就可以构成
4*4=16 个按键,比之直接将端口线用于键盘多出了一倍,而且线数越多,区别
越明显,比如再多加一条线就可以构成 20 键的键盘,而直接用端口线则只能多
出一键(9 键)。由此可见,在需要的键数比较多时,采用矩阵法来做键盘是合理
的。矩阵键盘通常通过以下来确定被按下按键的位置。
第一种方法为行扫描法:
首先判断键盘中有无键按下 将全部行线 H0-H3 置低电平,然后检测列线
L0-L3 的状态。只要有一列的电平为低,则表示键盘中有键被按下,而且闭合的
键位于低电平线与 4 根行线相交叉的 4 个按键之中。若所有列线均为高电平,则
键盘中无键按下;接着,判断闭合键所在的位置 在确认有键按下后,即可进入
确定具体闭合键的过程。其方法是:依次将行线置为低电平,即在置某根行线为
低电平时,其它线为高电平。在确定某根行线位置为低电平后,再逐行检测各列
线的电平状态。若某列为低,则该列线与置为低电平的行线交叉处的按键就是闭
合的按键。
第二种方法为高低电平翻转法:
首先让 P1 口高四位为 1,低四位为 0,。若有按键按下,则高四位中会有一
个 1 翻转为 0,低四位不会变,此时即可确定被按下的键的行位置;然后让 P1
口高四位为 0,低四位为 1,。若有按键按下,则低四位中会有一个 1 翻转为 0,
高四位不会变,此时即可确定被按下的键的列位置。
功能描述: 用反转法实现矩阵键盘扫描,数码管显示4x4键盘扫描的结果
硬件连接: 用8位杜邦线将J8与J12连接,用2位杜邦线分别将J11_0与J15_DS1及J11_1与J15_DS2连接,用8位杜邦线将J9与J6连接
sbit LE2=P2^1; //段选573锁存器使能
#define uint unsigned int
uchar code dis[16]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,
// 0 1 2 3 4 5 6 7
0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71}; //0~F的段码
// 8 9 A B C D E F
uchar temp;
//**************************************************************************************************
//延时函数
//**************************************************************************************************
delay(uint time) //int型数据为16位,所以最大值为65535
{
uint i,j; //定义变量i,j,用于循环语句
for(i=0;i<time;i++) //for循环,循环50*time次
for(j=0;j<50;j++); //for循环,循环50次
}
//**************************************************************************************************
//矩阵键盘扫描函数
//**************************************************************************************************
keyScan()
{
uchar x,y;
P3=0xf0; //P3赋值0xf0
if((P3&0xf0)!=0xf0) //判断高4位是否为全1(高4位全1代表没按键按下)
delay(20); //延时去抖动,一般为5ms~10ms(由于机械触点的弹性作用,按键在闭合时不会马上稳定地接通,
//而在闭合瞬间伴随有一连串的抖动,键抖动会引起一次按键被误读多次)
if((P3&0xf0)!=0xf0) //如果还能检测到有键盘按下去
{
x=P3&0xf0; //读取P3口数据
P3=0x0f; //反转,P3赋值0x0f
y=P3&0x0f; //读取P3口数据
keyValue=x|y; //得到扫描结果
}
}
}
//**************************************************************************************************
//矩阵键盘扫描结果处理函数
//**************************************************************************************************
uchar keyHandle(uchar value)
{
switch(value)
{
case 0xee:{return(0);break;} //对应按键S1
case 0xde:{return(1);break;} //对应按键S2
case 0xbe:{return(2);break;} //对应按键S3
case 0x7e:{return(3);break;} //对应按键S4
case 0xed:{return(4);break;} //对应按键S5
case 0xdd:{return(5);break;} //对应按键S6
case 0xbd:{return(6);break;} //对应按键S7
case 0x7d:{return(7);break;} //对应按键S8
case 0xeb:{return(8);break;} //对应按键S9
case 0xdb:{return(9);break;} //对应按键S10
case 0xbb:{return(10);break;} //对应按键S11
case 0x7b:{return(11);break;} //对应按键S12
case 0xe7:{return(12);break;} //对应按键S13
case 0xd7:{return(13);break;} //对应按键S14
case 0xb7:{return(14);break;} //对应按键S15
case 0x77:{return(15);break;} //对应按键S16
default:{break;}
}
}
//**************************************************************************************************
//显示扫描结果函数
//**************************************************************************************************
show()
{
P1=0x00; //0x00=0000 0000,即选通数码全8位
LE1=1; //锁存位
LE1=0; //断开锁存,位选573的Q7~Q0仍为0x00
P1=dis[temp]; //0~F的编码
LE2=1; //锁存段码
LE2=0; //断开锁存,段选573的Q7~Q0仍为dis[temp]
}
//主函数
//**************************************************************************************************
void main() //主函数
{
while(1) //进入while死循环
{
keyScan(); //按键扫描
temp=keyHandle(keyValue); //处理扫描结果
show(); //8位数码管显示按键值
}
}