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

[复制链接]
2840|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 | 显示全部楼层
谢谢!
 楼主| zg779660079 发表于 2012-7-28 15:59 | 显示全部楼层
我知道问题出在那了,P3=cord_h|0xf0;这是有重新对P3赋值了,我还用原来那个0x0f来计算,所以老是搞不懂,谢谢你了、 2# 雷影少年
 楼主| zg779660079 发表于 2012-7-28 15:59 | 显示全部楼层
谢谢你了、 3# zhoukouguren
 楼主| 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
 楼主| zg779660079 发表于 2012-7-28 16:24 | 显示全部楼层
这个帖子怎么关闭啊?不会唉、、、 2# 雷影少年
ningling_21 发表于 2012-7-28 16:35 | 显示全部楼层
点击最上面“我要结贴” 然后 给分,然后 点击“结贴给分” 就OK了...
songhere 发表于 2012-8-8 22:15 | 显示全部楼层
晕,这个键盘扫描程序实时性太差了吧~~~
分享一个键盘程序吧。。。。

  1. #include<reg52.h>


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

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



  10. /* ----数值定义-----  */

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


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





  14. /*-----按键散转-----
  15. 作用 :根据key_num的值散转程序
  16. 输入 : 无
  17. 输出 :无
  18. ------------------*/
  19. void key_deal_a(void)
  20. {
  21.         switch(key_num)
  22.         {
  23.                 case 0        : LED0 = !LED0;
  24.                                         break;
  25.                 case 1        : LED1 = !LED1;
  26.                                         break;
  27.                 case 2        : LED2 = !LED2;
  28.                                         break;
  29.                 case 3        : LED3 = !LED3;
  30.                                         break;
  31.                 default :  break;
  32.        
  33.         }

  34. }




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

  43.         temp  = P3;
  44.         temp &= 0xf0;

  45.         switch(temp)
  46.         {
  47.                 case 0xe0:        key_num1 = 0;          //按下为0
  48.                                         break;

  49.                 case 0xd0:        key_num1 = 1;
  50.                                         break;

  51.                 case 0xb0:        key_num1 = 2;
  52.                                         break;

  53.                 case 0x70:        key_num1 = 3;
  54.                                         break;
  55.                
  56.                 default  : key_num1 = 0xff;

  57.         }

  58.         return key_num1;

  59. }




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

  64.         if(0xff != key_num)
  65.         {
  66.                 if(key_num == key_BUF)
  67.                 {
  68.                         if( key_N_RES_F == 0)
  69.                         {       
  70.                                 key_deal_a();  //按键散转子程序

  71.                                 key_N_RES_F = 1;
  72.                         }
  73.                
  74.                 }
  75.                 else
  76.                 {
  77.                         goto  mark_key_1 ;
  78.                 }
  79.        
  80.         }
  81.         else
  82.         {
  83.   mark_key_1 :
  84.                  key_BUF     = key_num;
  85.                 key_N_RES_F = 0 ;
  86.         }

  87. }

ayb_ice 发表于 2012-8-9 09:52 | 显示全部楼层
就凭下面的语句
delayms(100);
就很不NB
zhuanghaiyang 发表于 2012-8-9 12:19 | 显示全部楼层
反转法
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

6

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部