注册 登录
电子工程世界-论坛 返回首页 EEWORLD首页 频道 EE大学堂 下载中心 Datasheet 专题
jeansbo114的个人空间 https://home.eeworld.com.cn/space-uid-471383.html [收藏] [复制] [分享] [RSS]
日志

基于proteus的51单片机仿真实例-4X4矩阵键盘

已有 961 次阅读2013-2-27 15:16 |个人分类:电子电路设计|

键盘识别思路是这样的,初始化时先让P1口的低四位(P13-P10)输出低电平,高四位(P17-P14)输出高电平,即让P1输出0xf0[P1=0xf0]

扫描键盘时,读P1口,看P1口是否为0xf0,如果仍为0xf0,则表示没有按键按下;如果不为0xf0,就先等待延时10ms左右,再读P1口,再次确认是否为0xf0。这是防止抖动干扰造成的错误识别。如果当再次确认不是0xf0,那就说明真的有按键按下,此时就可以读键码来识别是哪个键按下。

识别过程:初始化时让P1口的低四位输出低电平,高四位输出高电平,确认真的有按键按下时,首先读P1口的高四位,P1口输出0x0f,即让P1口的低四位输出高电平,高四位输出低电平,然后读P1口的低四位,P1口输出0xf0,最后把高四位读到的值与低四位读到的值,做或运算就得到该按键的键码,就可以知道是哪个键按下了。

第一种思路设计

#include <reg51.h>
#include <intrins.h>
#include <absacc.h>


#define uchar unsigned char
#define uint  unsigned int

uchar num[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0x89}; //  LED共阳极段码


void delayns(void) //延时
{
  uint i;
  for(i=300;i>0;i--);
}

uchar keyscan(void)           // 键盘扫描函数
{
 uchar scode,recode;
 P1=0xf0;          // 列线为高电平
 if((P1&0xf0)!=0xf0)       //判断有无按键按下,有则此句成立往下执行,否则就return 0;
 {   delayns();            //有按键按下时延时去抖
  if((P1&0xf0)!=0xf0)   //有键按下
  {
   scode=0xfe;      //辅助变量,设定行,逐行扫描初值P10=0低电平
   while((scode&0x10)!=0)
   {
    P1=scode;   //将某一行设为(低电压)0,从而判断是否为该行,输出行扫描
    if((P1&0xf0)!=0xf0)    //此行有按键按下
    {
     recode=(P1&0xf0)|0x0f;    //列码
     
     return((~scode)+(~recode));  //按键坐标
    }
    else
    scode=(scode<<1)|0x01;     //下一行判断
   }
  }
 }
 return(0);
}

 

void main()
{uchar key,temp;
  while(1)
  { key=keyscan();
    switch(key)
   {
     case 0x11: temp=0;  break;
     case 0x21: temp=1;  break;
     case 0x41: temp=2;  break;
     case 0x81: temp=3;  break;
     case 0x12: temp=4;  break;
     case 0x22: temp=5;  break;
     case 0x42: temp=6;  break;
     case 0x82: temp=7;  break;
     case 0x14: temp=8;  break;
     case 0x24: temp=9;  break;
     case 0x44: temp=10; break;
     case 0x84: temp=11; break;
     case 0x18: temp=12; break;
     case 0x28: temp=13; break;
     case 0x48: temp=14; break;
     case 0x88: temp=15; break;
  
 
   }
      P2=num[temp];
    delayns();         //延时去抖动干扰
  }
 }

 

第二种思路:

#include <reg51.h>
#include <intrins.h>
#include <absacc.h>


#define uchar unsigned char
#define uint  unsigned int

uchar num[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0x89}; //  LED共阳极段码
uchar k;                                           //全局变化

void delayns(void) //延时去抖干扰
{
  uint i;
  for(i=300;i>0;i--);
}

uchar keyscan()   //键盘扫描函数,用于识别那个键按下,并读取键值
{
   uchar x,y,z;
   P1=0xf0;   //先对P1置数,行扫描
   if(P1!=0xf0)     //判断是否有键按下
   {
     delayns();  //延时去抖动干扰
  if(P1!=0xf0)   //再次确认按键按下
   {
     x=P1&0xf0;   //保存列扫描时有键按下时的状态
     P1=0x0f;   //列扫描
  if(P1!=0x0f)
    y=P1&0x0f;  //保存行扫描时有键按下时的状态
  
  z=x|y;    //取出键值
  switch(z)
  {case 0xe7: k=0;  break;
   case 0xd7: k=1;  break;     //对键值赋值
   case 0xb7: k=2;  break;
   case 0x77: k=3;  break;
   case 0xeb: k=4;  break;
   case 0xdb: k=5;  break;
   case 0xbb: k=6;  break;
   case 0x7b: k=7;  break;
   case 0xed: k=8;  break;
   case 0xdd: k=9;  break;
   case 0xbd: k=10; break;
   case 0x7d: k=11; break;
   case 0xee: k=12; break;
   case 0xde: k=13; break;
   case 0xbe: k=14; break;
   case 0x7e: k=15; break;
  
  }

   }
   } return(k);

}

void main()
{ uint key;
  uint n=0;
 while(1)
 {
  key=keyscan(); //得到键值
  n=key;
  P2=num[n]; //P2口数码管显示
 
 }

}

 

PS:大家有什么不同建议思路,可以和我交流哈,大家互相学习,QQ:1298522437

评论 (0 个评论)

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 注册

热门文章