打印
[STC单片机]

STC 单片机ADC按键扫描松手检测程序问题

[复制链接]
4842|26
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
huzb11|  楼主 | 2016-7-11 13:55 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 huzb11 于 2016-7-11 13:57 编辑

u8 key_Process(u8 key_ad)
{        
u8 kad;
kad=GetADCResult(0);

if(kad==0) //执行K1操作
{


Disp(GetADCResult(0));

}

}
else if(kad>20&&kad<25)          //执行K2操作
{
close_Fault_Fled();
Disp(GetADCResult(0));
}
else if(kad>30&&kad<45)        //执行K3操作
{

close_Fault_Fled();
Disp(GetADCResult(0));
}
else if(kad>55&&kad<70)        //执行K4操作
{

close_Fault_Fled();
Disp(GetADCResult(0));
}
else if(kad>78&&kad<85)        //执行K5操作
{

close_Fault_Fled();
Disp(GetADCResult(0));
}
else if(kad>90&&kad<110)        //执行K6操作
{
close_Fault_Fled();
Disp(GetADCResult(0));
}
else if(kad>125&&kad<135)         //执行K7操作
{

close_Fault_Fled();
Disp(GetADCResult(0));
}
else if(kad>150&&kad<160)          //执行K8操作
{

close_Fault_Fled();
Disp(GetADCResult(0));
}
else if(kad>248&&kad<260)          //执行无按键AD值为全值255操作
{   
                //tg_comp();//检测无人站在托盘上时,进行发语音提醒
        close_Led();        
        Fault_Fled();
}


return 1;

}

上面程序控制K1-K8按键,当按下后,显示对应的AD键值,当松手后,就没显示了,如何让它松手后才正常显示AD键值。

后来,我把第一个按键改成这样,发现第一个按键,按下直接不显示。ADC按键扫描松手后检测如何做?哪位帮看一下。哪里出了问题?


if(kad==0) //执行K1操作
{
   Delay1ms();
   if(kad==0)
   {
   Delay1ms();
   while(kad)
   {

Disp_tg(GetADCResult(0));
   }
   }

}

相关帖子

沙发
wangyy608| | 2016-7-11 14:41 | 只看该作者
保存前一次的AD值

使用特权

评论回复
板凳
huzb11|  楼主 | 2016-7-11 14:47 | 只看该作者
wangyy608 发表于 2016-7-11 14:41
保存前一次的AD值

现有的程序如何改?如何操作?

使用特权

评论回复
地板
wangyy608| | 2016-7-11 14:52 | 只看该作者
kad=GetADCResult(0);
if((kad!=old——ad)&&(kad>248&&kad<260)   )
{   
     if(kad==0) //执行K1操作
    {
         Disp(GetADCResult(0));
    }
    .......
}
old_ad = kad;



大概是这么个意思

使用特权

