赞助论坛
  • 5250阅读
  • 0回复

学习单片机之---按键程序 [复制链接]

楼层直达
jswr  
发帖
339
精华
1
金币
264
威望
8
贡献
7
好评
15
注册
2008-06-30
楼主    jswr 发表于: 2008-08-05 14:51:14 
按键程序
[日期:2005-4-15] 来源:侃单片机 作者:xwj [字体:大 中 小]


 

//--------------------------------------------------------------------------//
//                     源程序大公开                     //
//             (c) Copyright 2001-2005 xuwenjun               //
//                   All Rights Reserved                   //
//                         V1.00                       //
//--------------------------------------------------------------------------//
//标 题: P1口行列式键盘程序                 ?               //
//文件名: xwj_hlkey.c                                     //
//版 本: V1.00                                         //
//修改人: 徐文军                 E-mail:xuwenjun@21cn.com       //
//日 期: 05-05-13                                       //
//描 述: P1口行列式键盘程序                 ?               //
//声 明:                                             //
//     以下代码仅免费提供给学习用途,但引用或修改后必须在文件中声明出处. //
//     如用于商业用途请与作者联系.   E-mail:xuwenjun@21cn.com       //
//     有问题请mailto [email]xuwenjun@21cn.com[/email]   欢迎与我交流!             //
//--------------------------------------------------------------------------//
//老版本: 无                   老版本文件名:               //
//创建人: 徐文军                 E-mail:xuwenjun@21cn.com       //
//日 期: 05-05-13                                       //
//描 述:                                             //
//       CODE SIZE     =   396   ----                     //
//       CONSTANT SIZE   =   32   ----                     //
//       DATA SIZE     =     4     1                     //
//       BIT SIZE       =     1   ----                     //
//--------------------------------------------------------------------------//
#include <reg52.h>
#include "xwj_hlkey.h"           // P1口行列式键盘 //
//#include "xwj_bp.h"           //峰鸣器

#define KEYDELAY 25   /*首键延迟次数*/
#define KEYLOOP 10   /*连续键间隔次数,需小于KEYDELAY*/
unsigned char key_bak;
unsigned char key_temp;
unsigned char key_old;
unsigned char key_data;
bit key_ok;

unsigned char code Tab_key[]=   //行列式键盘映射,这个表主要是为了直观
  {0x00,                 //无键按下
  '7','8','9','/',
  '4','5','6','*',
  '1','2','3','-',
  'C','0','=','+',
  //下面为按'C'同时再按的键:
  '7','8','9','/',
  '4','5','6','*',
  '1','2','3','-',
    '0','=','+',};

  // P1口行列式键盘 //
#define KEYPIN_L P1           // 定义键扫描列端口为 P1低四位输入 //
#define KEYPIN_H P1         // 定义键扫描行端口为 P1高四位扫描输出 //

  //内部私有函数 //
unsigned char fnKeyCode(unsigned char key);   // 根据键盘映射表输出顺序键值         //

  // P1口行列式键盘 //
//---------------------------------------------------------------------------//
void KeyScan(void)             //键扫描
  {
  unsigned char sccode,recode;
  KEYPIN_L = KEYPIN_L|0x0f;             // P1低四位为列线输入       //
  KEYPIN_H = KEYPIN_H&0x0f;             // P1高四位为行线发全零扫描码 //
  if ((KEYPIN_L&0x0f) != 0x0f)   //有键按下
    {
    key_temp = 0;
    sccode = 0xef;                 // 逐行扫描码初值(1110 1111) //
    while(sccode != 0xff)           //将扫描4次,key_temp为每次键值相 或的值 //
        {
        KEYPIN_H = sccode;           // 输出行扫描码       //
        if ((KEYPIN_L&0x0f) != 0x0f)   // 本行有键按下       //
          {
          recode = (KEYPIN_L&0x0f)|0xf0;   // 只要低位,高位置1 //
          key_temp |= (~sccode)+(~recode);   //特征码(高位为列P3,低位为行KEYPIN_H) //
        }
        sccode = (sccode << 1)|0x01;   // 扫描码0向高位移动 //
    }
    if (key_temp == key_bak)
        {
        key_old++;
        if (key_old==KEYDELAY)           //连续键,不要则把此if屏蔽
          {
          key_ok=1;
          key_data=fnKeyCode(key_temp);   //键解码
          key_old=KEYDELAY-KEYLOOP;
        }
    }
    else
        {
        key_old=0;
        key_bak=key_temp;
    }
  }
  else                   //键抬起
    {
    if (key_old)
        {
        key_ok=1;
        key_data=fnKeyCode(key_temp);   //键解码
/*         if (key_old==100)           //加上时间,不同时间不同功能,与连续键冲突
          {
          bp(1);
          key_data   +=   0x10;
        }
        if (key_old==200)
          {
          bp(2);
          key_data   +=   0x20;
        }
*/
    }
    key_old=0;
  }
  KEYPIN_H = KEYPIN_H|0xf0;
}

