8288|2

2

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

51单片机矩阵键盘扫描程序(源代码) [复制链接]

//小菜出品---严禁抄袭,转载请注明出处

#include <reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
uchar idata  x,y;
uchar code disp_code[] =
{
  0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90,
  // 0-9      0 1 2 3 4 5 6 7 8 9
  0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e,
  // 10-15    a b c d e f
  0x7F, 0xBF, 0x9C, 0xFF
  // 16-19    . - 。null
};    //数码管显示值列表
void delay(uchar c)                        //延时函数
{
   char a,b;
   for(a=c;a>0;a--)
   for(b=110;b>0;b--);

}

uchar key_scan()                        //键盘扫描函数

     uchar k;
  uchar z;
  x=0x00;                  
  y=0x00;
     P3=0xf0;                            //先给P3赋一个初值
  if(P3!=0xf0)                        //判断P3不等于所赋初值,说明有健按下
  {
      delay(10);                      //消除键盘抖动  延时10ms
      if(P3!=0xf0)                   
   {          
          x=P3;                    /*这里稍作解释:起初我们已经给P3赋了一个0xf0的值,如果有键按下,P3便一定不再是0xf0 ,
                              如果我们这时查看P3的值我们就能知道是哪一列的键按下了(说明一下,我的开发板上P3.0-P3.3接的是列)
            但这时我们先不看P3的值,这时我们先把P3的值赋给x,再给P3赋一个0x0f的值,由于这两条语句执行的速度是
             很快的,是us级的,而我们按一个按键怎么也得几十到上百ms,尽管我们在前面已经做过一个10ms的延时,但是
             在我们给P3重新赋值后,按键一定还是闭合的,所以P3被赋0xof后由于有按键闭合,故P3的值又变了,这时候我们
             查看P3的值就可以判断出来是是哪一行的按键按下了.然后我们把这时的P3值赋给y,再用x或上y,把他们的值赋给z
             然后判断z的值就可以知道是具体哪一个键被按下了!(行和列都确定了,具体是哪一个键自然就确定了) */                        
          P3=0x0f;             
          y=P3;
          z=x|y;
    switch(z)
    {
     case 0xee: k=0; break;
     case 0xed: k=1; break;
     case 0xeb: k=2; break;
     case 0xe7: k=3; break;
     case 0xde: k=4; break;
     case 0xdd: k=5; break;
     case 0xdb: k=6; break;
     case 0xd7: k=7; break;
     case 0xbe: k=8; break;
     case 0xbd: k=9; break;
     case 0xbb: k=10;break;
     case 0xb7: k=11;break;
     case 0x7e: k=12;break;
     case 0x7d: k=13;break;
     case 0x7b: k=14;break;
     case 0x77: k=15;break;
    }
       }
  }

 return(k);
}

void main()
{
 uchar dat;
 while(1)
 {
  P3=0xf0;
  while(P3!=0xf0)
  {
   dat=key_scan();
   P1=0;
   P0=disp_code[dat];
  }
 }
}

 

我感觉一般初学者会有疑问的地方 已经做出了详细的解释

如果还有弄不明白的地方 可以回帖提问  我会尽量做出解答

以期共同进步

此帖出自51单片机论坛

最新回复

一般 keil 编程默认把数据存放在Data 区,也即内部数据存储区(0x00-0x7f的128个RAM),如 int x,char y,默认都是存放在这个地方, 而 idata 则是存放在0x00-0xff的256个RAM,其中前128和dATa的128完全相同,只是因为访问的方式不同,除此之外,还有 xdATa: 外部扩展RAM,一般指外部0x0000-0xffff空间。 code : 0000H .. 0FFFFH 用于存放代码数据。当数据存储区不够时,可把数组定义在这里,节省空间,如 unsigned char a[10];   详情 回复 发表于 2014-4-14 13:17
点赞 关注
 

回复
举报

473

帖子

0

TA的资源

纯净的硅(高级)

推荐
 
uchar idata  x,y;
这个地方为什么这么定义
此帖出自51单片机论坛

点评

一般 keil 编程默认把数据存放在Data 区,也即内部数据存储区(0x00-0x7f的128个RAM),如 int x,char y,默认都是存放在这个地方, 而 idata 则是存放在0x00-0xff的256个RAM,其中前128和dATa的128完全相同,只是因为  详情 回复 发表于 2014-4-14 13:17
 
 
 

回复

1071

帖子

7

TA的资源

纯净的硅(中级)

板凳
 
zjjone1023 发表于 2010-12-23 11:03
uchar idata  x,y;
这个地方为什么这么定义

一般 keil 编程默认把数据存放在Data 区,也即内部数据存储区(0x00-0x7f的128个RAM),如 int x,char y,默认都是存放在这个地方,
而 idata 则是存放在0x00-0xff的256个RAM,其中前128和dATa的128完全相同,只是因为访问的方式不同,除此之外,还有
xdATa: 外部扩展RAM,一般指外部0x0000-0xffff空间。
code : 0000H .. 0FFFFH 用于存放代码数据。当数据存储区不够时,可把数组定义在这里,节省空间,如 unsigned char a[10];
此帖出自51单片机论坛

赞赏

1

查看全部赞赏

 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表