打印

那位高手来分析下这个矩阵键盘程序

[复制链接]
1993|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zg779660079|  楼主 | 2012-7-27 18:44 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 zg779660079 于 2012-7-27 18:52 编辑

在百度发现了一个非常牛b的程序,看了看没看懂,主要是在按下一个键盘后P3口怎么变化的和我理解的也许不一样,求教高手指点,帮我分析下键盘扫描那段程序,谢谢!

#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit dula=P2^6;
sbit wela=P2^7;
uchar num;
uchar bai,shi,ge;
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x7c};
void delayms(uint z)
{
uchar i,j;
for(i=z;i>0;i--)
  for(j=110;j>0;j--);
}
void display(uchar bai,uchar shi,uchar ge)
{
   
  wela=1;
  P0=0xfe;
  wela=0;
  dula=1;
  P0=table[bai];
  dula=0;
  delayms(5);

  wela=1;
  P0=0xfd;
  wela=0;
  dula=1;
  P0=table[shi];
  dula=0;
  delayms(5);

  wela=1;
  P0=0xfb;
  wela=0;
  dula=1;
  P0=table[ge];
  dula=0;
     delayms(5);
}
uchar keyscan()
{
  uchar cord_h,cord_l;
  P3=0x0f;
  cord_h=P3&0x0f;
  if(cord_h!=0x0f)
  {
    delayms(100);
cord_h=P3&0x0f;
if(cord_h!=0x0f)
{
   P3=cord_h|0xf0;
   cord_l=P3&0xf0;
   return(cord_h+cord_l);
}
  }
  return (0xff);   
}
void main()
{
  uchar key;
while(1)
{
  key=keyscan();
  switch(key)
  {
      case 0xee:num=0;break;
   case 0xde:num=1;break;
   case 0xbe:num=4;break;
   case 0x7e:num=9;break;
   case 0xed:num=16;break;
   case 0xdd:num=25;break;
   case 0xbd:num=36;break;
   case 0x7d:num=49;break;
   case 0xeb:num=64;break;
   case 0xdb:num=81;break;
   case 0xbb:num=100;break;
   case 0x7b:num=121;break;
   case 0xe7:num=144;break;
   case 0xd7:num=169;break;
   case 0xb7:num=196;break;
   case 0x77:num=225;break;
  }
  bai=num/100;
  shi=num%100/10;
  ge=num%10;
  display(bai,shi,ge);
}
}

相关帖子

沙发
雷影少年| | 2012-7-27 21:34 | 只看该作者
本帖最后由 雷影少年 于 2012-7-27 21:38 编辑

