51单片机外设之——矩阵键盘(传统法一)

来源:互联网 发布:驾驶员网络培训 编辑:程序博客网 时间:2024/05/30 22:42

前面提到了独立按键,可见,独立按键是由矩阵键盘分离而来的。接下来看的是 4*4 的矩阵键盘,这里使用的还是上节所使用的,延时消抖检测。 
先附上矩阵键盘的原理图: 
这里写图片描述 
在使用据矩阵键盘时,J5 排针处的跳帽连接 1 脚和 2 脚,使所有按键的有效端口全部连接至 I/O 口。 
具体的扫描方式为: 
先把P3^0~P3^7高四位和低四位赋不一样的电平值,当确定有键按下时,检测按下的是哪一行或哪一列(原本高电平的四位中有一位会变低电平),再将高四位和低四位赋与上一次相反的电平。再检测,即可找到所按下的按键。

实例为:把S4~S19 这16个按键,从上到下、从左至右,分别设置为1~16不同的键值,当S4按下时,数码管显示为 1;当S19按下时,数码管显示为16。 
其核心代码如下(数码管段码,显示函数等变量的定义,请参照前面给出的数码管的博文):

uchar temp;                                         //用于存储 P3 口的状态uchar key_value = 0;                                //键值的定义void matrixKeyScan(){    P3 = 0x0f;                                      //设置P3高四位为0,第四位为1    temp = P3;                                      //用一个变量存储P3口的状态,以免外界影响P3口,从而造成扫描有误    if(temp != 0x0f)    {        delay10ms();        if(temp!= 0x0f)                             //确定有键按下        {                   switch(temp)                            //查看P3(temp)的状态            {                case 0x0e :key_value = 1; break;    //按下的为第一行                case 0x0d :key_value = 5; break;                    case 0x0b :key_value = 9; break;                    case 0x07 :key_value = 13;break;    //按下的为第四行            }           }           P3 = 0xf0;                                  //再将 P3 口重新赋值,高四位为1,第四位为0        temp = P3;        if(temp != 0xf0)        {            switch(temp)            {                case 0xe0 : key_value +=3 ; break;   //按下的是第四列,键值key_value加3                case 0xd0 : key_value +=2 ; break;                case 0xb0 : key_value +=1 ; break;                case 0x70 : key_value +=0 ; break;   //按下的是第一列,键值key_value加0            }        }        while(P3 != 0xf0);                           //松手检测,因为最近的一次赋值是P3 = 0xf0    }}void main(){    while(1)    {        matrixKeyScan();                             //在主函数中调用矩阵键盘扫描函数        if(key_value > 9)                            //判断键值,并显示        {             dspbuf[1] = key_value%10;              dspbuf[0] = key_value/10;        }        else        {            dspbuf[0] = key_value;            dspbuf[1] = 10;                           //若键值小于10,则十位不显示,只显示个位,段码数组第10个为消影        }         display();                                    //数码管显示函数    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53

注:在此我们基于的是89C52单片机的按键扫描,但是对于蓝桥杯指定开发板平台(CT107D)所用的单片机为STC15F2K61S2,它与STC89C52在矩阵键盘的区别的是:前者没有P3^6和P3^7这两个 I/O 口,他们分别用P4^2,P4^4代替,具体的可以就参照STC15F2K61S2芯片手册(其他的区别大致有:它的运行速度比51单片机快,工作时可以选择是否分频;它的中断模式比51多,一些 I/O 口有其他功能等等……)。

这里有几点需要注意: 
1、在编程时,主函数尽可能少的进行一些数据处理等操作,主函数主要用来调用其他的函数。 
2、若使用的是STC15F2K61S2单片机,则在给 P3 口的两次赋值和高四位的电平检测阶段,需要将P4^2,P4^4单独列出来,与其余6个P3引脚的 I/O 口一起检测,并且在使用P4^2,P4^4之前,需要进行sbit位定义,以及 P4 引脚的寻址(srf P4 = 0xC0)。 
3、P3口的第二次赋值,应该也囊括在第一个 if 语句之中,因为只有当确定按下之后,才会开始行与列的扫描,行、列扫描是对于一次按键的扫描,所以不可分开。

未完待续……