//---------------------------------------------------------------------------//
unsigned char fnKeyCode(unsigned char key)   // 根据键盘映射表输出顺序键值   //
  {   //由于我的键盘要考虑多键同时按下,所以这个地方较繁琐,无必要则不必这样解码//
  switch(key)
    {
    case   0x11:           //   1 键 //
        key = 0x01;
        break;
    case   0x21:           //   2 键 //
        key = 0x02;
        break;
    case   0x41:           //   3 键 //
        key = 0x03;
        break;
    case   0x81:           //   4 键 //
        key = 0x04;
        break;
    case   0x12:           //   5 键 //
        key = 0x05;
        break;
    case   0x22:           //   6 键 //
        key = 0x06;
        break;
    case   0x42:           //   7 键 //
        key = 0x07;
        break;
    case   0x82:           //   8 键 //
        key = 0x08;
        break;
    case   0x14:           //   9 键 //
        key = 0x09;
        break;
    case   0x24:           //   10 键 //
        key = 0x0A;
        break;
    case   0x44:           //   11 键 //
        key = 0x0B;
        break;
    case   0x84:           //   12 键 //
        key = 0x0C;
        break;
    case   0x18:           //   13 键 //
        key = 0x0D;
        break;
    case   0x28:           //   14 键 //
        key = 0x0E;
        break;
    case   0x48:           //   15 键 //
        key = 0x0F;
        break;
    case   0x88:           //   16 键 //
        key = 0x10;
        break;
            //以下为功能键//
    case   0x19:           //   'C' +1 键 //
        key = 0x11;
        break;
    case   0x29:           //   'C' +2 键 //
        key = 0x12;
        break;
    case   0x49:           //   'C' +3 键 //
        key = 0x13;
        break;
    case   0x89:           //   'C' +4 键 //
        key = 0x14;
        break;
    case   0x1A:           //   'C' +5 键 //
        key = 0x15;
        break;
    case   0x2A:           //   'C' +6 键 //
        key = 0x16;
        break;
    case   0x4A:           //   'C' +7 键 //
        key = 0x17;
        break;
    case   0x8A:           //   'C' +8 键 //
        key = 0x18;
        break;
    case   0x1C:           //   'C' +9 键 //
        key = 0x19;
        break;
    case   0x2C:           //   'C' +10 键 //
        key = 0x1A;
        break;
    case   0x4C:           //   'C' +11 键 //
        key = 0x1B;
        break;
    case   0x8C:           //   'C' +12 键 //
        key = 0x1C;
        break;
//     case   0x18:           //   'C' +13 键 //
//         key = 0x1D;
//         break;
    case   0x38:           //   'C' +14 键 //
        key = 0x1D;
        break;
    case   0x58:           //   'C' +15 键 //
        key = 0x1E;
        break;
    case   0x98:           //   'C' +16 键 //
        key = 0x1F;
        break;
    default   :           //   无键   //
        key = 0x00;
        break;
  }
  return(Tab_key[key]);
}

unsigned char KeyGetCode(void)     //返回按键码
{
  key_ok=0;
  return(key_data);
}

bit KeyTest(void)           //检查有无按键
{
  KeyScan();         //键扫描
  return(key_ok);
}