就是线反转法扫描键盘和我的程序的方法类似,你可以参考下
https://bbs.21ic.com/viewthread.php?tid=357856&extra=&page=1
uchar keyscan()
{
uchar cord_h,cord_l;
P3=0x0f;
cord_h=P3&0x0f;
if(cord_h!=0x0f)       //判断是否有键按下   
{
delayms(100);          //延时消抖
cord_h=P3&0x0f;   //保存行坐标值
if(cord_h!=0x0f)
{
P3=cord_h|0xf0;
cord_l=P3&0xf0;      //保存列坐标值   
return(cord_h+cord_l);                //返回键盘坐标值
}
}
return (0xff);

使用特权

评论回复
板凳
zhoukouguren| | 2012-7-28 12:29 | 只看该作者
地板
zg779660079|  楼主 | 2012-7-28 15:56 | 只看该作者
谢谢!

使用特权

评论回复
5
zg779660079|  楼主 | 2012-7-28 15:59 | 只看该作者
我知道问题出在那了,P3=cord_h|0xf0;这是有重新对P3赋值了,我还用原来那个0x0f来计算,所以老是搞不懂,谢谢你了、 2# 雷影少年

使用特权

评论回复
6
zg779660079|  楼主 | 2012-7-28 15:59 | 只看该作者
谢谢你了、 3# zhoukouguren

使用特权

评论回复
7
zg779660079|  楼主 | 2012-7-28 16:21 | 只看该作者
我知道问题出在那了,P3=cord_h|0xf0;这是有重新对P3赋值了,我还用原来那个0x0f来计算,所以老是搞不懂,谢谢你了
就是线反转法扫描键盘和我的程序的方法类似,你可以参考下
https://bbs.21ic.com/viewthread.php?tid=357856&extra=&page=1
uchar keyscan()
{
uchar cord_h,cord_l;
P3=0x0f;
cord_h=P3&0x0f;
if(cord_h!=0x0f)      ...
雷影少年 发表于 2012-7-27 21:34

使用特权

评论回复
8
zg779660079|  楼主 | 2012-7-28 16:24 | 只看该作者
这个帖子怎么关闭啊?不会唉、、、 2# 雷影少年

使用特权

评论回复
9
ningling_21| | 2012-7-28 16:35 | 只看该作者
点击最上面“我要结贴” 然后 给分,然后 点击“结贴给分” 就OK了...

使用特权

评论回复
10
songhere| | 2012-8-8 22:15 | 只看该作者
晕,这个键盘扫描程序实时性太差了吧~~~
分享一个键盘程序吧。。。。

#include<reg52.h>


//sbit key0 = P3^4;     //键盘定义
//sbit key1 = P3^5;
//sbit key2 = P3^6;
//sbit key3 = P3^7;

sbit  LED0 = P1^0;    // 测试LED灯定义
sbit  LED1 = P1^1;
sbit  LED2 = P1^2;
sbit  LED3 = P1^3;



/* ----数值定义-----  */

unsigned char  key_num       = 0xff;    //本次键号
unsigned char  key_BUF       = 0XFF;        //备份键号


unsigned char  key_N_RES_F   = 1;  //按键禁止响应标志,1为禁止响应  





/*-----按键散转-----
作用 :根据key_num的值散转程序
输入 : 无
输出 :无
------------------*/
void key_deal_a(void)
{
        switch(key_num)
        {
                case 0        : LED0 = !LED0;
                                        break;
                case 1        : LED1 = !LED1;
                                        break;
                case 2        : LED2 = !LED2;
                                        break;
                case 3        : LED3 = !LED3;
                                        break;
                default :  break;
       
        }

}




/*------------------  
函数作用 :读取按键的瞬时值
    输入 : 无
        输出 : 返回键值 ,若没有键按下则返回 oxff;
-------------------*/
unsigned char key_read_instant(void)
{
        unsigned char  temp , key_num1 ;

        temp  = P3;
        temp &= 0xf0;

        switch(temp)
        {
                case 0xe0:        key_num1 = 0;          //按下为0
                                        break;

                case 0xd0:        key_num1 = 1;
                                        break;

                case 0xb0:        key_num1 = 2;
                                        break;

                case 0x70:        key_num1 = 3;
                                        break;
               
                default  : key_num1 = 0xff;

        }

        return key_num1;

}




/*  简单按键检测处理   单键单次短击 (10ms扫描一次键盘) */
void key_scan_dj(void)
{
        key_num = key_read_instant();

        if(0xff != key_num)
        {
                if(key_num == key_BUF)
                {
                        if( key_N_RES_F == 0)
                        {       
                                key_deal_a();  //按键散转子程序

                                key_N_RES_F = 1;
                        }
               
                }
                else
                {
                        goto  mark_key_1 ;
                }
       
        }
        else
        {
  mark_key_1 :
                 key_BUF     = key_num;
                key_N_RES_F = 0 ;
        }

}

使用特权

评论回复
11
ayb_ice| | 2012-8-9 09:52 | 只看该作者
就凭下面的语句
delayms(100);
就很不NB

使用特权

评论回复
12
zhuanghaiyang| | 2012-8-9 12:19 | 只看该作者
反转法

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

6

帖子

0

粉丝