打印

按键程序

[复制链接]
1289|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
xnwxq|  楼主 | 2009-8-23 18:18 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#ifndef _SKEY_H_
#define _SKEY_H_
#define uchar unsigned char
#define uint unsigned int
#define SKEY_FR  RA0
#define SKEY_AC  RA1
#define SKEY_RDEF RA3
#define BT_FR 0X0F  //REC按键值
#define BT_AC 0XF0  //AC按键值
#define BT_RDEF 0XFF //RDEF按键值
#define UNKEY 0X00 //无按键
      //返回的按键值
#define SUM  16  //检测按键的总次数。每次为1ms
#define PRE  0XAA //按键按下
#define CURRENT  0X0F //释放按键
uchar read_skey(void); //返回的当前按键值
#endif

#i nclude<pic.h>
#i nclude"skey.h"
static uchar read_pre(uchar SkeyBit,uchar * SkeyCount);//读释放状态
static uchar read_current(uchar SkeyBit,uchar *SkeyCount);//读按下状态
uchar SkeyFrState=UNKEY,SkeyAcState=UNKEY,SkeyRdefState=UNKEY;
uchar FrCount,AcCount,RdefCount;
uchar FrPreCount,AcPreCount,RdefPreCount;
static void io_init()
{
ANS0 = 0;  //设置AN0为数字端口
ANS1 = 0;  //设置AN1为数字端口
TRISA0 = 1;
TRISA1 = 1;
TRISA3 = 1;  //设置三个按键为输入
}
static uchar scan_pre(uchar SkeyBit)  //扫描按下的键值
{
uchar skey_v = UNKEY;
switch(SkeyBit)
{
  case BT_FR:
   if(!SKEY_FR)
   {
    skey_v=BT_FR;
   }
   break;
  case BT_AC:
   if(!SKEY_AC)
   {
    skey_v=BT_AC;
   }
   break;
   case BT_RDEF:
   if(!SKEY_RDEF)
   {
    skey_v=BT_RDEF;
   }
  break;
  default:break;
}
return skey_v;  //按键为低电平有效
}
static uchar scan_current(uchar SkeyBit)  //扫描释放的键值
{
uchar skey_v = UNKEY;
switch(SkeyBit)
{
  case BT_FR:
   if(SKEY_FR)
   skey_v=BT_FR;
   break;
  case BT_AC:
   if(SKEY_AC)
    skey_v=BT_AC;
   break;
   case BT_RDEF:
   if(SKEY_RDEF)
    skey_v=BT_RDEF;
   break;
  default:break;
}
return skey_v;  //释放按键为高电平有效
}
static uchar read_pre(uchar SkeyBit,uchar *SkeyCount)//参数为:需要采集的开关位
{
uchar SkeyTemp,PreState=UNKEY;//,SkeyCount;
      
if(*SkeyCount)  
{
  SkeyTemp = scan_pre(SkeyBit);
  if(SkeyTemp == SkeyBit)
  {
   *SkeyCount += 1;
  }
  else
  {
   *SkeyCount = 0;
   PreState = UNKEY;
  }
}
else
{
  SkeyTemp = scan_pre(SkeyBit);//采集第一个低电平
  if(SkeyTemp == SkeyBit)
  {
   *SkeyCount = 1;
  }  
}
if(*SkeyCount == SUM) //完成了采集次数
{
  PreState = PRE;
  SkeyCount = 0;  
}
return PreState;
}
static uchar read_current(uchar SkeyBit,uchar *SkeyCount)//参数:需要采集的开关位
{
uchar SkeyTemp,CurrentState=PRE;//,SkeyCount;
if(*SkeyCount)  
{
  SkeyTemp = scan_current(SkeyBit);
  if(SkeyTemp == SkeyBit)
  {
   *SkeyCount += 1;
  }
  else
  {
   CurrentState = PRE;
   *SkeyCount = 0;  
  }
}
else
{  //采集第一个高电平
  SkeyTemp = scan_current(SkeyBit);
  if(SkeyTemp == SkeyBit)
  {
   *SkeyCount = 1;
  }
}
if(*SkeyCount == SUM) //完成了采集次数
{
  CurrentState = CURRENT;
  *SkeyCount = 0;
}
return CurrentState;
}
/*******************************************
函数名:uchar read_skey()
功能:检测并返回当前按键值
参数:无
返回值:当前按键值
编写者:
日期:2009年7月29日
备注:read_skey()必须每5ms-30ms内,
运行一次才能正确的采集按键,并返回按键值
修改目的:实现3个按键不会相互干扰
修改日期:2009年8月12日
*******************************************/
uchar read_skey()
{
uchar SkeyValue = UNKEY;
io_init();
if(SkeyFrState == PRE) //状态为按下
{
  SkeyFrState = read_current(BT_FR,&FrCount);
}
else if(SkeyFrState == UNKEY) //状态为无按键
{
  SkeyFrState = read_pre(BT_FR,&FrPreCount);
}
if(SkeyFrState == CURRENT)  //状态为释放
{
  SkeyValue = BT_FR;
  SkeyFrState = UNKEY;
  return SkeyValue;
}
if(SkeyAcState == PRE) //状态为按下
{
  SkeyAcState = read_current(BT_AC,&AcCount);
}
else if(SkeyAcState == UNKEY) //状态为无按键
{
  SkeyAcState = read_pre(BT_AC,&AcPreCount);
}
if(SkeyAcState == CURRENT)  //状态为释放
{
  SkeyValue = BT_AC;
  SkeyAcState = UNKEY;
  return SkeyValue;
}
if(SkeyRdefState == PRE) //状态为按下
{
  SkeyRdefState = read_current(BT_RDEF,&RdefCount);
}
else if(SkeyRdefState == UNKEY)  //UNKEY状态为无按键
{
  SkeyRdefState = read_pre(BT_RDEF,&RdefPreCount);
}
if(SkeyRdefState == CURRENT)  //状态为释放
{
  SkeyValue = BT_RDEF;
  SkeyRdefState = UNKEY;
  return SkeyValue;
}
return SkeyValue;
}

相关帖子

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

本版积分规则

个人签名:我们都是风雨中的孩子,手牵着手才不会跌倒

162

主题

294

帖子

1

粉丝