四、单片机学习——矩阵键盘实验

实验目的:理解并掌握矩阵键盘的工作原理;
实验模块:核心板+矩阵键盘+数码管模块;
实验内容:数码管与矩阵键盘对应显示,即将键盘从左到右,从上到下依次命名
为“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连接

#include "reg51.h"       //包含头文件
sbit LE1=P2^0;           //位选573锁存器使能
sbit LE2=P2^1;           //段选573锁存器使能
#define uchar unsigned char
#define uint  unsigned int
uchar keyValue;          //定义扫描结果参数
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位数码管显示按键值               
      }        
}
原文地址:https://www.cnblogs.com/breads/p/12697367.html