评论回复
5
huzb11|  楼主 | 2016-7-11 15:50 | 只看该作者
wangyy608 发表于 2016-7-11 14:52
kad=GetADCResult(0);
if((kad!=old——ad)&&(kad>248&&kad

&&(kad>248&&kad<260  

这一句是什么意思?

还有old_ad = kad;

这一句是最后再给old_ad赋一次值吗?

使用特权

评论回复
6
huzb11|  楼主 | 2016-7-11 15:56 | 只看该作者
wangyy608 发表于 2016-7-11 14:52
kad=GetADCResult(0);
if((kad!=old——ad)&&(kad>248&&kad

试过了,不行。第一组按键 Kad=0,第一个按键按了之后,松手开始显示。

使用特权

评论回复
7
jrcsh| | 2016-7-11 16:35 | 只看该作者
  来个超时处理不就行了,

使用特权

评论回复
8
huzb11|  楼主 | 2016-7-11 16:37 | 只看该作者
求教各位高人如何解决,ADC按键松手后检测,下午弄很久了,都没成效。。。以上程序如何修改?

使用特权

评论回复
9
huzb11|  楼主 | 2016-7-11 16:50 | 只看该作者
fxmxh 发表于 2016-7-11 16:41
else if(kad>248&&kad248&&kad

那么我上面的程序如何修改呢?

使用特权

评论回复
10
huzb11|  楼主 | 2016-7-11 16:55 | 只看该作者
关键是按键松手后,怎么能让它正常显示?按一下才显示,我最上面已经OK了。我要ADC按键松手后才正常显示。。。

使用特权

评论回复
11
datouyuan| | 2016-7-11 17:33 | 只看该作者
你把按键分析和按键执行分开,就好做了.

再用一个变量存上一次的键值.

u8 u8KeyOld;
u8 key_Process(void)
{
        u8 kad;
        kad=GetADCResult(0);
        kad=GetKey(kad);
        if(u8KeyOld==kad)
        {//按键无变化
        }
        else
        {//按键有变化
                if(u8KeyOld=0xff)
                {
                        //ExeKey(kad);//按下执行
                }
                else
                {//松手
                        ExeKey(u8KeyOld);//松手执行
                }
        }
        u8KeyOld==kad;
}

使用特权

评论回复
12
zyj9490| | 2016-7-11 17:35 | 只看该作者
huzb11 发表于 2016-7-11 16:37
求教各位高人如何解决,ADC按键松手后检测,下午弄很久了,都没成效。。。以上程序如何修改? ...

你必须要用状态机原理,检测一次按键的过程,非高电平--去抖---再判---得出一个键,开始计时(区争长键还是短按)---检出高电平(恢复原始状态),完成一个短按键的过程,(超时,得出一个长按事件),执行按键函数。

使用特权

评论回复
13
datouyuan| | 2016-7-11 17:40 | 只看该作者
本帖最后由 datouyuan 于 2016-7-11 17:46 编辑
u8 GetKey(u8 Kad)
{
        f(kad==0) //执行K1操作
                return 1;
        else if(kad>20&&kad<25)          //执行K2操作
                return 2;
        //....
        else if(kad>248&&kad<260)          //执行无按键AD值为全值255操作
                return 0xff;
}
void ExeKey(u8 keyvalue)
{

        switch (keyvalue)
        {
                case 1://执行K1操作
                {
                }break;
                case 2://执行K2操作
                {
                }break;
                default:
                {
                }break;
        }
}

使用特权

评论回复
14
huzb11|  楼主 | 2016-7-11 17:45 | 只看该作者
本帖最后由 huzb11 于 2016-7-11 17:47 编辑

上面的程序,如何才能像普通按键一样,按键释放后仍能读取按键的值,如下面。在主程序直接可以直接调用。

u8 Readkey(void)
{
  u8 temp;
  temp=P5IN&0xf0;
  if(temp!=0xf0)
  {
    delayms(10);
    if(temp==(P5IN&0xf0))
    {
        return temp;
      }
  else
    return 0xff;
   }
    else
      return 0xff;
}

u8 keysend(u8 dat)
{
  u8 key;
  key=Readkey();
  switch(key)
  {
  case 0xe0: key=1;
  break;
  case 0xd0: //sp();
                 key=2;
                 //P5OUT=~BIT0;
                 break;
  case 0xb0: key=3;
  break;
  case 0x70: key=4;
  break;
  
  }
   return key;
}


--------------------

main(void)
{
while(1)
if(keysend(Readkey())==1)
                                
{   delayms(10);           //消除按键抖动
                             
if(keysend(Readkey())==1)
{
执行某操作
}
else if(keysend(Readkey())==2)
{
执行某操作
....
}-}

使用特权

评论回复
15
datouyuan| | 2016-7-11 17:50 | 只看该作者
本帖最后由 datouyuan 于 2016-7-11 17:54 编辑
huzb11 发表于 2016-7-11 17:45
上面的程序,如何才能像普通按键一样,按键释放后仍能读取按键的值,如下面。在主程序直接可以直接调用。

...

这2个函数仅仅是分析和执行按键.

你需要的功能是只要按15楼的程序做.在按下的位置再加全局变量保存你要的值
在松手的位置处理这些全局变量.

使用特权

评论回复
16
huzb11|  楼主 | 2016-7-11 19:07 | 只看该作者
datouyuan 发表于 2016-7-11 17:33
你把按键分析和按键执行分开,就好做了.

再用一个变量存上一次的键值.

kad=GetKey(kad);

这一句:getkey(kad),从哪里得到的值?

使用特权

评论回复
17
billliu66| | 2016-7-11 21:56 | 只看该作者
在没有跳转语句的情况下,程序是顺序执行的,在没有第二次执行"kad=GetADCResult(0);"时,kad的值是不会变的,尽管你已松手,因而将"Disp(GetADCResult(0));"改为"Disp(kad);"即可达成目标.

使用特权

评论回复
18
datouyuan| | 2016-7-12 10:36 | 只看该作者
huzb11 发表于 2016-7-11 19:07
kad=GetKey(kad);

这一句:getkey(kad),从哪里得到的值?

我在17楼给了示范代码(是根据你的u8 key_Process(u8 key_ad)函数写的)
Getkey(kad)           按键分析
Exekey(keyvalue)    按键执行

分开后,功能灵活,互不影响,结构清晰.

16楼的代码是定时执行(可以每隔50mS执行一次),结合时间你可以用17楼的2个函数,产生短按下 长按下 短按下抬起 长按下抬起 长按连发等各种按键效果.16楼的代码只给出了短按下 和按键抬起这两功能.

使用特权

评论回复
19
huzb11|  楼主 | 2016-7-12 12:05 | 只看该作者
datouyuan 发表于 2016-7-12 10:36
我在17楼给了示范代码(是根据你的u8 key_Process(u8 key_ad)函数写的)
Getkey(kad)           按键分析
E ...

我现在把它改为独立按键了。按键与菜单程序以前研究得太少。很多子程序都弄好了,一但放在按键里,就出问题了。要么按键松手后,去执行某一个函数,没反应。要么按完了,不执行。比如下面的程序。。。

u8 Readkey(void)
{
  u8 temp;
  temp=P5IN&0xf0;
  if(temp!=0xf0)
  {
    delayms(10);
    if(temp==(P5IN&0xf0))
    {
        return temp;
      }
  else
    return 0xff;
   }
    else
      return 0xff;
}

u8 keysend(u8 dat)
{
  u8 key;
  key=Readkey();
  switch(key)
  {
  case 0xe0: key=1;
  break;
  case 0xd0: //sp();
                 key=2;
                 //P5OUT=~BIT0;
                 break;
  case 0xb0: key=3;
  break;
  case 0x70: key=4;
  break;
  
  }
   return key;
}


--------------------

main(void)
{
while(1)
if(keysend(Readkey())==1)
                                
{   delayms(10);           //消除按键抖动
                             
if(keysend(Readkey())==1)
{
   Disp_tg();   调用体重测量函数。。。
}
else if(keysend(Readkey())==2)
{
执行某操作
....
}-}

以上程序也是,按键一松手后,程序就不执行。。。如何松手后还在执行。。。

使用特权

评论回复
20
huzb11|  楼主 | 2016-7-12 12:44 | 只看该作者
ADC按键,改成独立按键。还是按下去有显示测量,松手下后,又没显示。

u8 Readkey(void)
{
  u8 temp;
  temp=P2&0x0f;
  if(temp!=0x0f)
  {
  //  delayms(10);
    if(temp==(P2&0x0f))
    {
        return temp;
      }
  else
    return 0xff;
   }
    else
      return 0xff;
}


u8 keysend(u8 key)
{

  switch(key)
  {
  case 0x0e: key=1; break;
  case 0x0d: key=2; break;
  case 0x0b: key=3;break;
  case 0x07: key=4;break;
  
  }
   return key;
}

extern u8 ky;



main()       
{
   u8 key_num;
    io_init();
   //time_init();
        P0=P1=P2=P3=P4=P5=0xff;
        close_Led();
    init_SR04();   
        Sp=0;
        InitADC();
        while(1)
        {
          Srelay();       
                 
          //Disp_tg(GetADCResult(0));       
           //Disp_tg(ADC_key_filter());       
           //key_Process(GetADCResult(0));
            //readkey();
                ky=keysend(Readkey());
switch(ky)
  {
  case 1: Disp_tg(tg_test()); break;
  case 2:Disp_sg(sg_test());; break;
  case 3: //key=3;
  break;
  case 4:
  //key=4;
  break;
  
  }


       
               
               
   }   

}       

单个程序放在while(1)下都能正常执行。。。

使用特权

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

本版积分规则

12

主题

55

帖子

1

粉丝